# What is your best practice to access a cluster by a Java client?

**URL:** <https://discuss.elastic.co/t/what-is-your-best-practice-to-access-a-cluster-by-a-java-client/7865>\
**Category:** Elasticsearch\
**Created:** [May 25, 2012, 2:26pm UTC](https://discuss.elastic.co/t/what-is-your-best-practice-to-access-a-cluster-by-a-java-client/7865 "2012-05-25T14:26:23Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jprante](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jprante/32/44941_2.png) [@jprante](https://discuss.elastic.co/u/jprante)\
**Post date:** [May 25, 2012, 2:26pm UTC](https://discuss.elastic.co/t/what-is-your-best-practice-to-access-a-cluster-by-a-java-client/7865/1 "2012-05-25T14:26:23Z")

</div>

Hi,

I'd like to learn how you use the Java client API for Elasticsearch and  
what your experiences are so far.

My scenario is a web app (\*.war or similar) running on an app server ( e.g.  
Glassfish, JBoss etc.) installed as a front-end (for security, query  
translation) to Elasticsearch. The cluster can be remote (but need not to  
be remote).

I need robust access, that is, each query or indexing request must be  
reliably answered by a success or failure event and of course I need fast  
response times.

There are at least three variants:

a) a Node in client mode

b) a TransportClient

c) the REST API (HTTP port 9200)

Let's discuss some of the pros (+) & cons (-) from my naive view as an app  
developer:

a) + zero-conf, out-of-the box cluster discovery  
+ automatic failover  
+ fluent API interface  
- overhead of internal node joining the cluster(?)  
- missing network interface setup  
- unreadable binary protocol over port 9300

b) + almost zero-conf, configurable network interface setup  
+ automatic failover  
+ fluent API interface  
- slight overhead of TransportClient node when joining the cluster  
(finding the currently reachable nodes)  
- additional "sniff" mode for automatic node (re)discovery  
- unreadable binary protocol over port 9300

c) + readable protocol over port 9200 (HTTP)  
- no zero-conf cluster discovery, failover only with external load  
balancer  
- overhead of JSON/Java serialization and de-serialization

Right now, I decided to go with b)

My assumption was I could manage a TransportClient singleton as a  
long-lived object. I struggled with connections being apparently dropped  
(after a certain length of inactivity?), so subsequent client operations  
gave "no node available" - without being able to refresh the connection by  
an API method. It's a challenge to understand how keep-alive connections  
can be configured with TransportClient - after a period of 5000ms by  
default, the communication seems to time out? Closing and re-opening a  
TransportClient in a web app environment looks like an expensive operation,  
because in the background there are extra threads running for watching the  
connection, but unfortunately I do so - with each query, I open a new  
TransportClient object. This works reliable but adds to the overall  
turn-around of a request/response cycle, so it will not scale I am afraid.

I am aware kimchy is working hard to improve the TransportClient internals  
but I am curious to learn about the optimal management of the life cyle of  
a TransportClient object (singleton or not) and if sharing of requests via  
a single TransportClient by multiple threads is recommended.

Additionally, I use the admin client via the TransportClient to issue a  
cluster health check command, so in case of a "red" state,  
querying/indexing can be interrupted at the app layer. This adds some more  
overhead to each access via the Java client API but is more robust because  
the web app could in case report a cluster availability problem to the user.

So what are your experiences? Are my assumptions valid? Do I miss  
something? Is a), b) or c) preferable for a web app front-end scenario? Do  
you have some advise for best practice?

Best regards,

