読者です 読者をやめる 読者になる 読者になる

sorta kinda...

主にAWS関連ですが、これに限らずいろいろ勉強したことや思ったことを書いていきます。

結局 Elasticsearch ってどんな場面で活躍するの? [cloudpack OSAKA blog]

ナスです。なんか気がついたら 1 ヶ月近くも記事を書いてませんでした。
連休とか他にもイベントがあるとついついサボってしまいますね。

前回まで、Elasticsearch の技術的な内容を書いてきましたが、結局何に使えるの?って声がありましたので、ちょっと考えてみたいと思います。

 

基本的な使い方

よく聞くのがログ分析ですね。Web サーバやその他いろんなシステムのログを Elasticsearch に送って、ログを集計したり分析したり、kibana でダッシュボード的に使うとか、まぁそんな感じです。こうやって書くと、それって必要?とか言われます。実際、私もログ扱うのにそんなに困る?って思ってました。

 

ログの集計とか CloudWatch Logs でいいやんって?

CloudWatch Logs だと各リソースからログを集めて一元的に見れるって思いますよね。

使ってみたらわかりますが、いざという時にログ検索するとイラッとします。時間とかインスタンスでロググループが分かれるので、ログは確かに一箇所に集まってはいるけど、欲しい情報がすぐに出てこないです。なんとかすればできるのかもしれませんが、そこにそんな労力はかけたくないんですね。もっと簡単に目的を達成したいわけです。

そこで Elasticsearch です!

 

設定は簡単!

一旦は CloudWatch Logs にログを集めますが、Elasticsearch service に流すサブスクリプション設定をしてしまえば、あっという間に Elasticsearch にログが転送されます。しかもこちらが定義した通りの構造(フィルタ)で json 形式で。
こうすることで項目ごとに検索したり、ステータスごとに集計してダッシュボードに表示させたりできるので、日々の運用で助かる場面が結構出てきます。

まだ東京リージョンにはきていませんが、Kinesis Firehose を使うと、CloudWatch Logs を経由しなくてもログを Elasticsearch に放り込むことができますよ。
Kinesis Firehoseを使用してApache WebログをAmazon Elasticsearch Serviceに送信する | Amazon Web Services ブログ

 

個人的にはトラブルシューティングに役立つと思ってる

障害発生すると、普通ならある程度リソース情報を調べて、各サーバにログインしてログを見ていくわけですが、Elasticsearch 使っているといちいちサーバに入らなくてもログが見れるのが一番嬉しいと思います。

OS やアプリごとに検索の仕方は変わりますし、いろんな統計情報は監視システムで見たりするのって面倒です。でも Elasticsearch があると、そこだけでログ調査ができますし、うまく構造化できていればアクセス解析的な情報も取れるので、ログとアクセス状況とを見比べるような障害対応の時に使えると思います。

ただし、条件もあります。ログはもれなく格納されている必要があるし、分析しやすいように構造を考えないといけないし、そもそもの前提としてログフォーマットが少なくともアプリレベルで揃っている必要があります。(でないと日付とその他全部、と言う風に入れることになる。それは悲しい。)

銀の弾丸なんてないことはみなさんご承知だと思うので、その辺りはうまく使ってあげる必要が出てきます。

 

類似のものはいくつかある

Elasticsearch と似たようなものが他にもあります。

例えば、Sumo Logic は SaaS で提供されています。Elasticsearch と似ていますが、とりあえずすべてのログを放り込んで、調査する時にパースをかけていくので、絶対に前もって構造を考えないといけない、ということがありません。が、それゆえに、データが溜まりすぎるとパースが遅くなる、と言うデメリットもあるようです。あるようです、といったのは、Sumo Logic は使ったことないからです、すみません…
www.sumologic.com

あとは、Splunk が有名ですかね。こちらは、サーバにインストールして使うものと SaaS 提供と選べます。こっちの方が使い勝手がいいように思います。
www.splunk.com

あとは全く調べたことがないですが、BigQuery とかですかね。
BigQuery - アナリティクス データ ウェアハウス  |  Google Cloud Platform

たぶん他にもたくさん似たようなものがあると思います。

 

それぞれ、メリットデメリットがあるので、使いやすいものを使えばいいと思います。なんとなくこれまで使ってきた感想としては、多少苦労してでもコストを抑えたいのであれば Elasticsearch でいいですし、お金払ってでも楽に運用したいのであれば Sumo Logic や Splunk を使った方がいいですね。

今回紹介したものはクラウドを使ったサービスですが、ログの収集元はどこでも大丈夫です。なので、ちょっと気になった方はぜひ使ってみてください。それでもし「これは使える!」と思ったらぜひスモールスタートでいいので導入して運用してみてください。

Apache のアクセスログでオブジェクトサイズが "-" になってた [cloudpack OSAKA blog]

ナスです。

Cloudwatch logs のログを Elasticsearch Service に転送するの、簡単でいいですね。対象のロググループのアクションで、「Stream to Amazon Elasticsearch Service」を選べばいいだけですから。
docs.aws.amazon.com

