ブログトップ 記事一覧 ログイン 無料ブログ開設

wyukawa’s blog

2016-11-28

kafka-fluentd-consumerとfluencyとfluent-plugin-elasticsearchのメモリに関する話

うちの環境ではkafkaに入ってるログをkafka-fluentd-consumer 0.3.0でconsumeしたのちにfluent-plugin-elasticsearch 1.9.0経由でElasticsearchになげるということをしています。

fluent-plugin-elasticsearchは8プロセス動いていて各プロセスがメモリを5〜8GB使っている状態でした。マシンのメモリは64GBだったので割とメモリがかつかつな状態だったせいか、以下のようなログをはいてkafka-fluentd-consumerが落ちるという状況が発生していました。

failed; error='Cannot allocate memory' (errno=12)
#
# Native memory allocation (mmap) failed to map 555745280 bytes for committing reserved memory.

hs_err_pid[pid].logは下記のような感じ。

#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 555745280 bytes for committing reserved memory.
# Possible reasons:
#   The system is out of physical RAM or swap space
#   In 32 bit mode, the process size limit was hit
# Possible solutions:
#   Reduce memory load on the system
#   Increase physical memory or swap space
#   Check if swap backing store is full
#   Use 64 bit Java on a 64 bit OS
#   Decrease Java heap size (-Xmx/-Xms)
#   Decrease number of Java threads
#   Decrease Java thread stack sizes (-Xss)
#   Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.
#
#  Out of Memory Error (os_linux.cpp:2627), pid=2605, tid=140344240674560
#
# JRE version: Java(TM) SE Runtime Environment (8.0_66-b17) (build 1.8.0_66-b17)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode linux-amd64 compressed oops)
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#

kafka-fluentd-consumerはfluencyを使ってfluentdにログを投げています。

fluencyに関してはこちらを参照

で、fluencyは自身のバッファにoff heapを使っているのですが、そこでメモリを確保できなくて落ちたっぽいです。この辺スタックトレースもないのでわかりづらい。。。

fluencyのバッファサイズを減らす手もありますが、一方でBufferFullExceptionが出たからバッファサイズを増やした経緯もあります。

一旦fluent-plugin-elasticsearchのバッファをメモリからファイルに変えて様子を見ているところです。要はマシンの空きメモリ容量が増えれば良いと思ったため。

fluentdのメモリの使用状況は以下のような感じ。2回再起動しているので2つの谷がありますが、最初と最後に注目すると、5〜8GBから4〜5GBに下がっています。もっとも徐々に増えているのでまだ安心はできませんが。

f:id:wyukawa:20161128141907p:image

fluencyは内部のバッファが一杯になるとBufferFullExceptionをthrowします。これをcatchしてretryするかどうかはアプリケーション側に判断を委ねています。まあ集約ノードでも無い限りそんなに大量のログをなげないと思うので末端ノードだったらBufferFullExceptionが起きることは無いような気はします。

kafka-fluentd-consumerではBufferFullExceptionをcatchしてretryしています。

それは良いんですが、kafka-fluentd-consumerはちょいちょい例外を無視してます。これはおそらくログファイルが大きくなってディスクを圧迫するのを避けるためだとは思いますが、少し困る場合もあります。

うちの環境だとkafka-fluentd-consumerからログ送信した先のfluentdで下記のようなwarnがでていました。

[warn]: no patterns matched tag="failed"

これはkafka-fluentd-consumerがログ送信に失敗した場合はfailedタグをつけてエラーデータを送信するためです。受信側でfailledタグを受け取っていなかったので上記のエラーが出ていました。で、エラーの詳細を知りたい場合は受信側でfailedタグを受け取ってファイルに出力して確認するなどが必要になります。

2016-11-22

Elasticsearch 2.4から5.0.1にアップグレードしていろいろはまった

手元でカジュアルに運用しているElasticsearch 2.4(2.4.1だったかも)をえいやと5.0.1に上書きアップグレードしていろいろはまったのでメモっておく。