Jörg

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [May 25, 2012, 3:11pm UTC](https://discuss.elastic.co/t/what-is-your-best-practice-to-access-a-cluster-by-a-java-client/7865/2 "2012-05-25T15:11:08Z")

</div>

Hi Jörg,

I have the same design. My TransportClient is created by a Spring factory.  
I moved from NodeClient to TransportClient because of a nasty bug with Google guice which cause ES not to release all Threads each time you redeploy your war. You have to restart Jboss.  
TransportClient use less Threads so it seems to be better.

I love also your 3rd option as your webapp doesn't depends on a specific version of ES.

David

Le 25 mai 2012 à 16:26, Jörg Prante [joergprante@gmail.com](mailto:joergprante@gmail.com) a écrit :

> Hi,
> 
> I'd like to learn how you use the Java client API for Elasticsearch and what your experiences are so far.
> 
> My scenario is a web app (\*.war or similar) running on an app server ( e.g. Glassfish, JBoss etc.) installed as a front-end (for security, query translation) to Elasticsearch. The cluster can be remote (but need not to be remote).
> 
> I need robust access, that is, each query or indexing request must be reliably answered by a success or failure event and of course I need fast response times.
> 
> There are at least three variants:
> 
> a) a Node in client mode
> 
> b) a TransportClient
> 
> c) the REST API (HTTP port 9200)
> 
> Let's discuss some of the pros (+) & cons (-) from my naive view as an app developer:
> 
> a) + zero-conf, out-of-the box cluster discovery  
> + automatic failover  
> + fluent API interface  
> - overhead of internal node joining the cluster(?)  
> - missing network interface setup  
> - unreadable binary protocol over port 9300
> 
> b) + almost zero-conf, configurable network interface setup  
> + automatic failover  
> + fluent API interface  
> - slight overhead of TransportClient node when joining the cluster (finding the currently reachable nodes)  
> - additional "sniff" mode for automatic node (re)discovery  
> - unreadable binary protocol over port 9300
> 
> c) + readable protocol over port 9200 (HTTP)  
> - no zero-conf cluster discovery, failover only with external load balancer  
> - overhead of JSON/Java serialization and de-serialization
> 
> Right now, I decided to go with b)
> 
> My assumption was I could manage a TransportClient singleton as a long-lived object. I struggled with connections being apparently dropped (after a certain length of inactivity?), so subsequent client operations gave "no node available" - without being able to refresh the connection by an API method. It's a challenge to understand how keep-alive connections can be configured with TransportClient - after a period of 5000ms by default, the communication seems to time out? Closing and re-opening a TransportClient in a web app environment looks like an expensive operation, because in the background there are extra threads running for watching the connection, but unfortunately I do so - with each query, I open a new TransportClient object. This works reliable but adds to the overall turn-around of a request/response cycle, so it will not scale I am afraid.
> 
> I am aware kimchy is working hard to improve the TransportClient internals but I am curious to learn about the optimal management of the life cyle of a TransportClient object (singleton or not) and if sharing of requests via a single TransportClient by multiple threads is recommended.
> 
> Additionally, I use the admin client via the TransportClient to issue a cluster health check command, so in case of a "red" state, querying/indexing can be interrupted at the app layer. This adds some more overhead to each access via the Java client API but is more robust because the web app could in case report a cluster availability problem to the user.
> 
> So what are your experiences? Are my assumptions valid? Do I miss something? Is a), b) or c) preferable for a web app front-end scenario? Do you have some advise for best practice?
> 
> Best regards,
> 
> Jörg

---

<div class="post-metadata">

**Author:** ![Eric\_Jain](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eric_jain/32/834_2.png) [@Eric\_Jain](https://discuss.elastic.co/u/Eric_Jain)\
**Post date:** [May 25, 2012, 5:46pm UTC](https://discuss.elastic.co/t/what-is-your-best-practice-to-access-a-cluster-by-a-java-client/7865/3 "2012-05-25T17:46:18Z")

</div>

On May 25, 7:26 am, Jörg Prante [joergpra...@gmail.com](mailto:joergpra...@gmail.com) wrote:

> So what are your experiences? Are my assumptions valid? Do I miss  
> something? Is a), b) or c) preferable for a web app front-end scenario? Do  
> you have some advise for best practice?

The TransportClient doesn't support authentication, so if the cluster  
isn't behind the same firewall as the frontend, only c) seems like a  
viable solution.

The Java API supports a) and b), but not c), so you won't be able to  
switch from a) or b) to c) without rewriting your code.