でも、それで作成される Lambda Function が完璧かというとそうでもありません。残念ながらいろいろと調整しないといけないです。というか本番環境でそのまま使えた試しがまだ一回もないです… 使い方が悪いのかな。

 

Apacheアクセスログだけたまにエラーで転送されない

という事象に出くわしました。本当にたまにです。Elasticsearch Service に転送する Lambda のログを見ると、こんなエラーでした。

2017-04-19T00:00:00.700Z   xxxxxxxxxxxxxx    Failed Items: [
{
    "index": {
        "_index": "cwl-access_log-2017.04.19",
        "_type": "/var/log/httpd/access_log",
        "_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "status": 400,
        "error": {
            "type": "mapper_parsing_exception",
            "reason": "failed to parse [bytes]",
            "caused_by": {
                "type": "number_format_exception",
                "reason": "For input string: \"-\""
            }
        }
    }
}
]

ちなみにログ転送する際に定義したフィルタは↓これです。

[host, id, user, date, request, status, bytes, other]

bytes に入れようとした値が -(ハイフン) だったので、それ数値じゃねーよ!って言われてます。

 

対処は簡単

対処法は 2 つあります。

1 つは、Lambda で bytes にあたる値が “-” だったら 0 にする。もう 1 つは、httpd 側でログフォーマットを変更する。です。

httpd のログフォーマットについては、ここをみれば ok です。
ログファイル - Apache HTTP サーバ バージョン 2.2

該当の説明を見ると、

この最後のエントリはクライアントに送信されたオブジェクトの、 応答ヘッダを除いたサイズを表します。コンテントがクライアントに送られなかった 場合は、この値は “-” になります。コンテントが無い場合に “0” をログ収集するには、%b ではなく %B を使ってください。

とありますので、ログフォーマットを %B に変更してやればいいわけです。結局、Lambda 側で調整することにしたので、httpd のログフォーマットで調整できるかどうかは試していませんが、たぶんできると思います。

 

この件で思ったのは、ログファイルごとにログフォーマットがちゃんと揃ってないと Elasticsearch Service に転送する時にエラーが出まくることになるので、注意が必要だということです。ミドルウェア等のログフォーマットはだいたい揃っていると思いますのでいいのですが、自社や他ベンダーが開発したアプリケーションのログも Elasticsearch Service に転送するなら、ログフォーマットがどうなっているかよく調べたほうがいいと思います。

Amazon Elasticsearch Service でデータが保存されなくなった話 [cloudpack OSAKA blog]

ナスです。

またまた Elasticsearch の話です。今回は Amazon Elasticsearch Service にデータが保存されなくなった話です。Amazon 特有の話なのかそうでないのかわかりませんが、実際に起こったので書いておきます。

 

気がついたら何も保存されていなかった

初期構築を終えて数日運用した後に Elasticsearch Service の様子を見てみたら、Indices タブにあるべきインデックス名が全く出ていませんでした。クラスタ数は 1 で設定してあるので、ステータスは常に Yellow だったので、これが原因とは思えない。かといってストレージの空きはわりとある。って状況で、最初はなかなか原因がわかりませんでした。

 

Monitoring タブで見れるグラフがなんかおかしい

Elasticsearch Service のグラフを見ていると、なんか気になる形を発見。Write IOPS が 0 だ…

この状況を基にいろいろ調べたら、このドキュメントが出てきました。
AWS サービスエラー処理 - Amazon Elasticsearch Service

なんかメモリくさいな… と思って、CloudWatch で Write IOPS と JVMMemoryPressure のメトリクスを見るとこうなってました。
f:id:nasrinjp1:20170418221211p:plain

JVMMemoryPressure が92,93% あたりを超えると Write IOPS が 0 になり、JVMMemoryPressure が下がると同時に Write IOPS も増えていました。

 

原因は?

ドキュメントには、

t2 インスタンスでは、[JVMMemoryPressure] メトリクスが 92% を超えた場合、クラスターが赤の状態になるのを防ぐため、Amazon ES はすべての書き込みオペレーションをブロックすることによる保護メカニズムをトリガーします。

と書いてありますが、この環境ではデフォルトの m4.large を使っていますので、どうやら t2 だけに限らないっぽいです。もしかしたらデフォルトのインスタンスサイズ& t2 がこれに引っかかるという可能性もあります。(他のインスタンスタイプでは試せてないのでわかりません

 

どう対処したのか?

今回は、データが多すぎてメモリも多く使われたのだと仮定して、先日書いた↓の対応を行いました。
nasrinjp1.hatenablog.com

不要なデータを消した直後から、JVMMemoryPressure も下がり、無事に Write IOPS もガンガン上がり始め、ようやくデータが保存されていきました。

他には、クラスタ数を増やす、インスタンスのサイズをあげる、等の選択肢もありますが、不要なデータがたまりすぎている状況なら素直に不要データを削除するのがいいと思います。後は、JVM 関連のパラメータ調整くらいですかね。

 

Elasticsearch Service はマネージドサービスですが、ちゃんと使い方や特性を理解した上で運用しないと痛い目にあうなと思いました。マネージドサービス=何も気にしなくても運用できる、ではないことを再認識させられました。