LoginSignup
33
18

More than 5 years have passed since last update.

AWS Elasticsearch Serviceが律儀にgzipを返すようになって死んだ [解決済み]

Last updated at Posted at 2017-10-04

エラー内容

今朝起きたら、 Elasticsearch + Rails にこんなエラーが起こっていた。

MultiJson::ParseError: unexpected character at line 1, column 1 [parse.c:664]

なんと、いままで Accept-Encoding を無視していた AWS Elasticsearch Service が、急に仕事をしだして、 gzip 形式で返すようになった模様。

追記: なお、 elasticsearch-rails で利用されている faraday は、 Accept-Encoding: gzip がデフォなようです。

バージョン

追記しました

elasticsearch (5.0.0)
elasticsearch-api (5.0.0)
elasticsearch-transport (5.0.0)
elasticsearch-dsl (0.1.4)
elasticsearch-model (0.1.9)
elasticsearch-rails (0.1.9)
elasticsearch-transport (5.0.0)
faraday (0.9.2)
faraday_middleware (0.12.2)
faraday_middleware-aws-signers-v4 (0.1.5)

最新版からは若干古いです。

解決法

faraday_middleware gemを使って、gzipを受け取れるように変更する。

Gemfile

...
gem 'faraday_middleware'
...

config/initializers/aws.rb


Elasticsearch::Model.client = Elasticsearch::Client.new(
  host: ENV.fetch('ELASTICSEARCH_ENDPOINT'),
  port: 80
) do |faraday|
  faraday.use FaradayMiddleware::Gzip # ここを追加
  faraday.request :aws_signers_v4,
                  credentials: Aws::Credentials.new(ENV.fetch('AWS_KEY_ID'), ENV.fetch('AWS_ACCESS_KEY')),
                  service_name: 'es',
                  region: 'ap-northeast-1'
  faraday.adapter Faraday.default_adapter
end

被害者の会

他にも被害者はいる模様。
https://forums.aws.amazon.com/thread.jspa?threadID=223784

Posted on: Sep 26, 2017 10:56 AM

Just my personal experience -
Without any client changes, one day the ES responses stopped working. When I inspected the response, it was gzipped. The client library I was using requested gzip. Since I didn't make any changes to my client code, I am guessing that the following things are true, but none of them are really proven:

a) the client library had always been requesting gzipped responses ( evidence: https://github.com/elastic/elasticsearch-ruby/issues/457#issuecomment-326204925 )
b) the client library was not equipped to receive gzipped responses ( evidence: my code doesn't work )
c) the AWS ES service used to ignore the request for gzipped response, and now it honors it. ( evidence: my code used to work )

I was not able to figure out how to get my client library to stop requesting gzipped responses (seems it would require modifying the faraday library), but by changing my code to look like https://github.com/elastic/elasticsearch-ruby/issues/457#issuecomment-326020618 , I was able to get my client library to understand the gzipped response.

Hope those data points help.

ただ、時系列がずれているので、AWSが順次アップデートをしていったのだろうか?
詳細はAWSにコンタクトする予定。

こちらは、ほぼ同時刻の被害者の方
https://qiita.com/s_nakamura/items/49b19f2544aa61229bbc

コメント

gzip対応してないのにAccept-encodingでgzip投げてた利用者側が悪いのでは?

仰る通りです。。
OSSのライブラリを使っている以上、そのライブラリの挙動の責任は利用者にありますね。この記事のタイトルから「AWSやべー」という声が聞こえてきそうですが、どちらかと言うと、「いままでgzip無視しててごめんね、今朝直しといたから」と言った感じですね。

Amazon Elasticsearchのgzipの件、全ノードでgzipが返ってくるわけじゃなくてあるノードでだけgzip返ってくる罠
挙動が戻ってまたエラーになったら...

レスポンスがgzipでない場合、何もせず通過させるので、この変更を入れておけば、仮に挙動がもとに戻っても大丈夫なはずです。

追記 10/4 11:15 p.m. JST

とここまで書いてて気づいたが、 faraday_middleware によると、 Faraday.default_adapter == :net_http を使うと、Gzipは自動解凍されるよう。。。なんだこれ

  # This middleware is NOT necessary when these adapters are used:
  # - net_http on Ruby 1.9+
  # - net_http_persistent on Ruby 2.0+
  # - em_http

追記 10/5 12:10 a.m. JST

真の原因は、これかな?(未検証)

https://github.com/elastic/elasticsearch-ruby/issues/457#issuecomment-326204925
faraday_middleware-aws-signers-v4 は IAM Role から Elasticsearch Service の認証通す middleware

Can this be the reason why compression is enabled by default ?
https://github.com/winebarrel/faraday_middleware-aws-signers-v4/blob/588b8c1086a72e2762ea3834bfff3d9f71b66024/lib/faraday_middleware/request/aws_signers_v4.rb#L70

if Net::HTTP::HAVE_ZLIB
  env.request_headers['Accept-Encoding'] ||= 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3'
end
33
18
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
18