その前にElasticsearch 5がどんな感じなのかはwyukawa’s tumblr, johtaniさんとElasticsearchについて話しましたGuest...を聞くと良いと思います。まあ宣伝です。

まあこういうのは2つクラスタ用意してblue green deploymentするのが安全だと思います。

ただどっちにしろクライアントの対応状況にも気をつけたほうが良いです。REST API使ってるやつならだいたい大丈夫だと思いますが、Java系だと互換性が無いんじゃないかな。

僕の環境ではfluent-plugin-elasticsearchから書き込んでますが、アップグレード作業中はデータを止めたほうが良いと思いました。

データがくる状態でアップグレード作業してたらOutOfMemoryが出たりtoo many open files出たりしてましたが、データ流入止めてElasticsearch再起動したら落ち着きました。

公式のアップグレード手順は下記ですが、これだけだと正直に言ってはまると思いました。

Full cluster restart upgrade | Elasticsearch Reference [5.0] | Elastic

なので上記に書かれていないことではまったことをつらつら書きます。


プラグイン

まず僕は HeadとKopfという2つのプラグインを使っていましたが、これはそのままでは使えなくなりました。

Elasticsearch 5.0とともにsite pluginを動かす | Elastic

プラグインが入っている状態でアップグレードしてもElasticsearchが起動しないので、Elasticsearch 2.4を止めた後に下記のようにしてプラグインを削除します。

/usr/share/elasticsearch/bin/plugin remove head
/usr/share/elasticsearch/bin/plugin remove kopf

その後、Elasticseach 5.0.1が起動したら後継であるGitHub - lmenezes/cerebroをセットアップすれば良いです。見た目はまんまKopfだけど作者が同じだしね。


ES_HEAP_SIZEは使えないので代わりにES_JAVA_OPTSを使う

Elasticsearch 5.0.0-alpha2 released | Elastic

Importantly, you can no longer use the ES_HEAP_SIZE environment variable

とのことです。


インデックスの設定はnodeの設定に書かない

elasticsarch.ymlにslow log設定を書いてると下記のようなエラーになります。

Found index level settings on node level configuration.

Since elasticsearch 5.x index level settings can NOT be set on the nodes
configuration like the elasticsearch.yaml, in system properties or command line
arguments.In order to upgrade all indices the settings must be updated via the
/${index}/_settings API. Unless all settings are dynamic all indices must be closed
in order to apply the upgradeIndices created in the future should use index templates
to set default values.

pull requestはPrevent index level setting from being configured on a node level by s1monw ? Pull Request #17144 ? elastic/elasticsearch ? GitHubだと思います。

僕はHistogram aggregation causes OOM on 2.3.2 ? Issue #18635 ? elastic/elasticsearch ? GitHubに遭遇したときにslow log設定を入れたのですが、そもそもこのissueのようにハングアップする場合はslow logの意味は無かっのでこの設定は消しました。


VIPを持っているホストでnetwork.host: 0.0.0.0だとVIPにつなぎにいこうとしてエラーになる。

なので下記のようにネットワークインターフェースを使います。VIP使ってなければ関係ないと思います。

network.host: _bond0_
network.bind_host: 0.0.0.0

参考

Network Settings | Elasticsearch Reference [5.0] | Elastic


フィールド名の先頭にドットがあるとエラーになる。

Elasticsearchは1系ではドットがOKで2系でNGになり5系でまたOKになったという経緯があります。

Elasticsearch 2.4.0 released | Elastic

が、しかし、フィールド名の先頭にドットがあるとエラーになったので質問してみた。

"name cannot be empty string" error if field name starts with - Elasticsearch - Discuss the Elastic Stack


count APIにid検索使うとエラーになる。