---

<div class="post-metadata">

**Author:** ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)\
**Post date:** [May 29, 2012, 7:49pm UTC](https://discuss.elastic.co/t/what-is-your-best-practice-to-access-a-cluster-by-a-java-client/7865/4 "2012-05-29T19:49:59Z")

</div>

Heya,

You summary is correct. Java Clients (both Node and Transport) should be  
"singletons", thats how they should be used. 0.19.4 have some improvements  
to how it works, and if you see timeouts, it might make sense to increase  
those values (its fine), I updated the transport client page with those  
settings.

On Fri, May 25, 2012 at 4:26 PM, Jörg Prante [joergprante@gmail.com](mailto:joergprante@gmail.com) wrote:

> Hi,
> 
> I'd like to learn how you use the Java client API for Elasticsearch and  
> what your experiences are so far.
> 
> My scenario is a web app (\*.war or similar) running on an app server (  
> e.g. Glassfish, JBoss etc.) installed as a front-end (for security, query  
> translation) to Elasticsearch. The cluster can be remote (but need not to  
> be remote).
> 
> I need robust access, that is, each query or indexing request must be  
> reliably answered by a success or failure event and of course I need fast  
> response times.
> 
> There are at least three variants:
> 
> a) a Node in client mode
> 
> b) a TransportClient
> 
> c) the REST API (HTTP port 9200)
> 
> Let's discuss some of the pros (+) & cons (-) from my naive view as an app  
> developer:
> 
> a) + zero-conf, out-of-the box cluster discovery  
> + automatic failover  
> + fluent API interface  
> - overhead of internal node joining the cluster(?)  
> - missing network interface setup  
> - unreadable binary protocol over port 9300
> 
> b) + almost zero-conf, configurable network interface setup  
> + automatic failover  
> + fluent API interface  
> - slight overhead of TransportClient node when joining the cluster  
> (finding the currently reachable nodes)  
> - additional "sniff" mode for automatic node (re)discovery  
> - unreadable binary protocol over port 9300
> 
> c) + readable protocol over port 9200 (HTTP)  
> - no zero-conf cluster discovery, failover only with external load  
> balancer  
> - overhead of JSON/Java serialization and de-serialization
> 
> Right now, I decided to go with b)
> 
> My assumption was I could manage a TransportClient singleton as a  
> long-lived object. I struggled with connections being apparently dropped  
> (after a certain length of inactivity?), so subsequent client operations  
> gave "no node available" - without being able to refresh the connection by  
> an API method. It's a challenge to understand how keep-alive connections  
> can be configured with TransportClient - after a period of 5000ms by  
> default, the communication seems to time out? Closing and re-opening a  
> TransportClient in a web app environment looks like an expensive operation,  
> because in the background there are extra threads running for watching the  
> connection, but unfortunately I do so - with each query, I open a new  
> TransportClient object. This works reliable but adds to the overall  
> turn-around of a request/response cycle, so it will not scale I am afraid.
> 
> I am aware kimchy is working hard to improve the TransportClient internals  
> but I am curious to learn about the optimal management of the life cyle of  
> a TransportClient object (singleton or not) and if sharing of requests via  
> a single TransportClient by multiple threads is recommended.
> 
> Additionally, I use the admin client via the TransportClient to issue a  
> cluster health check command, so in case of a "red" state,  
> querying/indexing can be interrupted at the app layer. This adds some more  
> overhead to each access via the Java client API but is more robust because  
> the web app could in case report a cluster availability problem to the user.
> 
> So what are your experiences? Are my assumptions valid? Do I miss  
> something? Is a), b) or c) preferable for a web app front-end scenario? Do  
> you have some advise for best practice?
> 
> Best regards,
> 
> Jörg

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 6, 2017, 3:26am UTC](https://discuss.elastic.co/t/what-is-your-best-practice-to-access-a-cluster-by-a-java-client/7865/5 "2017-07-06T03:26:25Z")

</div>


