Fluetndはかなり便利です。
特に Fluentd + ElasticSearch + Kibana の三点セットは
多くの書籍、ブログで紹介されています。
しかし、実際にプロジェクトに導入しようとすると
注意しないといけないことがいっぱい出てきます。
今回はその中でも、ElasticSearchにログが重複で登録されてしまう問題の対応策として
keyにハッシュ値を使用する方法を書きだめします。
Elasticsearchに転送する際にはfluent-plugin-elasticsearchというプラグインを使用します。
まず下記のような設定でElasticsearchに転送しているとします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<match web-access.**> @type elasticsearch host "#{ENV['ELASTIC_SEARCH_HOST']}" type_name ${tag} port "#{ENV['ELASTIC_SEARCH_PORT']}" logstash_format true <buffer tag,time> @type file path /var/log/td-agent/elasticsearch flush_thread_count 4 timekey 3600 timekey_wait 10m chunk_limit_size 128m </buffer> </match> |
Fluetndのメッセージ転送モデルは ‘At most once’と‘At least once’の両方をサポートしています。
その他のモデルに関して下記のように説明しています。
・At most once: Messages are immediately transferred. If the transfer succeeds, the message is never sent out again. However, many failure scenarios can cause lost messages (ex: no more write capacity)
・At least once: Each message is delivered at least once. In failure cases, messages may be delivered twice.
・Exactly once: Each message is delivered once and only once. This is what people want.
Exactly onceを実現するのはめちゃめちゃ難しく
別のモデルを採用して、別の技術で欠損・重複を防いだほうが
効率が良くなる場合が多いそうです。
FluentdからElasticsearchに転送失敗すると
リトライ処理が走ります。
このとき、Elasticsearch側が一意判定に失敗し
ログの重複が大量に発生してしまいます。
これに対応するため
keyをhash値にすることで一意であることを担保します。
fluent-plugin-elasticsearchにはそういった問題に対応するためのfilter機能が搭載されています。
generate-hash-idを使用して
td-agent.confに追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
## ↓ここから追加 <filter web-access.**> @type elasticsearch_genid hash_id_key _hash </filter> ## ↑ここまで <match web-access.**> @type elasticsearch host "#{ENV['ELASTIC_SEARCH_HOST']}" type_name ${tag} port "#{ENV['ELASTIC_SEARCH_PORT']}" logstash_format true id_key _hash #### <- ここ追加 remove_keys _hash #### <- ここ追加 <buffer tag,time> @type file path /var/log/td-agent/elasticsearch flush_thread_count 4 timekey 3600 timekey_wait 10m chunk_limit_size 128m </buffer> </match> |
この設定を追加するだけ。
簡単だね
じゃあね〜〜〜〜。