$ curl -XGET 'localhost:9200/.kibana/index-pattern/_count?q=_id:aaa-*&pretty'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "query_shard_exception",
        "reason" : "Can only use prefix queries on keyword and text fields - not on [_id] which is of type [_id]",
        "index_uuid" : "bXfFwplIT1-GhfmQ_YIJ3g",
        "index" : ".kibana"
      }
    ],
    "type" : "search_phase_execution_exception",
    "reason" : "all shards failed",
    "phase" : "query_fetch",
    "grouped" : true,
    "failed_shards" : [
      {
        "shard" : 0,
        "index" : ".kibana",
        "node" : "N13vRpZMRg-FNB8Ggdl1tA",
        "reason" : {
          "type" : "query_shard_exception",
          "reason" : "Can only use prefix queries on keyword and text fields - not on [_id] which is of type [_id]",
          "index_uuid" : "bXfFwplIT1-GhfmQ_YIJ3g",
          "index" : ".kibana"
        }
      }
    ],
    "caused_by" : {
      "type" : "query_shard_exception",
      "reason" : "Can only use prefix queries on keyword and text fields - not on [_id] which is of type [_id]",
      "index_uuid" : "bXfFwplIT1-GhfmQ_YIJ3g",
      "index" : ".kibana"
    }
  },
  "status" : 400
}

curator 3はElasticsearch 5に対応していない。curator 4を使う必要がある。

GitHub - elastic/curator: Curator: Tending your Elasticsearch indices


FlinkはまだElasticsearch 5に対応していない。

[FLINK-4988] Elasticsearch 5.x support - ASF JIRA


Kibana 5についても書いておきます。

アップグレード自体はすんなりいきました。

ドキュメントはStandard Upgrade | Kibana User Guide [5.0] | Elastic かな。


localhost以外からもアクセスする

まずlocalhost以外からもアクセスできるように下記の設定を追加します。

server.host: 0.0.0.0

Timelionのページが真っ白

KibanaでTimelionのリンクをクリックしてもページが真っ白で何も表示されない。

After installation on Kibana 4.2.0 the page is blank ? Issue #12 ? elastic/timelion ? GitHubと同じ気がしたのでコメントしといた。

2016-11-20

wyukawa's podcastの現在

早いものでpodcastを始めて2ヶ月ほど経ちました。配信したエピソードは12個あって、必要な情報は下記からたどれると思います。SoundCloundの統計を見る限り1エピソードあたりだいたい200〜300ほど再生されているようです。せっかくゲストに出てもらっているのでもうちょっと増やしたいなあと思ってますが、どうやるのが良いのか考え中です。

webページ

http://wyukawa.tumblr.com/

iTunes

https://itunes.apple.com/jp/podcast/wyukawas-podcast/id1152456701

Twitterハッシュタグ

https://twitter.com/hashtag/wyukawafm?src=hash


いろいろフィードバックもらって収録環境も少し変えたのでその辺を書いてみます。

ゲストを呼んでオンラインで収録するときはSkypeつかってやってます。以前はPodcastの始め方 - wyukawa’s blogのようにやってましたが、最近はSkype Call Recorderを使って録音したものをAudacityにかけてノイズ除去してます。なのでこの場合はGarageBand使わないですね。

podcast始めた時からブーンっていう雑音が入っているのが気になってたんですけど、どうやらこれはハムノイズって言われているもののようでした。僕はMacBook Airを使って収録しているんですけど、電源ケーブルとヘッドセットを両方つけて録音すると発生しているようだったのでep11からは電源ケーブル外して収録してます。なのでep11, ep12は音質が割と良いと思います。

ホスティング環境はSoundCloundなんですが、無料だと3時間分しかあげられないので無制限のPRO UNLIMITEDにしてます。https://soundcloud.com/pro

GitHub使えばホスティングは無料でできますが、まあその辺は金で解決しちゃっております。ただSoundCloundの統計情報はそんなに充実してない気がします。hourlyごとの視聴数とかも知りたいけどないですね。この辺はデータエンジニアとしては気になります。iTunesは統計情報をくれないので自分でホスティングしている場合はその辺他の人はどうしてるんだろう。Google Analyticsとかかな。

