BufferedOutput of Fluentd

この記事は【2014年5月8日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

fluentdのBufferedOutputについて理解が浅かった。。

fluentdでアプリケーションサーバーからのログを集約するAggregatorノードの設定をメモリ容量をもとに見直していたところ,出力先に何らかの障害が発生し出力不可になった場合,Aggregatorノード上のfluentdが再送上限回数に到達する前に物理メモリを食い潰し詰まってしまいそうだった。

BufferedOuputを継承するクラス(ObjectBufferedOutput やTimeSlicedOutputはこのクラスを継承している)は,出力先に何らかの障害が発生し,転送不可になった場合でも,データをバッファリングすることで極力データをロストしないような仕組みになっており,BufferedOutputクラスは以下のような動作をする。以下,備忘録を兼ねて記載しておく(間違ってたらごめんなさい。v0.10.39より)

  • 出力に失敗し,失敗回数がretry_limitより小さい場合,BufferedOutput#calc_retry_waitで計算される時間後までwaitする。
  • secondaryが設定されていないかつ出力に失敗した場合,失敗回数がretry_limitに達すると,キューに溜まったチャンクは破棄され,失敗履歴もクリアされる。
  • secondaryが設定されているかつ出力に失敗した場合,失敗回数がretry_limitに達すると,即座にretryされ(BefferedOutput#try_flushのbegin…end),next_rety_time後にsecondaryへflushされる。secondaryへの出力にも失敗しsecondary_limitを超えると,キューに溜まったチャンクは破棄され,失敗履歴もクリアされる。
  • キュー内のチャンク数がbuffer_queue_limitに達していて,新たにキューにチャンクを追加しようとするとBufferQueueLimitErrorが投げられ新たなチャンクは拒否される。
  • キュー内のチャンク数がbuffer_queue_limit以下で,”現在のチャンクのサイズ+emitされるデータのサイズ”がbuffer_chunk_limitを超えた場合,新しいチャンクが生成される。
  • リトライに成功した場合で,キュー内に複数のチャンクが蓄積されていた場合は,queued_chunk_flush_intervalの間隔でflushされる。

secondaryの指定は,ドキュメントではforwardout_fileを指定する例が紹介されているけれど,参考リンクでも言及されているように,なんでも指定可能なようである。ただし,secondaryを指定した場合,primaryとクラスが異なるとconfigtestやfluentdの起動時に警告が表示される(Output#secondary_init)。しかし,out_fileではsecondary_initがオーバーライドされており,具体的な処理は定義されていないため警告は表示されない。

僕の場合は,お世話になっているout_fileと互換のfile_alternativeプラグインをsecondaryに設定したが,out_fileのようにsecondary_initがオーバーライドされていないため警告が表示されてしまう(組み込みのOutputプラグインでないため,あえてそのようになっているものだと勝手に推測している。。)。しかし,少し様子を見てみるが,処理自体は正常に動作しているようだった。

この設定では,失敗回数が13回に達し,次のリトライ時間(約2時間強くらい?)になった時に即座にsecondaryへflushされる。

正しく扱えるようになるには,やはり細部を知る必要があると改めて実感。

参考

Impala queries in Hue remain to be "in flight".

この記事は【2014年2月1日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

単純なログ検索しか行なっていないけれど,HueからImpalaクエリを実行して爆速!と喜んでいたのだが,クエリがCMのActivityMonitorではRUNNINGのまま,Impala Query UIでもXX queries in flightのように表示されていつまで経っても終了しない。 

環境は以下。

  • CDH4.4
  • Hue2.5
  • Impala1.2.2
  • Cloudera Manager4.8

impala-shell経由やJDBC経由で実行したクエリについてはCompletedになっているようだが,Hueで実行した場合にこの現象が見られる。どうも,色々調べてみると同現象に類似した内容のレポートがあがっているようで,known issuesらしい。ここでの現象もおそらくこれに該当するかと。hue close impala queryのようなキーワードでひっかかる。

Hueの将来のバージョンにおいては,リソースのcleaningを完全に保証するものではないものの,Hueで実行されたクエリについてcleaningできるようになる?(下記リンクより)

また,Impalaにおいてはアイドル状態のクエリ,セッションを強制的にcloseするコマンドラインオプションが追加されている。CMからは,Impaladのコマンドライン引数安全バルブで指定できる。しかし,これらを設定してもこの問題については試した限りでは上手くいかなかった。Hueからの実行については,キャンセルするしかないか。。

参考

Impalaのmetadataの更新

この記事は【2014年1月16日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

fluentdでHDFSへ書き込んだログをImpalaですぐに実行したい。

Impala1.2.Xで,Impalad,Catalogd + StateStoreの構成で試験的に稼働させている。CatalogdとStateStoreの役割については,いつも参考にさせていただいているKernel023さんの参考リンクに詳しく説明されている。Catalogdサービスを動かしていればImpala経由で実行したDDLによる変更は,クラスタ内の他のImpaladにも反映されるようだ。なお,HueのImpala Query UIから『METASTOREカタログの更新』を実行するとInvalid method name: 'ResetCatalog' (code THRIFTAPPLICATION): Noneとエラーになる。クエリでinvalidate metadataと実行することは問題ない。 

現在,fluendからHDFSへ書き込んだ時間単位のログ(flush_intervalは数分置き)は,EXTERNAL TABLEでHiveで読めるようにしている。また,時間単位のログはDailyでHiveのDBディレクトリ直下に圧縮して保存している。いずれも,Hive経由で処理しているので,時間単位とDailyでの更新をImpalaへ別途通知する必要がある。 

Impalaに更新を通知するのにどうすればよいものかと思っていたが,結局以下のようにして現状対応することとした。

  • 時間単位のログについては,定期に1時間単位などでrefresh <table>を実行。invalidate metadataだと時間がかかるので,テーブル指定で変更のあるテーブルのみに適用する。
  • 最新の時間単位のログをImpalaクエリで処理する場合は,実行するクエリにrefresh <table>を加える。
  • Dailyでログを圧縮した際には,invalidate metadataを実行。

とりあえずはこれでしばらく様子を見てみる。

メインの開発環境がJavaなので,いつもの慣れたAPIでJDBC経由でクエリを実行したいと思っていたところ,Impalaの実行にはimpala-shell,ODBC,JDBC,Beeswax(Thrift),Impala Query UIのインターフェースがあるようだった。JDBC経由での実行については,以下にサンプルを公開してくれている方がいるので参考にさせていただいた。

https://github.com/onefoursix/Cloudera-Impala-JDBC-Example

参考

プログラミング Hive

プログラミング Hive

  • 作者: Edward Capriolo,Dean Wampler,Jason Rutherglen,佐藤直生,嶋内翔,Sky株式会社玉川竜司
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2013/06/15
  • メディア: 大型本
  • この商品を含むブログ (3件) を見る

Hue/Hiveにてデフォルトでクラスパスに追加されるjarを設定する

この記事は【2014年1月8日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

Cloudera Managerを使ってHueをインストールして,SerDeありのテーブルを作成した際にMetastore Managerの画面でテーブルのサンプルを閲覧するとExceptionになってしまう。

Hive CLIでテーブルを作成し,HueのMetastore Managerのテーブルのサンプルタブを押すとおそらくサンプルを取得するクエリが投げられると思うのだけど,SerDe有りのテーブルの場合,add jarできないのでエラーになってしまう。ちなみに,Beeswax(Hive UI)上でadd jarしてクエリを投げるとサンプルも正常に閲覧できる。セッションが残っている間は有効なのだろうか。

ということで,Beeswaxでデフォルトでjarをクラスパスに設定できないかと。jarの指定方法には,hive-conf/hive-site.xmlhive.aux.jars.pathと環境変数HIVE_AUX_JARS_PATHがあるが,参考リンクを見ると,

Beeswax: there is a workaround with the HIVE_AUX_JARS_PATH : https://issues.cloudera.org/browse/HUE-1127

HiveServer2 supports a hive.aux.jars.path property in the hive-site.xml. HiveServer2 does not support a .hiverc and Hue is looking at providing an equivalent at some point: https://issues.cloudera.org/browse/HUE-1066

by http://stackoverflow.com/questions/19135869/best-place-for-json-serde-jar-in-cdh-hadoop-for-use-with-hive-hue-mapreduce

と書かれており,Beeswaxではhive-env.sh方式と同様にHIVE_AUX_JARS_PATHを使って,HiveServer2はhive.aux.jars.pathを使って指定できるみたいだった。けれど,Cloudera ManagerのBeeswaxで安全バルブを探してみたけど見つからない。。そこで,hive-site.xmlの安全バルブに試しに以下のように指定してみたところ上手くいった。どうやらBeeswaxサービス起動時にここをみているようだ。

パスの指定は,ローカルファイルシステムでディレクトリでなくjarの絶対パスの指定で上手くいった。HDFS上のパスやローカルファイルシステム上のディレクトリを指定してみたが動作しなかった。これで,サンプルのタブを開いても結果が正常に表示されるようになった。

ちなみに,環境は以下。

  • CM4.8
  • CDH4.4
  • Hue2.5

参考

DataNodeで大量のINFOレベルメッセージが・・・

この記事は【2013年12月15日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

パッケージでインストールしていたCDH4.4から,新たにCloudera Manager Standard(以下CM)管理のクラスタ(CDH4.5)に切り替え,以前同様fluentdのwebhdfsプラグインからHDFSヘログをappendしたところ,予期せぬ現象が・・・。以前も出ていたのだろうか。。

WebHDFSの有効化

CDH4.5でwebhdfsを利用可能にするため,以下のように設定した。dfs.support.appendについては,デフォルトでtrueとなっているようだった。CM経由では,hdfsサービス > サービス全体 > WebHDFS の有効化にチェックがついていることを確認する。CMの場合,実際の設定ファイルを確認するには,/var/run/cloudera-scm-agent/process下のxxx-hdfs-(NAME|DATA)NODE/hdfs-site.xmlで確認できる。

その後,fluentdのwebhdfsプラグインを使ってWebHDFS API経由でHDFSへappendしたが,以下のようなINFOレベルのログが大量に出力されてしまう事態に遭遇。初めは,許容範囲かと思う程度だったけれど,段々と高頻度でメッセージが出力され,最終的にはtailでコンソールがログで埋め尽くされたしまう状態だった。INFOなので基本的には関与せずで問題ないかと思っていたが,ここまでくるとさすがに目をつぶってはいられない。しかも同じブロックIDっぽい。終了条件が満足されず無限ループから脱することができなくなっているように見える。

HDFSサービスを再起動すると,

のようなメッセージがつらつらと出力される。念のためブロック状態を確認するためhdfs fsckを実行したところHEALTHYと表示され,不良ブロックらしきも報告されない。それから,ファイルのappend自体は成功しているように見える。

なんとくWebHDFS経由でのファイルappendに関連していると思われるので,fluentd側を1 collector,1 webhdfsで設定しHDFSへの書き込みの状況を観察する。

まず,appendをすべてcreateのみにしてみる。fluentdのwebhdfsプラグインの設定で,append noにしてみたところ,Verification failed for xxxxのようなメッセージは確認されなかった(テスト条件にもよると思うので一概には言えないかもしれないが)ので,appendに起因すると推測する。append noなので,毎回新しいファイルが作成される。ここでは,chunk_idごとに一意なファイルとなる。

次に,単一のcollectorからのappendでのHDFSへの書き込みを行ない様子を見る。flush_intervalを20sで設定してみたところ,上記ほどのレベルでないが同メッセージの出力が確認されることがある。flush_intervalを短くするとその頻度は高くなるようだった。

CDH4.4でも同様だったかダウングレードして同様な条件で試してみたところ,少なくともINFOレベルでの上記のようなメッセージが見られなかったので,CDH4.5へのアップグレードによるものか?ソースを見てみたが,さすがに簡単に特定はできなさそうだ。。

結局,今回はCDH4.4にダウングレードして様子を見ることとしたが,メッセージが出力されないだけで根本的な解決には至っていない気がするが。。

参考

Cloudera Manager + fluentd webhdfsのイベントで報告されるFileNotFoundExceptionを除外する

この記事は【2013年12月14日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

Cloudera Manager Standard(以下CM)で環境構築中。 

CMでは,CMの管理画面上で各種サービスの設定を管理できるようになっているが,主要な設定以外の任意の設定を追加したい場合,安全バルブというフックを利用することで可能となっている。fluentd + webhdfsでHDFSへファイルを書き込む場合,2回のHTTPリクエストが発生する。1回目のHTTPリクエストでは,新規ファイル作成の場合は以下のようなFileNotFoundExceptionが表示されるが,これは仕様どおりで実質無害なExceptionなので除外したい。

初め,NameNodeの安全バルブでappenderのRFAにorg.apache.log4j.varia.StringMatchFilterの設定を加えたが,変わらずCM管理画面上のイベントには,FileNotFoundExceptionが報告されてしまう。ということで,どうもEventServerは上記とは別にログイベントを受け取っているようだ。EventServer,NameNodeのlog4j.propertiesを見ると,以下のような定義が見られる。

ということで,RFAとは別にログイベントを転送しているであろうこのappenderにfilter設定を追加すれば上手くいきそうである。properties形式で以下のように安全バルブに設定を加える。

これで今のところイベントにあがってきていないので上手くいったようだ。NameNodeのログもフィルタリングする場合は,RFAにも設定を加える。

参考

WordPress XMLRPC投稿でカテゴリー作成

この記事は【2013年2月11日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

WordPressでXMLRPC投稿時にカテゴリーを自動で設定したいという相談がありちょっと調べてみた。

WordPressでカテゴリー作成するには,通常管理画面から行なうことになるが,php内からももちろん作成が可能である。以下のAPIがwp-includes/taxonomy.phpに用意されているので,これを使用すればよいだろう。

なお,admin内であれば以下のショートカットAPIを使うとよりシンプルかと思われる。このAPIは,wp-admin/includes/taxonomy.phpで定義されている。

でここから,階層構造をもつカテゴリーを一度に複数指定したい場合。

これには,ちょっとはまってしまった。まず,カテゴリー作成が行なわれた場合,term関連のテーブルが更新され,clear_term_cache関数により各種wpキャッシュが削除され,さらにcategory_childrenという子カテゴリーのリストを保存するデータがwp_optionsテーブルから削除される。しかし,clear_term_cache関数では,static指定でtaxonomy(ここでは,category)のキャッシュをクリアしたどうかのフラグが管理されており,category_childrenの削除は最初の一度しか有効にならない。よって,階層構造をもつカテゴリーを一度に複数作成した場合,最初に作成した時のみcategory_childrenが削除され,残りの作成したカテゴリーに適用されない。category_childrenオプションは,管理画面のカテゴリー画面で使用されている値のため,結局表示されるカテゴリーリストとテーブルデータとの間に差異が生じ,カテゴリー階層が正しく表示されないことになる。

結局,以下のようにキャッシュを強制的に削除することで対応した。

このやり方は正攻法でないかもしれないし,そもそも一度に階層構造をもつカテゴリー指定を行なうこと自体が推奨されないのかもしれない。

 

プログラミングや日常の記録など