# Transport Clientによる検索を維持しつつノードを再起動したい

**URL:** <https://discuss.elastic.co/t/transport-client/941>\
**Category:** 日本語による質問・議論はこちら\
**Created:** [May 20, 2015, 7:02am UTC](https://discuss.elastic.co/t/transport-client/941 "2015-05-20T07:02:59Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![bigwheel](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/bigwheel/32/44826_2.png) [@bigwheel](https://discuss.elastic.co/u/bigwheel)\
**Post date:** [May 20, 2015, 7:02am UTC](https://discuss.elastic.co/t/transport-client/941/1 "2015-05-20T07:02:59Z")

</div>

シチュエーション

1. 3台のノードからなるクラスタに[JavaのTransport Client](https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/client.html#transport-client)で接続（接続先IPアドレスに3つのノードすべてを列挙）
2. 1台のノードをシャットダウン・起動
3. 20%前後の確率で [https://github.com/elastic/elasticsearch/issues/11202](https://github.com/elastic/elasticsearch/issues/11202) のエラーがJava Client側で発生

* * *

概要

Javaアプリケーションを起動したまま、検索できる状態を維持しつつノードを1つずつ再起動したいです(ローリングアップデートなどのため)。  
しかしTransport Clientで接続した場合、ノードを再起動するとcatchすることができないエラーが発生する場合があります。

これに対する私が知っている解決策は現状3つあります。

1. REST API(9200ポート)をLBで束ねてREST APIへアクセスする。ノードのシャットダウン時にはLBからそのノードを一時的に切り離す
2. Node Clientを使用する(手元で実験してみたところNode Clientによる接続ではエラーは発生しませんでした)
3. ノードのシャットダウン前にTransport Clientの接続先一覧からそのノードのIPを削除、その後Javaアプリケーションを再起動してTransport Clientがシャットダウンするノードへアクセスしないようにする(起動後には逆の手順を行う)

しかし、現状の私達の環境で採用するにはそれぞれ問題があります。

1. 現状使用しているelastic4sというライブラリが使えない
2. ノードサーバからアプリケーションサーバへの接続がネットワーク環境の制約上できないため使えない
3. 3ノード・2アプリケーションの場合、接続先の書き換えと再起動を8回もする必要があり煩雑。

Transport Clientによる検索を維持しつつノードを再起動する方法はなにかないでしょうか？

---

<div class="post-metadata">

**Author:** ![johtani](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/johtani/32/44956_2.png) [@johtani](https://discuss.elastic.co/u/johtani)\
**Post date:** [May 21, 2015, 8:33am UTC](https://discuss.elastic.co/t/transport-client/941/2 "2015-05-21T08:33:19Z")

</div>

@johtani です。

制約について確認ですが、elastic4sがTransportClientを使っているということでいいでしょうか？  
あと、2番目のネットワーク環境の制約がちょっと理解できませんでした。

TransportClientはラウンドロビンで接続先を決めているだけで、クラスタの状態まではわかっていないので、難しいかと。

案として、アプリケーションサーバでElasticsearchをクライアントノードとして起動するというのはどうでしょうか？  
そして、アプリケーションからは、ローカルのクライアントノードに対してTransportClientで接続してみるというのは？

---

<div class="post-metadata">

**Author:** ![johtani](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/johtani/32/44956_2.png) [@johtani](https://discuss.elastic.co/u/johtani)\
**Post date:** [May 21, 2015, 8:59am UTC](https://discuss.elastic.co/t/transport-client/941/3 "2015-05-21T08:59:15Z")

</div>

あとは、elastic4sがTransportClientを利用しているという意味であれば、elastic4s側でExceptionをキャッチして、リトライの処理を行うようにしてもらうというのもいいかもしれないです。  
Exceptionである以上、キャッチできないというのはないと思うので。

---

<div class="post-metadata">

**Author:** ![bigwheel](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/bigwheel/32/44826_2.png) [@bigwheel](https://discuss.elastic.co/u/bigwheel)\
**Post date:** [May 21, 2015, 9:45am UTC](https://discuss.elastic.co/t/transport-client/941/4 "2015-05-21T09:45:04Z")

</div>

> 制約について確認ですが、elastic4sがTransportClientを使っているということでいいでしょうか？

はい、その通りです。

> あと、2番目のネットワーク環境の制約がちょっと理解できませんでした。

私達のところではESクラスタのネットワークとアプリケーションサーバが別のサブネットに所属しておりnat越しになっているため、  
アプリケーションサーバ → ESクラスタはアクセスできても逆ができない構成になっています。

Node Clientを使用する場合、  
Node Client → 接続先のデータノード  
への接続だけではなく、  
接続先のデータノード → Node Client  
へもpingが通らないと(publish\_hostが見えないと？)Node Clientが使えない、よって私達のところのネットワークではNode Clientは使えない、と思っていたのですがこの理解は間違っていたりしますか？

> 案として、アプリケーションサーバでElasticsearchをクライアントノードとして起動するというのはどうでしょうか？  
> そして、アプリケーションからは、ローカルのクライアントノードに対してTransportClientで接続してみるというのは？

アプリケーションサーバ内でクライアントノードを立ち上げようともしてみたのですが、前述のnat越しの問題のためか同じクラスタとして立ち上げることが出来なかったように思います。

> あとは、elastic4sがTransportClientを利用しているという意味であれば、elastic4s側でExceptionをキャッチして、リトライの処理を行うようにしてもらうというのもいいかもしれないです。  
> Exceptionである以上、キャッチできないというのはないと思うので。

すみません、これは自分の勘違いでした。キャッチできます。

> <https://gist.github.com/bigwheel/df9d0fc6dd429c26333f>

上のようなコードで実験してたのですが、stacktrace上に自分のコードが出てこないのでcatchできていないと勘違いしていました。  
実際にはきっちりcatch移行の部分を通っていました。

catchできてるのでリトライを入れるのが一番楽ですかね。

---

<div class="post-metadata">

**Author:** ![johtani](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/johtani/32/44956_2.png) [@johtani](https://discuss.elastic.co/u/johtani)\
**Post date:** [May 21, 2015, 9:53am UTC](https://discuss.elastic.co/t/transport-client/941/5 "2015-05-21T09:53:08Z")

</div>

確かにping通らないと厳しいですね。  
であれば、クラスタ側にクライアントノードを立てるのも一つの案かと思いますがどうでしょう？  
LBの方が運用が楽という話であれば別ですが。

---

<div class="post-metadata">

**Author:** ![bigwheel](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/bigwheel/32/44826_2.png) [@bigwheel](https://discuss.elastic.co/u/bigwheel)\
**Post date:** [May 21, 2015, 10:31am UTC](https://discuss.elastic.co/t/transport-client/941/6 "2015-05-21T10:31:47Z")

</div>

クラスタが存在するネットワーク側にクライアントノードを建てることも考えたのですが、  
ローリングアップデートのときは結局クライアントノードもアップグレードする必要が有るためシャットダウン・起動する必要がある → 結局同じエラーが発生する可能性があるのでそれでは解決できないという結論になりました。  
あと、クラスタが存在するネットワークが物理サーバー用のネットワークであるためクライアントノードを建てる場合は物理サーバーである必要があり、コスト面でNGというのもあります。

---

<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, 1:52pm UTC](https://discuss.elastic.co/t/transport-client/941/7 "2017-07-06T13:52:20Z")

</div>