他にはPodcastのやっていきかた - ?????を読んでうっかりBlue Micro Yetiを買ってしまったのでオフラインでゲスト呼んで収録するときは使おうかと思います。

Blue Micro Yeti USB 2.0マイク 15374

Blue Micro Yeti USB 2.0マイク 15374

2016-11-11

Prometheus Casual Talks #2を開催しました

Prometheus Casual Talks #2 - connpass

Prometheus Casual Talks #2 まとめ - Togetterまとめ

Prometheus開発者のBrian Brazilさんが来日するのでそれにあわせてPrometheus Casual Talks第二回を開催しました。

第一回の様子はPrometheus Casual Talks #1を開催しました - wyukawa’s blog参照

スライドはそのうち全部上がると思いますが、今回はLINE LIVEでの録画があるので気になる方はそちらをチェックしていただくと良いと思います。Prometheus Casual Talks #2 - LINE LIVE

内容としてはBrianさんがPrometheusの入門的な内容を、@tokuhiromさんがPrometheusをJavaアプリケーションをモニタリングする話を、@mtandaさんがGrafana周りの話を、@kfdmさんがPrometheusを使ってPrometheusそのものやアラート回数などをモニタリングする話を、しました。


PrometheusはDockerというかImmutable Infrastructure界隈で使うのが一般的で、前回も今回もそういう話題は少なかったので、その辺を知りたい方には物足りなかったかもしれません。そういう環境だとService Discoveryの技術を活用するのが必要で、だからこそPrometheusもKubernetesやEC2などとの連携を重視しているように見えます。

また会場で少し話題になったPush vs Pullの宗教的な議論がありますが、ほとんどのモニタリングソフトはPush型でPull型のほうがレアだと思います。Prometheus, Borgmon以外だとNagiosとかCloudForecastかな。

僕が考えるPull型のメリットはPush型に比べて中央のサーバーがつまりにくいことかなと思います。つまりそうになったらサーバー増やしてPullするものを分割すればいい。あとHAが容易にできる。アラートもモニタリング対象サーバーからPushするモデルだとそのサーバーがダウンしてたらPushできない、なのでタイムアウトがあったりするけど、Pull型だったら最初から外形監視っぽく使える。

ただPull型だとPullする対象のサーバーを探さなくちゃいけないので、だからこそService Discoveryの技術が必要。ただうちみたいにオンプレミス環境だとその必要性が薄くて、だからこそpromgenが出てきたという。

またPull型だとファイアーウオールの壁を越えられないので、商用モニタリングソフトとしてはちょっと採用しにくい。もっともPromCon 2016でプレゼンがあったFrankensteinはPrometheusベースの商用モニタリングサービスだけど、そこの部分をPush型にしている例だと理解しています。

Long Term Storageの話題も少し出ましたが、Prometheus開発者としてはそこは他のプロジェクト、例えばFrankensteinだとDynamoDB, S3だし、VulcanだとCassandraのように任せてコア側はインターフェースを用意するという方向性のようです。

2016-10-30

富山マラソン走ってきた

結果はネットタイムが4時間32分でした。4時間30分は切りたかったけど練習不足なのでしゃーない。

富山マラソンは今年で2回目で僕は初参加です。

いつもこの時期はしまだ大井川マラソンに出てるんですけど、今年は富山マラソンに出てみました。

運営もよくストレスなく走れました。

高岡市役所前をスタートしてこの大会のおそらく目玉である新湊大橋を通って富山市の富岩運河環水公園がゴールです。

ワンウェイです。

エイドは白エビの天むすとます寿司がおいしかったです。

菓子パンもいっぱいあって全部食べたかったんですけど、意外と胃がうけつけなかったのでちょっとだけ食べました。