fluent-plugin-elasticsearch(elasticsearch-ruby)で負荷分散してる場合のリトライ設定
結論的にはマニュアル以上の情報はないです。個人的メモに近い感じ。
この辺は気軽にテスト/確認しづらいレイヤだと思ってるので、具体的な実装を知らないと怖かったので調べてみました。
背景
世にある記事だと、elasticsearchサーバのローカルにfluentd receiverを置いて、そこからesに投入する形式が多く見られた。
が、それだとreceiverが生きててesプロセスだけが死んだ場合にデータの投入が部分的に止まるよねってことで、送信元のfluentdからesに直接接続して投入することにした。
その場合fluent-plugin-elasticsearch
が分散処理を行うので、その部分のfailure/retryの扱いやパラメータを調査した。
ポイント
先に、設定項目とかのまとめだけ。
fluent-plugin-elasticsearch
は内部的にelasticsearch-ruby
(elasticsearch-transport
)を利用していて、そこが接続管理をしている。設定を検討した方がいい
elatissearch-ruby
の項目は以下reload_connections
reload_on_failure
- 接続失敗した場合にサーバリストを更新するか否か。
- これは
true
にするのが良さそうだが、サービスの監視体制等次第かも。正常にクラスタから外れないまま壊れたサーバが出るとどうなるだろう。。。 reload_connections
の長さとのバランスにもよる。
retry_on_failure
- サーバがunreachableだった場合のretry可否と試行回数。
true
指定だとdefaultの3
が使われる。 fluent-plugin-elasticsearch
では5
で固定。まぁそんもん感。
- サーバがunreachableだった場合のretry可否と試行回数。
retry_on_status
- サーバエラーが返ってきた時にretryするかどうか。
- クラスタのうちの1台だけが異常になった場合とか想定すると、
true
したい。- ...だが、これは
fluent-plugin-elasticsearch
では指定できない。
- ...だが、これは
環境次第だがWARNのログも閾値設けて監視の対象とした方が安全そう
- ここを見ないとLANポート・ケーブル故障とかネットワーク異常系の場合に気づきにくそう
reload_connections
をしていれば無停止でクラスタ構成変更に対応できるが、confの書き換えは忘れず行う必要があるので手順漏れがないよう注意以下項目は、関連するがdefaultのままでもたぶん支障はない
resurrect_after
- default
60
- default
resurrect_timeout
fluent-plugin-elasticsearch
にはない
sniffer_timeout
fluent-plugin-elasticsearch
にはない
以下詳細
まぁほぼソースコードの解説なので。。。
アクセスエラー処理の流れ
対象となるソースコードはこのあたりにまとまっている。
とくにBase#perform_request
が中心。
- 指定された選択方式(RRとか)で接続先サーバを決め、リクエストを送る
- retry対応が走るのは以下のパターンだけで、それ以外は問答無用で死ぬ
unreachableだった場合(Timeout / ConnectionFailed)
- 対象サーバは死亡判定を受ける
reload_on_failure
パラメータがあれば、接続不能なサーバにあたった時点で即座にサーバリストのリロードが走るretry_on_failure
パラメータが設定されていると、改めてretry- max回数を超えるまでは失敗してもWARNしか吐かないので、WARNログをチェックしたほうが良さそう
[#{e.class}] Attempt #{tries} connecting to #{connection.host.inspect}
ServerErrorだった場合
retry_on_status
パラメータがあるなら、無条件でretry- エラーを返したサーバに接続ペナルティはない(dead判定もfailure判定もされない)ので、調子悪いサーバが対象から外れることはない。
- WARNで出る
[#{e.class}] Attempt #{tries} to get response from #{url}
のログをちゃんと監視しておくと良いのかもしれない。 - max失敗するとFatal。default回数は3。
retry_on_failure
パラメータに数字を渡すと変えられる。
- パラメータがないならそのまま失敗する!!
なお、fluent-plugin-elasticsearch
にはretry_on_status
がないので、この処理は通らない。
死亡判定と復帰判定
サーバの死亡判定はunreachable時、復帰の判定は接続先サーバの選定時に走る。
死亡判定
unreachableになると一旦死亡判定される
- 死亡判定をされると、メモリ上に死亡フラグと失敗回数インクリメント、死亡時刻が記録される
reload_connections
パラメータがセットされてると、指定リクエスト回数毎にサーバリストのリロードが走る
- メモリがクリアされると死亡判定は消えちゃうよ
- 死亡判定されると一旦接続対象から外されて、復帰判定を待つ
復帰判定
unreachableになったサーバにも再度接続のチャンスを与えるために、一定時間経過の後で復帰判定が行われる
resurrect_after
パラメータが関与- 最後のアクセスから
resurrect_after
秒後に復活チェック(default: 60sec) - 死亡判定を受けたConnectionが、死亡時刻から
resurrect_timeout x (2 ** 失敗回数-1)
経っていたら復帰させる
復帰のあと、接続に成功した場合
復帰後にちゃんと接続に成功したら、正常に戻ったと判定されて失敗回数がクリアされる
対象サーバリストのリロード
- 実際にクラスタにnode情報を取りに行って、対象サーバのリストを更新する
- その際のtimeoutは別途
sniffer_timeout
で決められる(default: 1)
- その際のtimeoutは別途
- この機能を使うことで、設定ファイルのhostsリストを編集・リロードすることなく、クラスタ群の追加削除に対応できる
- ただし情報はメモリ上にロードされるだけなので、設定ファイルの更新は併せて行う必要がある
だいたいこんな感じ。そんじゃーね。