Y-Ken Studio
新しもの好きのデータエンジニアが四方山話をお届けします。
2016-09-08T18:16:06+09:00
yoshi-ken
Hatena::Blog
hatenablog://blog/12704591929886561864
みんなのGO言語、いよいよ発売です(書評)
hatenablog://entry/10328749687183250281
2016-09-08T18:16:06+09:00
2016-09-08T18:16:06+09:00 GO言語いいですよね。学習しやすくパフォーマンスも良く、メモリ管理が楽で、さらにワンバイナリも作れると。 コマンドラインツールなどもGo言語でさくっと書けば、ワンバイナリで非常に便利な物ができあがります。 今回「みんなのGO言語」をsuzuken (@suzu_v) | Twitterさんよりご恵贈いただきましたので、早速紹介を行いたいと思います。 気になる目次も紹介します。これだけの情報が144ページに収まっているので、通勤時間中の読み物にもぴったりです。 第1章Goによるチーム開発のはじめ方とコードを書く上での心得(松木雅幸) 第2章マルチプラットフォームで動作する社内ツールのつくり方Wi…
<p>GO言語いいですよね。学習しやすくパフォーマンスも良く、メモリ管理が楽で、さらにワン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%A4">バイ</a>ナリも作れると。
<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%DE%A5%F3%A5%C9%A5%E9%A5%A4%A5%F3">コマンドライン</a>ツールなどもGo言語でさくっと書けば、ワン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%A4">バイ</a>ナリで非常に便利な物ができあがります。</p>
<p>今回「<a href="http://amzn.to/2cEQK35">みんなのGO言語</a>」を<a href="https://twitter.com/suzu_v">suzuken (@suzu_v) | Twitter</a>さんよりご恵贈いただきましたので、早速紹介を行いたいと思います。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20160908/20160908165601.jpg" alt="f:id:yoshi-ken:20160908165601j:plain" title="f:id:yoshi-ken:20160908165601j:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>気になる目次も紹介します。これだけの情報が144ページに収まっているので、通勤時間中の読み物にもぴったりです。</p>
<ul>
<li>第1章Goによるチーム開発のはじめ方とコードを書く上での心得(松木雅幸)</li>
<li>第2章<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%EB%A5%C1%A5%D7%A5%E9%A5%C3%A5%C8%A5%D5%A5%A9%A1%BC%A5%E0">マルチプラットフォーム</a>で動作する社内ツールのつくり方<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>(mattn)</li>
<li>第3章実用的なアプリケーションを作るために(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C6%A3%B8%B6%BD%D3%B0%EC">藤原俊一</a>郎)</li>
<li>第4章<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%DE%A5%F3%A5%C9%A5%E9%A5%A4%A5%F3">コマンドライン</a>ツールを作る(中島大一)</li>
<li>第5章The Dark Arts Of Reflection(牧 大輔)</li>
<li>第6章Goのテストに関するツールセット(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CE%EB%CC%DA%B7%F2%C2%C0">鈴木健太</a>)</li>
</ul>
<p>この本は、こんな方にもお勧めだと思います!</p>
<ul>
<li>個人利用からチームで利用し始める際に、設計スタイルなどのベストプラクティスが学びたい</li>
<li>GO言語を使ってイメージを形にする際の作法を学びたい</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20160908/20160908165935.jpg" alt="f:id:yoshi-ken:20160908165935j:plain" title="f:id:yoshi-ken:20160908165935j:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>特に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%DE%A5%F3%A5%C9%A5%E9%A5%A4%A5%F3">コマンドライン</a>ツールの章はいま自分が欲しかった情報だったのでとても嬉しかったです。<br />
そして、6章では個人開発では抜けがちなテスト周りの記述も手厚くある、とても参考になりました。</p>
<p>著者の皆様ならびに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a>様、ありがとうございました。</p>
<p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477418392X/y_ken_studio-22/"><img src="http://ecx.images-amazon.com/images/I/61EL3Dc95dL._SL160_.jpg" class="hatena-asin-detail-image" alt="みんなのGo言語【現場で使える実践テクニック】" title="みんなのGo言語【現場で使える実践テクニック】"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477418392X/y_ken_studio-22/">みんなのGo言語【現場で使える実践テクニック】</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> 松木雅幸,mattn,<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C6%A3%B8%B6%BD%D3%B0%EC">藤原俊一</a>郎,中島大一,牧大輔,<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CE%EB%CC%DA%B7%F2%C2%C0">鈴木健太</a>,稲葉貴洋</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2016/09/09</li><li><span class="hatena-asin-detail-label">メディア:</span> 大型本</li><li><a href="http://d.hatena.ne.jp/asin/477418392X/y_ken_studio-22" target="_blank">この商品を含むブログ (1件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p>
yoshi-ken
Appraisalを用いた、Fluentdプラグインの後方互換性を保てるテスト方法 #Fluentd
hatenablog://entry/6653586347154784961
2016-01-27T18:00:00+09:00
2016-01-27T20:18:52+09:00 2015年にはFluentd v0.12系が主流となってきましたが、まだ古いv0.10系を利用している環境も残っていると思います。 プラグイン開発する上では、Fluentdの後方互換性が保てているかのテストもTravis-CIで行いたいですよね。 その時にどのように行うのか、メモを残しておきたいと思います。 また、どのようにAppraisalsを使い、手元でバージョンを使い分けたテストが実行できるかも紹介します。
<p>2015年にはFluentd v0.12系が主流となってきましたが、まだ古いv0.10系を利用している環境も残っていると思います。<br />
<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>開発する上では、Fluentdの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%E5%CA%FD%B8%DF%B4%B9">後方互換</a>性が保てているかのテストも<a class="keyword" href="http://d.hatena.ne.jp/keyword/Travis">Travis</a>-CIで行いたいですよね。</p>
<p>その時にどのように行うのか、メモを残しておきたいと思います。<br />
また、どのようにAppraisalsを使い、手元でバージョンを使い分けたテストが実行できるかも紹介します。</p>
<h2>マイナーバージョン違いのFluentd毎にテストを実行する</h2>
<p>td-agent1系とtd-agent2系で採用されているそれぞれのFluentdバージョンでテストを実行します。<br /></p>
<p>次のように編集することで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%A3%BF%F4">複数</a>のバージョンそれぞれでテストが実行できるようになります。</p>
<p>cf. <a href="https://github.com/y-ken/fluent-plugin-twitter/pull/22/files">https://github.com/y-ken/fluent-plugin-twitter/pull/22/files</a></p>
<pre class="code lang-diff" data-lang="diff" data-unlink><span class="synType">diff --git a/.travis.yml b/.travis.yml</span>
index 43ef400..9d916eb 100644
<span class="synType">--- a/.travis.yml</span>
<span class="synType">+++ b/.travis.yml</span>
<span class="synStatement">@@ -9,3 +10,9 @@</span><span class="synPreProc"> rvm:</span>
before_install:
- gem update bundler
<span class="synIdentifier">+</span>
<span class="synIdentifier">+gemfile:</span>
<span class="synIdentifier">+ - Gemfile</span>
<span class="synIdentifier">+ - gemfiles/fluentd_v0.10.gemfile</span>
<span class="synIdentifier">+ - gemfiles/fluentd_v0.12.gemfile</span>
<span class="synIdentifier">+</span>
<span class="synType">diff --git a/Appraisals b/Appraisals</span>
new file mode 100644
index 0000000..ec90e47
<span class="synType">--- /dev/null</span>
<span class="synType">+++ b/Appraisals</span>
<span class="synStatement">@@ -0,0 +1,8 @@</span>
<span class="synIdentifier">+appraise "fluentd v0.10" do</span>
<span class="synIdentifier">+ gem "fluentd", "~> 0.10.46"</span>
<span class="synIdentifier">+end</span>
<span class="synIdentifier">+</span>
<span class="synIdentifier">+appraise "fluentd v0.12" do</span>
<span class="synIdentifier">+ gem "fluentd", "~> 0.12.0"</span>
<span class="synIdentifier">+end</span>
<span class="synIdentifier">+</span>
<span class="synType">diff --git a/fluent-plugin-twitter.gemspec b/fluent-plugin-twitter.gemspec</span>
index 59cbf45..747d2b8 100644
<span class="synType">--- a/fluent-plugin-twitter.gemspec</span>
<span class="synType">+++ b/fluent-plugin-twitter.gemspec</span>
<span class="synStatement">@@ -17,6 +17,7 @@</span><span class="synPreProc"> Gem::Specification.new do |s|</span>
s.add_development_dependency "rake"
s.add_development_dependency "test-unit", ">= 3.1.0"
<span class="synIdentifier">+ s.add_development_dependency "appraisal"</span>
s.add_runtime_dependency "fluentd", ">= 0.10.46"
s.add_runtime_dependency "twitter", ">= 5.0.0"
s.add_runtime_dependency "tweetstream", ">= 2.6.1"
<span class="synType">diff --git a/gemfiles/fluentd_v0.10.gemfile b/gemfiles/fluentd_v0.10.gemfile</span>
new file mode 100644
index 0000000..5ababf3
<span class="synType">--- /dev/null</span>
<span class="synType">+++ b/gemfiles/fluentd_v0.10.gemfile</span>
<span class="synStatement">@@ -0,0 +1,7 @@</span>
<span class="synIdentifier">+# This file was generated by Appraisal</span>
<span class="synIdentifier">+</span>
<span class="synIdentifier">+source "http://rubygems.org"</span>
<span class="synIdentifier">+</span>
<span class="synIdentifier">+gem "fluentd", "~> 0.10.46"</span>
<span class="synIdentifier">+</span>
<span class="synIdentifier">+gemspec :path => "../"</span>
<span class="synType">diff --git a/gemfiles/fluentd_v0.12.gemfile b/gemfiles/fluentd_v0.12.gemfile</span>
new file mode 100644
index 0000000..058b6cf
<span class="synType">--- /dev/null</span>
<span class="synType">+++ b/gemfiles/fluentd_v0.12.gemfile</span>
<span class="synStatement">@@ -0,0 +1,7 @@</span>
<span class="synIdentifier">+# This file was generated by Appraisal</span>
<span class="synIdentifier">+</span>
<span class="synIdentifier">+source "http://rubygems.org"</span>
<span class="synIdentifier">+</span>
<span class="synIdentifier">+gem "fluentd", "~> 0.12.0"</span>
<span class="synIdentifier">+</span>
<span class="synIdentifier">+gemspec :path => "../"</span>
</pre>
<h2>Fluentd v0.10.x ではFilterのテストを除外する</h2>
<p>Fluentd v0.10系ではFilterをサポートしておりません。<br />
このため、<code>uninitialized constant Fluent::Filter</code>エラーが発生しないよう、後述するテストの除外指定が必要です。</p>
<pre class="code" data-lang="" data-unlink>$ bundle exec rake
/home/travis/.rvm/rubies/ruby-2.3.0/bin/ruby -I"lib:lib:test" -I"/home/travis/.rvm/gems/ruby-2.3.0/gems/rake-10.5.0/lib" "/home/travis/.rvm/gems/ruby-2.3.0/gems/rake-10.5.0/lib/rake/rake_test_loader.rb" "test/**/test_*.rb"
/home/travis/build/y-ken/fluent-plugin-anonymizer/lib/fluent/plugin/
filter_anonymizer.rb:2:in `<module:Fluent>': uninitialized constant Fluent::Filter (NameError)</pre>
<p>テストを除外する実装例としては次の通りです。</p>
<p>cf. <a href="https://github.com/y-ken/fluent-plugin-anonymizer/commit/b48c3827c225a713ef0ec9b9e5112ded2a5e3f5b">Omit test when `Fluent::Filter` is not defined · y-ken/fluent-plugin-anonymizer@b48c382 · GitHub</a></p>
<pre class="code lang-diff" data-lang="diff" data-unlink><span class="synType">diff --git a/test/helper.rb b/test/helper.rb</span>
index 9f0ce2a..ae21d27 100755
<span class="synType">--- a/test/helper.rb</span>
<span class="synType">+++ b/test/helper.rb</span>
<span class="synStatement">@@ -23,7 +23,10 @@</span><span class="synPreProc"> def method_missing(method, *args)</span>
end
require 'fluent/plugin/out_anonymizer'
<span class="synSpecial">-require 'fluent/plugin/filter_anonymizer'</span>
<span class="synIdentifier">+if Fluent.const_defined?(:Filter)</span>
<span class="synIdentifier">+ require 'fluent/plugin/filter_anonymizer'</span>
<span class="synIdentifier">+end</span>
<span class="synIdentifier">+</span>
class Test::Unit::TestCase
end
<span class="synType">diff --git a/test/plugin/test_filter_anonymizer.rb b/test/plugin/test_filter_anonymizer.rb</span>
index 2813b4a..df1e33a 100644
<span class="synType">--- a/test/plugin/test_filter_anonymizer.rb</span>
<span class="synType">+++ b/test/plugin/test_filter_anonymizer.rb</span>
<span class="synStatement">@@ -2,6 +2,7 @@</span>
class AnonymizerFilterTest < Test::Unit::TestCase
def setup
<span class="synIdentifier">+ omit_unless(Fluent.const_defined?(:Filter))</span>
Fluent::Test.setup
@time = Fluent::Engine.now
end
</pre>
<h2>テストの実行</h2>
<p>依存関係を解決するため、<code>appraisal install</code>を実行します。<br />
ここではbundler経由でappraisalを入れているため、次のような実行結果となります。</p>
<p>cf. <a href="https://github.com/thoughtbot/appraisal#usage">https://github.com/thoughtbot/appraisal#usage</a></p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ bundle <span class="synStatement">exec</span> appraisal <span class="synStatement">install</span>
Warning: Your gemfiles directive <span class="synError">in</span> .travis.yml is incorrect. Run <span class="synSpecial">`appraisal generate --travis`</span> to get the correct configuration.
<span class="synStatement">>></span> bundle check <span class="synSpecial">--gemfile=</span><span class="synStatement">'</span><span class="synConstant">/***/fluent-plugin-twitter/gemfiles/fluentd_v0.10.gemfile</span><span class="synStatement">'</span> || bundle <span class="synStatement">install</span> <span class="synSpecial">--gemfile=</span><span class="synStatement">'</span><span class="synConstant">/***/fluent-plugin-twitter/gemfiles/fluentd_v0.10.gemfile</span><span class="synStatement">'</span>
Resolving dependencies...
The Gemfile<span class="synStatement">'</span><span class="synConstant">s dependencies are satisfied</span>
<span class="synConstant">>> bundle check --gemfile=</span><span class="synStatement">'</span>/***/fluent-plugin-twitter/gemfiles/fluentd_v0.12.gemfile<span class="synStatement">'</span><span class="synConstant"> || bundle install --gemfile=</span><span class="synStatement">'</span>/***/fluent-plugin-twitter/gemfiles/fluentd_v0.12.gemfile<span class="synStatement">'</span>
<span class="synConstant">Resolving dependencies...</span>
<span class="synConstant">The Gemfile</span><span class="synStatement">'</span>s dependencies are satisfied
</pre>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%A3%BF%F4">複数</a>バージョンでテストするため、<code>appraisal rake test</code>コマンドを実行します。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ bundle <span class="synStatement">exec</span> appraisal rake <span class="synStatement">test</span>
<span class="synStatement">>></span> <span class="synIdentifier">BUNDLE_GEMFILE</span>=/***/fluent-plugin-twitter/gemfiles/fluentd_v0.10.gemfile bundle <span class="synStatement">exec</span> rake <span class="synStatement">test</span>
/Users/***/.rbenv/versions/2.2.0/bin/ruby <span class="synSpecial">-I</span><span class="synStatement">"</span><span class="synConstant">lib:lib:test</span><span class="synStatement">"</span> <span class="synSpecial">-I</span><span class="synStatement">"</span><span class="synConstant">/***/fluent-plugin-twitter/vendor/bundle/ruby/2.2.0/gems/rake-10.5.0/lib</span><span class="synStatement">"</span> <span class="synStatement">"</span><span class="synConstant">/***/fluent-plugin-twitter/vendor/bundle/ruby/2.2.0/gems/rake-10.5.0/lib/rake/rake_test_loader.rb</span><span class="synStatement">"</span> <span class="synStatement">"</span><span class="synConstant">test/**/test_*.rb</span><span class="synStatement">"</span>
Loaded suite /***/fluent-plugin-twitter/vendor/bundle/ruby/2.2.0/gems/rake-10.5.0/lib/rake/rake_test_loader
Started
...
Finished <span class="synError">in</span> 0.650067 seconds.
---------------------------------------------------------------------------------------------------------------------------------------
<span class="synConstant">3</span> tests, <span class="synConstant">15</span> assertions, <span class="synConstant">0</span> failures, <span class="synConstant">0</span> errors, <span class="synConstant">0</span> pendings, <span class="synConstant">0</span> omissions, <span class="synConstant">0</span> notifications
<span class="synConstant">100</span>% passed
---------------------------------------------------------------------------------------------------------------------------------------
4.61 tests/s, 23.07 assertions/s
<span class="synStatement">>></span> <span class="synIdentifier">BUNDLE_GEMFILE</span>=/***/fluent-plugin-twitter/gemfiles/fluentd_v0.12.gemfile bundle <span class="synStatement">exec</span> rake <span class="synStatement">test</span>
/Users/***/.rbenv/versions/2.2.0/bin/ruby <span class="synSpecial">-I</span><span class="synStatement">"</span><span class="synConstant">lib:lib:test</span><span class="synStatement">"</span> <span class="synSpecial">-I</span><span class="synStatement">"</span><span class="synConstant">/***/fluent-plugin-twitter/vendor/bundle/ruby/2.2.0/gems/rake-10.5.0/lib</span><span class="synStatement">"</span> <span class="synStatement">"</span><span class="synConstant">/***/fluent-plugin-twitter/vendor/bundle/ruby/2.2.0/gems/rake-10.5.0/lib/rake/rake_test_loader.rb</span><span class="synStatement">"</span> <span class="synStatement">"</span><span class="synConstant">test/**/test_*.rb</span><span class="synStatement">"</span>
Loaded suite /***/fluent-plugin-twitter/vendor/bundle/ruby/2.2.0/gems/rake-10.5.0/lib/rake/rake_test_loader
Started
...
Finished <span class="synError">in</span> 0.172614 seconds.
---------------------------------------------------------------------------------------------------------------------------------------
<span class="synConstant">3</span> tests, <span class="synConstant">15</span> assertions, <span class="synConstant">0</span> failures, <span class="synConstant">0</span> errors, <span class="synConstant">0</span> pendings, <span class="synConstant">0</span> omissions, <span class="synConstant">0</span> notifications
<span class="synConstant">100</span>% passed
---------------------------------------------------------------------------------------------------------------------------------------
17.38 tests/s, 86.90 assertions/s
</pre>
<p>それぞれのFluentdバージョンを用いたテストもクリアした事が確認できました。</p>
yoshi-ken
Travis-CIでapt-get installに失敗する時の対処法
hatenablog://entry/6653586347154606648
2016-01-26T12:07:00+09:00
2016-01-26T12:13:09+09:00 最近はTravisCIでの不可解なエラーのためgem update bundlerを追記する対応が必要になり話題となりましたね。 なんと今度は、今まで動いていたapt-get installが、次のメッセージで失敗するようになりました。 E: Unable to locate package libgeoip-dev さて、困りました。 早速対処法を探ります。
<p>最近はTravisCIでの不可解なエラーのため<code>gem update bundler</code>を追記する対応が必要になり話題となりましたね。<br />
なんと今度は、今まで動いていたapt-get installが、次のメッセージで失敗するようになりました。</p>
<p><code>E: Unable to locate package libgeoip-dev</code></p>
<p>さて、困りました。<br />
早速対処法を探ります。</p>
<h3>解決方法</h3>
<p>結論としては、.<a class="keyword" href="http://d.hatena.ne.jp/keyword/travis">travis</a>.ymlの<code>before_install</code>のセクションで、<br />
<code>sudo apt-get update</code>と記述して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>ファイルの更新を行うとエラーが解消します。<br /></p>
<h3>エラー内容</h3>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>ファイルの読み込みは成功しているが、そこに<code>libgeoip-dev</code>が存在しないようです。</p>
<pre class="code" data-lang="" data-unlink>$ sudo apt-get install libgeoip-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package libgeoip-dev
The command "sudo apt-get install libgeoip-dev" failed and exited with 100 during .
Your build has been stopped.</pre>
<p>全文はこちらです。
<a href="https://travis-ci.org/y-ken/fluent-plugin-geoip/jobs/104577451">https://travis-ci.org/y-ken/fluent-plugin-geoip/jobs/104577451</a></p>
<h3>調査事項</h3>
<ul>
<li>libgeoip-devのパッケージが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>から消えたのか?</li>
</ul>
<p>次の通り消えていません。
<a href="https://packages.debian.org/search?keywords=libgeoip-dev">https://packages.debian.org/search?keywords=libgeoip-dev</a></p>
<ul>
<li>公式ドキュメントを探ると?</li>
</ul>
<p>なんと、記載がありました。<br />
古いパッケージ情報により、たびたび起こるそうです。</p>
<pre class="code" data-lang="" data-unlink>This is often caused by old package database and can be fixed by adding the following to .travis.yml:
before_install:
- sudo apt-get update</pre>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%B2%BE%C8%B8%B5">参照元</a>: <a href="https://docs.travis-ci.com/user/common-build-problems/#Linux%3A-apt-fails-to-install-package-with-404-error">https://docs.travis-ci.com/user/common-build-problems/#Linux%3A-apt-fails-to-install-package-with-404-error</a></p>
<h3>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/travis">travis</a>.yml を更新します</h3>
<p>ドキュメントに従い、<code>sudo apt-get update</code>を追記します。<br />
今回は同時に、<code>NoMethodError: undefined method 'spec' for nil:NilClass</code>を解消するためのgem updateも追加しました。
エラー全文: <a href="https://travis-ci.org/y-ken/fluent-plugin-geoip/jobs/104785639">https://travis-ci.org/y-ken/fluent-plugin-geoip/jobs/104785639</a></p>
<p>変更前</p>
<pre class="code" data-lang="" data-unlink>before_install:
- sudo apt-get install libgeoip-dev</pre>
<p>変更後</p>
<pre class="code" data-lang="" data-unlink>before_install:
- sudo apt-get update
- sudo apt-get install libgeoip-dev
- gem update bundler</pre>
<p>これにて次のPullRequestの通り、エラーは解消です。<br />
めでたしめでたし。</p>
<p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fy-ken%2Ffluent-plugin-geoip%2Fpull%2F29" title="Failed travis-ci by y-ken · Pull Request #29 · y-ken/fluent-plugin-geoip" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/y-ken/fluent-plugin-geoip/pull/29">github.com</a></cite></p>
yoshi-ken
Fluentdのレコードにホスト名を付与する最良の方法
hatenablog://entry/6653458415124007450
2015-10-14T12:10:00+09:00
2015-10-14T15:24:08+09:00 Fluentdでログを集める時にそのサーバのホスト名(hostname)をレコードに追加したい。 そういう時に便利な設定サンプルを紹介します。 ユースケース tailプラグインで収集したApacheのエラーログに、ホスト情報を付与する その他、ございましたら教えてください
<p>Fluentdでログを集める時にそのサーバのホスト名(hostname)をレコードに追加したい。
そういう時に便利な設定サンプルを紹介します。</p>
<h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B9%A5%B1%A1%BC%A5%B9">ユースケース</a></h2>
<ul>
<li>tail<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>で収集した<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apache">Apache</a>のエラーログに、ホスト情報を付与する</li>
<li><em>その他、ございましたら教えてください</em></li>
</ul>
<h2>Filterを用いた手法(オススメ)</h2>
<p>td-agent2環境(fluentd v0.12以降のバージョン)を利用していれば、Filter<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>が使えます。<br />
手間の掛かるタグ書き換えは必要ありません。<br />
次の方法が標準付属の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>で実現できるため、最もシンプルです。</p>
<pre class="code lang-apache" data-lang="apache" data-unlink><source>
@type forward
</source>
<filter <span class="synConstant">debug</span>.*>
@type record_transformer
<record>
host ${hostname}
</record>
</filter>
<span class="synComment"># @type forwardなど、どこに送りたいか適宜指定する</span>
<match <span class="synConstant">debug</span>.*>
@type stdout
</match>
</pre>
<p>動作サンプル</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ <span class="synStatement">echo</span><span class="synConstant"> </span><span class="synStatement">'</span><span class="synConstant">{"message":"test"}</span><span class="synStatement">'</span><span class="synConstant"> </span>| /opt/td-agent/embedded/bin/fluent-cat debug.test
$ <span class="synStatement">tail</span> <span class="synConstant">-1</span> /var/log/td-agent/td-agent.log
<span class="synConstant">2015-10-09</span> <span class="synConstant">17</span>:<span class="synConstant">03</span>:<span class="synConstant">59</span> <span class="synSpecial">+0900</span> debug.test: <span class="synSpecial">{</span><span class="synStatement">"</span><span class="synConstant">message</span><span class="synStatement">"</span>:<span class="synStatement">"</span><span class="synConstant">test</span><span class="synStatement">"</span>,<span class="synStatement">"</span><span class="synConstant">host</span><span class="synStatement">"</span>:<span class="synStatement">"</span><span class="synConstant">tk2-***-***.vs.sakura.ne.jp</span><span class="synStatement">"</span><span class="synSpecial">}</span>
</pre>
<h2>タグ書き換えを伴う手法</h2>
<p>どのバージョンのFluentdでも利用できます。
但し<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の事前インストールが必要です。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># プラグインのインストール(td-agent1)</span>
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem <span class="synStatement">install</span> fluent-plugin-record-reformer
<span class="synComment"># プラグインのインストール(td-agent2)</span>
$ sudo /usr/sbin/td-agent-gem <span class="synStatement">install</span> fluent-plugin-record-reformer
</pre>
<p>td-agent1環境(fluentd v0.10系のバージョン)向けの設定例</p>
<pre class="code lang-apache" data-lang="apache" data-unlink><match record_reformer.<span class="synConstant">debug</span>.*>
type record_reformer
output_tag stdout.${tag_suffix[1]}
<record>
hostname ${hostname}
</record>
</match>
<span class="synComment"># type forwardなど、どこに送りたいか適宜指定する</span>
<match stdout.<span class="synConstant">debug</span>.*>
type stdout
</match>
</pre>
<p>td-agent2環境(fluentd v0.12以降のバージョン)向けの設定例</p>
<pre class="code lang-apache" data-lang="apache" data-unlink><match record_reformer.<span class="synConstant">debug</span>.*>
@type record_reformer
output_tag stdout.${tag_suffix[1]}
<record>
hostname ${hostname}
</record>
</match>
<span class="synComment"># @type forwardなど、どこに送りたいか適宜指定する</span>
<match stdout.<span class="synConstant">debug</span>.*>
@type stdout
</match>
</pre>
<p>output_tagの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>の書き方については<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>のREADMEが参考になります。<br />
<a href="https://github.com/sonots/fluent-plugin-record-reformer#placeholders">https://github.com/sonots/fluent-plugin-record-reformer#placeholders</a></p>
<h2>forward_with_hostname という<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を使う手法</h2>
<p>どのバージョンのFluentdでも利用できます。<br />
若干トリッキーですが、標準のout_forward<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>をオーバーライドしたものです。<br />
そちらを <code>/etc/td-agent/plugin/out_forward_with_hostname.rb</code> に配置して利用します。</p>
<p>参考: <a href="http://qiita.com/catatsuy/items/6755a796423067a77acd">http://qiita.com/catatsuy/items/6755a796423067a77acd</a></p>
<h2>hostname <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を使う方法</h2>
<p>タグ書き換えがadd_prefixのみですが、こういったものもあるようです。
<a href="http://fukata.org/2013/05/16/release-fluent-plugin-hostname-v0-0-2/">http://fukata.org/2013/05/16/release-fluent-plugin-hostname-v0-0-2/</a></p>
<h2>その他</h2>
<p>tail<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>で取り込む時にタグにホスト名を付与し、そのまま使う方法もあります。
<a href="http://www.fluentd.org/guides/recipes/apache-add-hostname">http://www.fluentd.org/guides/recipes/apache-add-hostname</a></p>
yoshi-ken
Rubyで全角英数字を半角英数字にnkfで変換する時の落とし穴
hatenablog://entry/8454420450096530515
2015-06-05T12:40:32+09:00
2015-10-21T18:25:44+09:00 RubyでUTF-8文字列の全角英数字の表記揺れを統一したいとき、 気をつけないと希に文字化けする事象を見つけたのでメモします。 NKFを用いて全角英数字→半角英数字に変換する方法 ググるとよく出てくる方法は次の通りです。 もちろん、問題なく普通に動きます。
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-8">UTF-8</a>文字列の全角英数字の表記揺れを統一したいとき、
気をつけないと希に文字化けする<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%F6%BE%DD">事象</a>を見つけたのでメモします。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20150605/20150605122403.png" alt="f:id:yoshi-ken:20150605122403p:plain" title="f:id:yoshi-ken:20150605122403p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/NKF">NKF</a>を用いて全角英数字→半角英数字に変換する方法</h2>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%B0%A4%EB">ググる</a>とよく出てくる方法は次の通りです。<br />
もちろん、問題なく普通に動きます。</p>
<pre class="code lang-ruby" data-lang="ruby" data-unlink>$ pry
[<span class="synConstant">1</span>] pry(main)> <span class="synPreProc">require</span> <span class="synSpecial">'</span><span class="synConstant">nkf</span><span class="synSpecial">'</span>
=> <span class="synConstant">true</span>
[<span class="synConstant">2</span>] pry(main)> <span class="synType">NKF</span>.nkf(<span class="synSpecial">'</span><span class="synConstant">-m0Z1 -w</span><span class="synSpecial">'</span>, <span class="synSpecial">"</span><span class="synConstant">Ruby−2.2</span><span class="synSpecial">"</span>)
=> <span class="synSpecial">"</span><span class="synConstant">Ruby-2.2</span><span class="synSpecial">"</span>
</pre>
<p>ここで<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%BC%EF%B0%CD%C2%B8%CA%B8%BB%FA">機種依存文字</a>が混じるとどうなるでしょうか。</p>
<pre class="code lang-ruby" data-lang="ruby" data-unlink>pry(main)> <span class="synType">NKF</span>.nkf(<span class="synSpecial">'</span><span class="synConstant">-m0Z1 -w</span><span class="synSpecial">'</span>, <span class="synSpecial">"</span><span class="synConstant">ルビー Ⅱ</span><span class="synSpecial">"</span>)
=> <span class="synSpecial">"</span><span class="synConstant">ルビー Ⅱ</span><span class="synSpecial">"</span>
pry(main)> <span class="synType">NKF</span>.nkf(<span class="synSpecial">'</span><span class="synConstant">-m0Z1 -w</span><span class="synSpecial">'</span>, <span class="synSpecial">"</span><span class="synConstant">ルⅡ</span><span class="synSpecial">"</span>)
=> <span class="synSpecial">"</span><span class="synConstant">繝ォ竇。</span><span class="synSpecial">"</span>
pry(main)> <span class="synType">NKF</span>.nkf(<span class="synSpecial">'</span><span class="synConstant">-m0Z1 -w</span><span class="synSpecial">'</span>, <span class="synSpecial">"</span><span class="synConstant">Ruby Ⅱ</span><span class="synSpecial">"</span>)
=> <span class="synSpecial">"</span><span class="synConstant">Ruby 竇。</span><span class="synSpecial">"</span>
</pre>
<p>なんと、文字の組み合わせ次第では化けてしまいます。これは気づきにくいですね。<br />
調べると、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%BC%EF%B0%CD%C2%B8%CA%B8%BB%FA">機種依存文字</a>に関するオプションを発見しました。</p>
<blockquote><p>--cp932 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a> の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%BC%EF%B0%CD%C2%B8%CA%B8%BB%FA">機種依存文字</a>(〜−¢£¬|など)を<a class="keyword" href="http://d.hatena.ne.jp/keyword/Unicode">Unicode</a>に変換するときに文字化けしないようにする。<br />
引用元: <a href="http://www003.upp.so-net.ne.jp/NAMBOKU/ruby/ruby0352.html">http://www003.upp.so-net.ne.jp/NAMBOKU/ruby/ruby0352.html</a></p></blockquote>
<p>試しにこの引数を追加すると、期待通りの動作とは・・・なりません!!!<br />
まあ元が<a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-8">UTF-8</a>なのでcp932を指定するのも変だとはうすうす思っておりましたが。</p>
<pre class="code" data-lang="" data-unlink>pry(main)> NKF.nkf('-m0Z1 -w --cp932', "ルビー Ⅱ")
=> "ルビー Ⅱ"
pry(main)> NKF.nkf('-m0Z1 -w --cp932', "ルⅡ")
=> "繝ォ竇。"
pry(main)> NKF.nkf('-m0Z1 -w --cp932', "Ruby Ⅱ")
=> "Ruby 竇。"</pre>
<p>ここで1度、引数のそれぞれの意味を見てみましょう。</p>
<table>
<thead>
<tr>
<th> 引数 </th>
<th> 意味 </th>
</tr>
</thead>
<tbody>
<tr>
<td> -m0 </td>
<td> <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIME">MIME</a>(電子メール用のフォーマット)に変換しない<br />(<a class="keyword" href="http://d.hatena.ne.jp/keyword/nkf">nkf</a>はこのオプションを指定しない限り、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIME">MIME</a>に変換する処理を行う)。 </td>
</tr>
<tr>
<td> -Z1 </td>
<td> 全角スペースを半角スペース1個に変換する。 </td>
</tr>
<tr>
<td> -w </td>
<td> 出力ファイルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9">文字コード</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-8">UTF-8</a>(BOMなし)とする(-W80とおなじ)。 </td>
</tr>
</tbody>
</table>
<p>引用元: <a href="http://www003.upp.so-net.ne.jp/NAMBOKU/ruby/ruby0352.html">http://www003.upp.so-net.ne.jp/NAMBOKU/ruby/ruby0352.html</a></p>
<p>ここで気づくのは、入力<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9">文字コード</a>の指定が行われていないことです。<br />
このため、先ほどのcp932のオプションは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Shift_JIS">Shift_JIS</a>での読み込み時に使うものであったことが分かりました。<br />
そこで、次のように-wと-Wをそれぞれ指定してみましょう。</p>
<table>
<thead>
<tr>
<th> 引数 </th>
<th> 意味 </th>
</tr>
</thead>
<tbody>
<tr>
<td> -m0 </td>
<td> <a class="keyword" href="http://d.hatena.ne.jp/keyword/MIME">MIME</a>(電子メール用のフォーマット)に変換しない<br />(<a class="keyword" href="http://d.hatena.ne.jp/keyword/nkf">nkf</a>はこのオプションを指定しない限り、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIME">MIME</a>に変換する処理を行う)。 </td>
</tr>
<tr>
<td> -Z1 </td>
<td> 全角スペースを半角スペース1個に変換する。 </td>
</tr>
<tr>
<td> -W </td>
<td> 入力ファイルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9">文字コード</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-8">UTF-8</a>(BOMなし)とする(-W80とおなじ)。<strong>※追加※</strong> </td>
</tr>
<tr>
<td> -w </td>
<td> 出力ファイルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9">文字コード</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-8">UTF-8</a>(BOMなし)とする(-W80とおなじ)。 </td>
</tr>
</tbody>
</table>
<pre class="code" data-lang="" data-unlink>pry(main)> NKF.nkf('-m0Z1 -W -w', "ルビー Ⅱ")
=> "ルビー Ⅱ"
pry(main)> NKF.nkf('-m0Z1 -W -w', "ルⅡ")
=> "ルⅡ"
pry(main)> NKF.nkf('-m0Z1 -W -w', "Ruby Ⅱ")
=> "Ruby Ⅱ"</pre>
<p>無事に期待通りの動作となりました。</p>
<h2>まとめ</h2>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/nkf">nkf</a>を利用するときは、入力<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9">文字コード</a>を自動判定ではなくしっかりと指定しましょう!</p>
<table>
<thead>
<tr>
<th> 引数 </th>
<th> 意味 </th>
</tr>
</thead>
<tbody>
<tr>
<td> -S </td>
<td> 入力ファイルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9">文字コード</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/shift_jis">shift_jis</a>とする。 </td>
</tr>
<tr>
<td> -E </td>
<td> 入力ファイルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9">文字コード</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/EUC">EUC</a>-JPとする。 </td>
</tr>
<tr>
<td> -J </td>
<td> 入力ファイルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9">文字コード</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/ISO-2022-JP">ISO-2022-JP</a>(いわゆるjisコード)とする。 </td>
</tr>
<tr>
<td> -W </td>
<td> 入力ファイルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9">文字コード</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-8">UTF-8</a>(BOMなし)とする(-W80とおなじ)。 </td>
</tr>
</tbody>
</table>
<h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%A2%A4%EF%A4%BB%A4%C6%C6%C9%A4%DF%A4%BF%A4%A4">あわせて読みたい</a></h2>
<p>半角英数字に変換し、さらに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%BC%EF%B0%CD%C2%B8%CA%B8%BB%FA">機種依存文字</a>も変換したいケースでは、<br />
<a class="keyword" href="http://d.hatena.ne.jp/keyword/NKF">NKF</a>ではなく次のページで紹介されている<a class="keyword" href="http://d.hatena.ne.jp/keyword/unicode">unicode</a> gemが万能でお勧めです。</p>
<p>文字列の表記揺れを<a class="keyword" href="http://d.hatena.ne.jp/keyword/Unicode">Unicode</a>正規化で簡単に解決する方法<br />
<a href="http://qiita.com/y-ken/items/d08eb7f66c8fb2fa7d21">http://qiita.com/y-ken/items/d08eb7f66c8fb2fa7d21</a></p>
<p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477414164X/y_ken_studio-22/"><img src="http://ecx.images-amazon.com/images/I/51b7R1hZL-L._SL160_.jpg" class="hatena-asin-detail-image" alt="プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)" title="プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477414164X/y_ken_studio-22/">プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> 矢野啓介</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2010/02/18</li><li><span class="hatena-asin-detail-label">メディア:</span> 単行本(ソフトカバー)</li><li><span class="hatena-asin-detail-label">購入</span>: 34人 <span class="hatena-asin-detail-label">クリック</span>: 578回</li><li><a href="http://d.hatena.ne.jp/asin/477414164X/y_ken_studio-22" target="_blank">この商品を含むブログ (130件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p>
yoshi-ken
jqコマンドをsudoを使わずにインストールし、PATHを通す方法
hatenablog://entry/8454420450082625314
2015-02-06T15:01:05+09:00
2015-02-06T15:01:15+09:00 JSONデータをコマンドラインでフィルター出来るjqコマンド、便利ですよね。 割と新しいepelリポジトリであれば、yum -y install jqで使えるようになります。 しかし次のようなケースでは大抵フルパスでバイナリを指定するのではないでしょうか。 root権限はないが、jqコマンドが使いたい PATHの設定を変更する操作は避けたい しかし今回紹介する方法を使うと、とても簡単にPATHが通る状態にできます。
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/JSON">JSON</a>データを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%DE%A5%F3%A5%C9%A5%E9%A5%A4%A5%F3">コマンドライン</a>でフィルター出来るjqコマンド、便利ですよね。
割と新しいepel<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>であれば、<code>yum -y install jq</code>で使えるようになります。
しかし次のようなケースでは大抵フルパスでバイナリを指定するのではないでしょうか。</p>
<ul>
<li>root権限はないが、jqコマンドが使いたい</li>
<li>PATHの設定を変更する操作は避けたい</li>
</ul>
<p>しかし今回紹介する方法を使うと、とても簡単にPATHが通る状態にできます。</p>
<h2>環境</h2>
<ul>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/CentOS">CentOS</a> 6.6 64bit版</li>
</ul>
<h2>インストール方法</h2>
<p>ユーザのホームディレクトリ以下に<code>bin</code>ディレクトリを作り、バイナリを放り込むのみ。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ <span class="synStatement">mkdir</span> ~/bin
$ wget http://stedolan.github.io/jq/download/linux64/jq <span class="synSpecial">-O</span> ~/bin/jq
$ <span class="synStatement">chmod</span> <span class="synSpecial">+x</span> ~/bin/jq
</pre>
<p>jqコマンドの在処を確認すると、この通り認識されています。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ which jq
~/bin/jq
</pre>
<h2>からくり</h2>
<p>CentOS6では、<a class="keyword" href="http://d.hatena.ne.jp/keyword/bash">bash</a>_profile に次の内容が書かれているため、ホーム以下に<code>bin/</code>ディレクトリを作りバイナリを設置すると、自然とパスが通った状態となります。</p>
<p>ユーザ名がadminなら<code>/home/admin/bin/</code>という具合です。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ cat ~/.bash_profile
<span class="synComment"># .bash_profile</span>
<span class="synComment"># Get the aliases and functions</span>
<span class="synStatement">if [</span> <span class="synStatement">-f</span> ~/.bashrc <span class="synStatement">];</span> <span class="synStatement">then</span>
<span class="synStatement"> . </span>~/.bashrc
<span class="synStatement">fi</span>
<span class="synComment"># User specific environment and startup programs</span>
<span class="synIdentifier">PATH</span>=<span class="synPreProc">$PATH</span>:<span class="synPreProc">$HOME</span>/bin
<span class="synStatement">export</span><span class="synIdentifier"> PATH</span>
</pre>
yoshi-ken
データ可視化アプリの新星、PrometheusをCentOSにインストールする方法
hatenablog://entry/8454420450082549611
2015-02-05T19:21:54+09:00
2015-11-21T14:31:23+09:00 SoundCloudが内製しているモニタリングシステム「Prometheus」がいま気になっております。 時系列データベースを用いた柔軟なクエリ言語を用い、ダッシュボードによる可視化やアラート機能もあるそうです。 Prometheus: Go言語で書かれたモニタリングシステム - ワザノバ | wazanova とりあえず使ってみたので、紹介します。
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/SoundCloud">SoundCloud</a>が内製している<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%CB%A5%BF%A5%EA%A5%F3%A5%B0">モニタリング</a>システム「Prometheus」がいま気になっております。<br />
時系列データベースを用いた柔軟なクエリ言語を用い、ダッシュボードによる可視化やアラート機能もあるそうです。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20150205/20150205191805.png" alt="f:id:yoshi-ken:20150205191805p:plain" title="f:id:yoshi-ken:20150205191805p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<ul>
<li><a href="http://wazanova.jp/items/1672">Prometheus: Go言語で書かれたモニタリングシステム - ワザノバ | wazanova</a></li>
</ul>
<p>とりあえず使ってみたので、紹介します。</p>
<h2>環境</h2>
<ul>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/CentOS">CentOS</a> 6</li>
</ul>
<h2>インストール</h2>
<p>このドキュメントに従い、進めていきます。<br />
<a href="http://prometheus.io/docs/introduction/getting_started/">http://prometheus.io/docs/introduction/getting_started/</a></p>
<h3>git clone</h3>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ <span class="synStatement">cd</span> /usr/<span class="synStatement">local</span>/src/
$ sudo git clone https://github.com/prometheus/prometheus.git
Initialized empty Git repository <span class="synError">in</span> /usr/<span class="synStatement">local</span>/src/prometheus/.git/
remote: Counting objects: <span class="synConstant">11061</span>, done.
remote: Compressing objects: <span class="synConstant">100</span>% <span class="synPreProc">(</span><span class="synConstant">7</span><span class="synSpecial">/</span><span class="synConstant">7</span><span class="synPreProc">)</span>, done.
remote: Total <span class="synConstant">11061</span> <span class="synPreProc">(</span><span class="synSpecial">delta </span><span class="synConstant">0</span><span class="synPreProc">)</span>, reused <span class="synConstant">0</span> <span class="synPreProc">(</span><span class="synSpecial">delta </span><span class="synConstant">0</span><span class="synPreProc">)</span>
Receiving objects: <span class="synConstant">100</span>% <span class="synPreProc">(</span><span class="synConstant">11061</span><span class="synSpecial">/</span><span class="synConstant">11061</span><span class="synPreProc">)</span>, 4.73 MiB | <span class="synConstant">989</span> KiB/s, done.
Resolving deltas: <span class="synConstant">100</span>% <span class="synPreProc">(</span><span class="synConstant">5957</span><span class="synSpecial">/</span><span class="synConstant">5957</span><span class="synPreProc">)</span>, done.
$ <span class="synStatement">cd</span> prometheus/
</pre>
<h3>make build</h3>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ make build
curl <span class="synSpecial">-o</span> /usr/<span class="synStatement">local</span>/src/prometheus/.build/cache/go1.4.linux-amd64.tar.gz <span class="synSpecial">-L</span> https://golang.org/dl/go1.4.linux-amd64.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
<span class="synConstant">0</span> <span class="synConstant">85</span> <span class="synConstant">0</span> <span class="synConstant">85</span> <span class="synConstant">0</span> <span class="synConstant">0</span> <span class="synConstant">217</span> <span class="synConstant">0</span> <span class="synSpecial">--:--:--</span> <span class="synSpecial">--:--:--</span> <span class="synSpecial">--:--:--</span> 418Warning: Failed to create the file
Warning: /usr/<span class="synStatement">local</span>/src/prometheus/.build/cache/go1.4.linux-amd64.tar.gz
<span class="synConstant">0</span> 60.3M <span class="synConstant">0</span> <span class="synConstant">735</span> <span class="synConstant">0</span> <span class="synConstant">0</span> <span class="synConstant">871</span> <span class="synConstant">0</span> <span class="synConstant">20</span>:<span class="synConstant">11</span>:<span class="synConstant">03</span> <span class="synSpecial">--:--:--</span> <span class="synConstant">20</span>:<span class="synConstant">11</span>:<span class="synConstant">03</span> <span class="synConstant">871</span>
curl: <span class="synPreProc">(</span><span class="synConstant">23</span><span class="synPreProc">)</span> Failed writing body <span class="synPreProc">(</span><span class="synConstant">0</span><span class="synSpecial"> </span><span class="synStatement">!=</span><span class="synSpecial"> </span><span class="synConstant">735</span><span class="synPreProc">)</span>
make: *** <span class="synStatement">[</span>/usr/local/src/prometheus/.build/cache/go1.4.linux-amd64.tar.gz<span class="synStatement">]</span> Error <span class="synConstant">23</span>
</pre>
<p>sudoを付けて再実行します。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ sudo make build
curl <span class="synSpecial">-o</span> /.build/cache/go1.4.linux-amd64.tar.gz <span class="synSpecial">-L</span> https://golang.org/dl/go1.4.linux-amd64.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
<span class="synConstant">0</span> <span class="synConstant">85</span> <span class="synConstant">0</span> <span class="synConstant">85</span> <span class="synConstant">0</span> <span class="synConstant">0</span> <span class="synConstant">234</span> <span class="synConstant">0</span> <span class="synSpecial">--:--:--</span> <span class="synSpecial">--:--:--</span> <span class="synSpecial">--:--:--</span> 416Warning: Failed to create the file /.build/cache/go1.4.linux-amd64.tar.gz
<span class="synConstant">0</span> 60.3M <span class="synConstant">0</span> <span class="synConstant">735</span> <span class="synConstant">0</span> <span class="synConstant">0</span> <span class="synConstant">835</span> <span class="synConstant">0</span> <span class="synConstant">21</span>:<span class="synConstant">03</span>:<span class="synConstant">16</span> <span class="synSpecial">--:--:--</span> <span class="synConstant">21</span>:<span class="synConstant">03</span>:<span class="synConstant">16</span> <span class="synConstant">835</span>
curl: <span class="synPreProc">(</span><span class="synConstant">23</span><span class="synPreProc">)</span> Failed writing body <span class="synPreProc">(</span><span class="synConstant">0</span><span class="synSpecial"> </span><span class="synStatement">!=</span><span class="synSpecial"> </span><span class="synConstant">735</span><span class="synPreProc">)</span>
make: *** <span class="synStatement">[</span>/.build/cache/go1.4.linux-amd64.tar.gz<span class="synStatement">]</span> Error <span class="synConstant">23</span>
</pre>
<p>おっとこれはsudo経由での実行は意識されていないようです。<br />
shコマンドの引数として実行してみましょう。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ sudo sh <span class="synSpecial">-c</span> <span class="synStatement">"</span><span class="synConstant">make build</span><span class="synStatement">"</span>
curl <span class="synSpecial">-o</span> /usr/<span class="synStatement">local</span>/src/prometheus/.build/cache/go1.4.linux-amd64.tar.gz <span class="synSpecial">-L</span> https://golang.org/dl/go1.4.linux-amd64.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
<span class="synConstant">100</span> 60.3M <span class="synConstant">100</span> 60.3M <span class="synConstant">0</span> <span class="synConstant">0</span> 13.9M <span class="synConstant">0</span> <span class="synConstant">0</span>:<span class="synConstant">00</span>:<span class="synConstant">04</span> <span class="synConstant">0</span>:<span class="synConstant">00</span>:<span class="synConstant">04</span> <span class="synSpecial">--:--:--</span> 21.9M
<span class="synStatement">[</span> <span class="synStatement">-d</span> <span class="synStatement">"</span><span class="synConstant">/usr/local/src/prometheus/.build/root/gopath/src/github.com/prometheus/prometheus</span><span class="synStatement">"</span> <span class="synStatement">]</span> || <span class="synSpecial">{</span> <span class="synStatement">mkdir</span> -vp /usr/<span class="synStatement">local</span>/src/prometheus/.build/root/gopath/src/github.com/prometheus <span class="synStatement">;</span> ln -s <span class="synStatement">"</span><span class="synConstant">/usr/local/src/prometheus</span><span class="synStatement">"</span> <span class="synStatement">"</span><span class="synConstant">/usr/local/src/prometheus/.build/root/gopath/src/github.com/prometheus/prometheus</span><span class="synStatement">"</span> <span class="synStatement">;</span> <span class="synSpecial">}</span>
<span class="synStatement">mkdir</span>: created directory <span class="synSpecial">`/usr/</span><span class="synStatement">local</span><span class="synSpecial">/src/prometheus/.build/root/gopath</span><span class="synStatement">'</span>
<span class="synConstant">mkdir: created directory `/usr/local/src/prometheus/.build/root/gopath/src</span><span class="synStatement">'</span>
<span class="synStatement">mkdir</span><span class="synSpecial">: created directory `</span>/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/gopath/src/github.com<span class="synStatement">'</span>
<span class="synConstant">mkdir: created directory `/usr/local/src/prometheus/.build/root/gopath/src/github.com/prometheus</span><span class="synStatement">'</span>
<span class="synStatement">[</span> <span class="synStatement">-d</span> <span class="synStatement">"</span><span class="synConstant">/usr/local/src/prometheus/.build/root/gopath/src/github.com/prometheus/prometheus</span><span class="synStatement">"</span> <span class="synStatement">]</span>
tar <span class="synSpecial">-C</span> /usr/<span class="synStatement">local</span>/src/prometheus/.build/root <span class="synSpecial">-xzf</span> /usr/<span class="synStatement">local</span>/src/prometheus/.build/cache/go1.4.linux-amd64.tar.gz
<span class="synStatement">touch</span> /usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go/bin/go
<span class="synIdentifier">TMPDIR</span>=/tmp <span class="synIdentifier">GOROOT</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go <span class="synIdentifier">GOPATH</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/gopath /usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go/bin/go get github.com/tools/godep
<span class="synIdentifier">TMPDIR</span>=/tmp <span class="synIdentifier">GOROOT</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go <span class="synIdentifier">GOPATH</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/gopath /usr/<span class="synStatement">local</span>/src/prometheus/.build/root/gopath/bin/godep restore
go: missing Mercurial command. See http://golang.org/s/gogetcmd
package code.google.com/p/goprotobuf/proto: <span class="synStatement">exec</span>: <span class="synStatement">"</span><span class="synConstant">hg</span><span class="synStatement">"</span>: executable file not found <span class="synError">in</span> <span class="synPreProc">$PATH</span>
godep: restore: <span class="synStatement">exit</span> <span class="synStatement">status</span> <span class="synConstant">1</span>
go: missing Mercurial command. See http://golang.org/s/gogetcmd
package github.com/matttproud/golang_protobuf_extensions/ext
imports code.google.com/p/goprotobuf/proto: <span class="synStatement">exec</span>: <span class="synStatement">"</span><span class="synConstant">hg</span><span class="synStatement">"</span>: executable file not found <span class="synError">in</span> <span class="synPreProc">$PATH</span>
godep: restore: <span class="synStatement">exit</span> <span class="synStatement">status</span> <span class="synConstant">1</span>
make: *** <span class="synStatement">[</span>dependencies<span class="synStatement">]</span> Error <span class="synConstant">1</span>
</pre>
<p>hgコマンドが必要とのこと。<a class="keyword" href="http://d.hatena.ne.jp/keyword/mercurial">mercurial</a>をインストールします。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ sudo yum <span class="synSpecial">-y</span> <span class="synStatement">install</span> mercurial
</pre>
<p>次は、エラーを起こさずに実行できました。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ sudo sh <span class="synSpecial">-c</span> <span class="synStatement">"</span><span class="synConstant">make build</span><span class="synStatement">"</span>
<span class="synIdentifier">TMPDIR</span>=/tmp <span class="synIdentifier">GOROOT</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go <span class="synIdentifier">GOPATH</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/gopath /usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go/bin/go get github.com/tools/godep
<span class="synIdentifier">TMPDIR</span>=/tmp <span class="synIdentifier">GOROOT</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go <span class="synIdentifier">GOPATH</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/gopath /usr/<span class="synStatement">local</span>/src/prometheus/.build/root/gopath/bin/godep restore
<span class="synIdentifier">TMPDIR</span>=/tmp <span class="synIdentifier">GOROOT</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go <span class="synIdentifier">GOPATH</span>=/usr/<span class="synStatement">local</span>/src/prometheus/.build/root/gopath /usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go/bin/go get <span class="synSpecial">-d</span>
make <span class="synSpecial">-C</span> config
make<span class="synStatement">[</span><span class="synConstant">1</span><span class="synStatement">]</span>: Entering directory <span class="synSpecial">`/usr/</span><span class="synStatement">local</span><span class="synSpecial">/src/prometheus/config</span><span class="synStatement">'</span>
<span class="synConstant">make[1]: Nothing to be done for `all</span><span class="synStatement">'</span><span class="synSpecial">.</span>
<span class="synSpecial">make[</span><span class="synConstant">1</span><span class="synSpecial">]: Leaving directory `</span>/usr/<span class="synStatement">local</span>/src/prometheus/config<span class="synStatement">'</span>
<span class="synConstant">make -C tools</span>
<span class="synConstant">make[1]: Entering directory `/usr/local/src/prometheus/tools</span><span class="synStatement">'</span>
make <span class="synSpecial">-C</span> rule_checker
make<span class="synStatement">[</span><span class="synConstant">2</span><span class="synStatement">]</span>: Entering directory <span class="synSpecial">`/usr/</span><span class="synStatement">local</span><span class="synSpecial">/src/prometheus/tools/rule_checker</span><span class="synStatement">'</span>
<span class="synConstant">TMPDIR=/tmp GOROOT=/usr/local/src/prometheus/.build/root/go GOPATH=/usr/local/src/prometheus/.build/root/gopath /usr/local/src/prometheus/.build/root/go/bin/go build -o rule_checker .</span>
<span class="synConstant">make[2]: Leaving directory `/usr/local/src/prometheus/tools/rule_checker</span><span class="synStatement">'</span>
<span class="synSpecial">make[</span><span class="synConstant">1</span><span class="synSpecial">]: Leaving directory `</span>/usr/<span class="synStatement">local</span>/src/prometheus/tools<span class="synStatement">'</span>
<span class="synConstant">make -C web</span>
<span class="synConstant">make[1]: Entering directory `/usr/local/src/prometheus/web</span><span class="synStatement">'</span>
<span class="synComment"># Note that embed-static.sh excludes map files and the</span>
<span class="synComment"># non-minified bootstrap files.</span>
../utility/embed-static.sh static templates | /usr/<span class="synStatement">local</span>/src/prometheus/.build/root/go/bin/gofmt <span class="synStatement">></span> blob/files.go
make<span class="synStatement">[</span><span class="synConstant">1</span><span class="synStatement">]</span>: Leaving directory <span class="synSpecial">`/usr/</span><span class="synStatement">local</span><span class="synSpecial">/src/prometheus/web</span><span class="synStatement">'</span>
<span class="synConstant">TMPDIR=/tmp GOROOT=/usr/local/src/prometheus/.build/root/go GOPATH=/usr/local/src/prometheus/.build/root/gopath /usr/local/src/prometheus/.build/root/go/bin/go build -o prometheus -ldflags " -X main.buildVersion 0.10.0 -X main.buildRevision 982923f -X main.buildBranch master -X main.buildUser root@vm-local -X main.buildDate 20150205-18:56:43 -X main.goVersion 1.4" .</span>
</pre>
<h3>設定ファイルの作成</h3>
<p>例に従い、次の内容の設定ファイルを<code>prometheus.conf</code>として作成しました。</p>
<pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synComment"># Global default settings.</span>
<span class="synConstant">global</span>: {
<span class="synConstant">scrape_interval</span>: <span class="synSpecial">"</span><span class="synConstant">15s</span><span class="synSpecial">"</span> <span class="synComment"># By default, scrape targets every 15 seconds.</span>
<span class="synConstant">evaluation_interval</span>: <span class="synSpecial">"</span><span class="synConstant">15s</span><span class="synSpecial">"</span> <span class="synComment"># By default, evaluate rules every 15 seconds.</span>
<span class="synComment"># Attach these extra labels to all time series collected by this Prometheus instance.</span>
<span class="synConstant">labels</span>: {
<span class="synConstant">label</span>: {
<span class="synConstant">name</span>: <span class="synSpecial">"</span><span class="synConstant">monitor</span><span class="synSpecial">"</span>
<span class="synConstant">value</span>: <span class="synSpecial">"</span><span class="synConstant">tutorial-monitor</span><span class="synSpecial">"</span>
}
}
}
<span class="synComment"># A job definition containing exactly one endpoint to scrape: Prometheus itself.</span>
<span class="synConstant">job</span>: {
<span class="synComment"># The job name is added as a label `job={job-name}` to any time series scraped from this job.</span>
<span class="synConstant">name</span>: <span class="synSpecial">"</span><span class="synConstant">prometheus</span><span class="synSpecial">"</span>
<span class="synComment"># Override the global default and scrape targets from this job every 5 seconds.</span>
<span class="synConstant">scrape_interval</span>: <span class="synSpecial">"</span><span class="synConstant">5s</span><span class="synSpecial">"</span>
<span class="synComment"># Let's define a group of static targets to scrape for this job. In this</span>
<span class="synComment"># case, only one.</span>
<span class="synConstant">target_group</span>: {
<span class="synComment"># These endpoints are scraped via HTTP.</span>
<span class="synConstant">target</span>: <span class="synSpecial">"</span><span class="synConstant">http://localhost:9090/metrics</span><span class="synSpecial">"</span>
}
}
</pre>
<h3>起動</h3>
<p>先ほどの設定ファイルの他、<code>storage.local.path</code>でメトリクスデータを保存する先を指定して起動します。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ ./prometheus -<span class="synIdentifier">config.file</span>=prometheus.conf -<span class="synIdentifier">storage.local.path</span>=/tmp/prometheus-metrics
prometheus, version 0.10.0 <span class="synPreProc">(</span><span class="synSpecial">branch: master, revision: 982923f</span><span class="synPreProc">)</span>
build user: root@vms-<span class="synStatement">local</span>
build date: <span class="synConstant">20150205-18</span>:<span class="synConstant">56</span>:<span class="synConstant">43</span>
go version: 1.4
</pre>
<h3>ブラウザで確認</h3>
<p>初期起動画面はこのような感じでした。<br />
データがまだないので、何か入れて見たいと思います。</p>
<p><code>http://your-host:9090/</code>にアクセスすると、status画面が表示されました。</p>
<p><img src="https://qiita-image-store.s3.amazonaws.com/0/19199/f3a51d5a-ec4d-1cbe-ab21-438820bd0e90.png" alt="prometheus-status.png" /></p>
<p><code>http://your-host:9090/metrics</code>にアクセスすると、そのホストで保持しているメトリクス情報が出力されました。</p>
<p><img src="https://qiita-image-store.s3.amazonaws.com/0/19199/9157f359-311b-eb82-5fac-f502ce164f2f.png" alt="prometheus-metrics.png" /></p>
<p><code>http://your-host:9090/alerts</code>にアクセスすると、アラート情報があれば表示されるようです。</p>
<p><img src="https://qiita-image-store.s3.amazonaws.com/0/19199/f56a0267-7ae8-1f8f-ced3-d8395eb385eb.png" alt="prometheus-alerts.png" /></p>
<p><code>http://your-host:9090/graph</code>にアクセスすると、グラフを追加出来るようになっておりました。</p>
<p><img src="https://qiita-image-store.s3.amazonaws.com/0/19199/513b9d6a-ec5d-c632-b7be-e3a30ca586c5.png" alt="prometheus-graph.png" /></p>
<p>データが無いので何とも言えませんが、割と気軽に始められました。<br />
Fluentdとの連携など、引き続き検証を進めていきたいと思います。</p>
yoshi-ken
elasticsearchのファイルディスクリプタを監視する
hatenablog://entry/8454420450080297722
2015-01-15T12:18:35+09:00
2015-01-15T15:49:21+09:00 elasticsearchはLuceneをベースにしているため、細かい粒度でのファイルを多く生成します。 そのため "too many open files" エラーが発生して停止しないよう、安定稼働のためには日頃のリソース監視が必要です。 では、どのようにファイルディスクリプタの利用状況を確認すれば良いのでしょうか。調べてみました。
<p>elasticsearchは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lucene">Lucene</a>をベースにしているため、細かい粒度でのファイルを多く生成します。<br />
そのため "too many open files" エラーが発生して停止しないよう、安定稼働のためには日頃のリソース監視が必要です。<br />
では、どのようにファイル<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%AF%A5%EA%A5%D7%A5%BF">ディスクリプタ</a>の利用状況を確認すれば良いのでしょうか。調べてみました。</p>
<h2>検証環境</h2>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%A3%BF%F4">複数</a>のバージョンでテストしております。</p>
<ul>
<li>elasticsearch 1.0.1</li>
<li>elasticsearch 1.3.4</li>
<li>elasticsearch 1.4.2</li>
</ul>
<h2>調査の目的</h2>
<p>root権限が必要な<code>/proc/{proc_id}/limits</code>などを参照せずに次の値を取得する方法。</p>
<ul>
<li>max_file_descriptors</li>
<li>open_file_descriptors</li>
</ul>
<h2>同時に開ける最大のファイル数(Max open files)の確認</h2>
<p>elasticsearchいずれのバージョンでも同様の結果を取得できます。
?prettyを付けると人間に読みやすい形式で改行やインデントをしてくれるので大変便利ですね。</p>
<p>この結果の{nodes}->{e1Gbmg6PQdOklg7NktAEvA}->{process}->{max_file_descriptors}を参照します。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ curl localhost:<span class="synConstant">9200</span>/_nodes/_local/process?pretty
<span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">cluster_name</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">elasticsearch</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">nodes</span><span class="synStatement">"</span> : <span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">e1Gbmg6PQdOklg7NktAEvA</span><span class="synStatement">"</span> : <span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">name</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">Soldier X</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">transport_address</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">inet[/**.**.**.***:9300]</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">host</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">******</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">ip</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">**.**.**.***</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">version</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">1.4.2</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">build</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">927caff</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">http_address</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">inet[/**.**.**.***:9200]</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">process</span><span class="synStatement">"</span> : <span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">refresh_interval_in_millis</span><span class="synStatement">"</span> : <span class="synConstant">1000</span>,
<span class="synStatement">"</span><span class="synConstant">id</span><span class="synStatement">"</span> : <span class="synConstant">2403</span>,
<span class="synStatement">"</span><span class="synConstant">max_file_descriptors</span><span class="synStatement">"</span> : <span class="synConstant">65535</span>,
<span class="synStatement">"</span><span class="synConstant">mlockall</span><span class="synStatement">"</span> : <span class="synStatement">false</span>
<span class="synSpecial">}</span>
<span class="synSpecial">}</span>
<span class="synSpecial">}</span>
<span class="synSpecial">}</span>
</pre>
<p>jqコマンドなら、次のように値だけ取得できます。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ curl <span class="synSpecial">-s</span> localhost:<span class="synConstant">9200</span>/_nodes/_local/process | jq <span class="synStatement">'</span><span class="synConstant">.nodes[] |.process.max_file_descriptors</span><span class="synStatement">'</span>
<span class="synConstant">65535</span>
</pre>
<p>もし未設定の場合には、多めに設定しておきましょう。<br />
<a class="keyword" href="http://d.hatena.ne.jp/keyword/CentOS">CentOS</a>であれば<code>/etc/sysconfig/elasticsearch</code>の<code>MAX_OPEN_FILES</code>を編集します。</p>
<h2>open file descriptorsの確認</h2>
<p>現在開いているファイル数は、次のコマンド結果の<code>open_file_descriptors</code>を見ます。<br />
elasticsearchいずれのバージョンでも同様の結果を取得できます。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ curl localhost:<span class="synConstant">9200</span>/_nodes/_local/stats/process?pretty
<span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">cluster_name</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">elasticsearch</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">nodes</span><span class="synStatement">"</span> : <span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">e1Gbmg6PQdOklg7NktAEvA</span><span class="synStatement">"</span> : <span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">timestamp</span><span class="synStatement">"</span> : <span class="synConstant">1421290231439</span>,
<span class="synStatement">"</span><span class="synConstant">name</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">Soldier X</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">transport_address</span><span class="synStatement">"</span> : <span class="synStatement">"</span><span class="synConstant">inet[/**.**.**.***:9300]</span><span class="synStatement">"</span>,
<span class="synStatement">"</span><span class="synConstant">host</span><span class="synStatement">"</span> : <span class="synStatement">""</span>,
<span class="synStatement">"</span><span class="synConstant">ip</span><span class="synStatement">"</span> : <span class="synStatement">[</span> <span class="synStatement">"</span><span class="synConstant">inet[/**.**.**.***:9300]</span><span class="synStatement">"</span>, <span class="synStatement">"</span><span class="synConstant">NONE</span><span class="synStatement">"</span> <span class="synStatement">]</span>,
<span class="synStatement">"</span><span class="synConstant">process</span><span class="synStatement">"</span> : <span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">timestamp</span><span class="synStatement">"</span> : <span class="synConstant">1421290231439</span>,
<span class="synStatement">"</span><span class="synConstant">open_file_descriptors</span><span class="synStatement">"</span> : <span class="synConstant">222</span>,
<span class="synStatement">"</span><span class="synConstant">cpu</span><span class="synStatement">"</span> : <span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">percent</span><span class="synStatement">"</span> : <span class="synConstant">0</span>,
<span class="synStatement">"</span><span class="synConstant">sys_in_millis</span><span class="synStatement">"</span> : <span class="synConstant">38985620</span>,
<span class="synStatement">"</span><span class="synConstant">user_in_millis</span><span class="synStatement">"</span> : <span class="synConstant">48149180</span>,
<span class="synStatement">"</span><span class="synConstant">total_in_millis</span><span class="synStatement">"</span> : <span class="synConstant">87134800</span>
<span class="synSpecial">}</span>,
<span class="synStatement">"</span><span class="synConstant">mem</span><span class="synStatement">"</span> : <span class="synSpecial">{</span>
<span class="synStatement">"</span><span class="synConstant">resident_in_bytes</span><span class="synStatement">"</span> : <span class="synConstant">1137655808</span>,
<span class="synStatement">"</span><span class="synConstant">share_in_bytes</span><span class="synStatement">"</span> : <span class="synConstant">13058048</span>,
<span class="synStatement">"</span><span class="synConstant">total_virtual_in_bytes</span><span class="synStatement">"</span> : <span class="synConstant">13476794368</span>
<span class="synSpecial">}</span>
<span class="synSpecial">}</span>
<span class="synSpecial">}</span>
<span class="synSpecial">}</span>
<span class="synSpecial">}</span>
</pre>
<p>なお、<a href="http://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af">軽量JSONパーサー『jq』</a>なら、次のようにデータだけ取得できます。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ curl <span class="synSpecial">-s</span> localhost:<span class="synConstant">9200</span>/_nodes/_local/stats/process | jq <span class="synStatement">'</span><span class="synConstant">.nodes[] |.process.open_file_descriptors</span><span class="synStatement">'</span>
<span class="synConstant">222</span>
</pre>
<h2>まとめ</h2>
<p>傾向を把握するためにも、日頃からリソース監視を行い、グラフなどで可視化しておけると良いですね。</p>
<p>リソース監視の際には、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Perl">Perl</a>で書かれた次のMunin Pluginを利用すると大変便利ですよ!<br /></p>
<ul>
<li>A useful Munin plugin for monitoring elasticsearch 1.x nodes in <a class="keyword" href="http://d.hatena.ne.jp/keyword/Perl">Perl</a>.<br />
<a href="https://github.com/y-ken/munin-plugin-elasticsearch">https://github.com/y-ken/munin-plugin-elasticsearch</a></li>
</ul>
<h2>併せて読みたい</h2>
<ul>
<li>Elasticsearch のノードで "too many open files" が出てしまったので対処したメモ - ようへいの日々精進 XP<br />
<a href="http://inokara.hateblo.jp/entry/2014/03/08/083548">http://inokara.hateblo.jp/entry/2014/03/08/083548</a></li>
</ul>
yoshi-ken
どこでもオンライン♪ 人工衛星経由でリモート作業を進めるテクニック
hatenablog://entry/8454420450077499923
2014-12-25T11:52:00+09:00
2014-12-25T11:52:02+09:00 こんにちは、某L社のAdventCalendarの25日目を担当する事になりました、よしけんさんです。 「人工衛星経由でインターネットできる」と聞いたら、なんだか未来感があってワクワクしませんか? これさえ持っていれば、どんな過酷な旅をしていようとも通信できる安心感。頼もしいですね。 photo by Hans J. Hansen 衛星電話とは 次の特徴を持つ、強力な通信デバイスです。 地上がどうなろうとも空が見えていれば、リモート作業が捗ります!!!! 1)世界中、海のど真ん中でも山の頂上でも何処でも繋がります 2)着信やローミング手数料が掛かりません 3)衛星を利用しているので、地上のイン…
<p>こんにちは、某L社のAdventCalendarの25日目を担当する事になりました、よしけんさんです。</p>
<p>「<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BF%CD%B9%A9%B1%D2%C0%B1">人工衛星</a>経由でインターネットできる」と聞いたら、なんだか未来感があってワクワクしませんか?
これさえ持っていれば、どんな過酷な旅をしていようとも通信できる安心感。頼もしいですね。</p>
<p><a href="http://www.flickr.com/photos/9884500@N05/3993643015"><img src="http://farm3.staticflickr.com/2567/3993643015_bffbc266c8.jpg" alt="" /></a></p>
<p><a href="http://www.flickr.com/photos/9884500@N05/3993643015">photo by Hans J. Hansen</a></p>
<h2>衛星電話とは</h2>
<p>次の特徴を持つ、強力な通信デバイスです。<br />
地上がどうなろうとも空が見えていれば、リモート作業が捗ります!!!!</p>
<blockquote><p>1)世界中、海のど真ん中でも山の頂上でも何処でも繋がります<br />
2)着信や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A1%BC%A5%DF%A5%F3%A5%B0">ローミング</a>手数料が掛かりません<br />
3)衛星を利用しているので、地上のインフラが壊滅しても通信が出来ます</p></blockquote>
<p>本日は衛星電話を用いたリモート作業の検証レポートを海外からお届けします。<br />
あまり、役に立つときが来て欲しくないものですけどね (~_~;)</p>
<h2>検証端末</h2>
<p>日本デジコムよりレンタルしました、スラーヤ(Thuraya) SG-2520 です。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20110301/20110301183614.jpg" alt="f:id:yoshi-ken:20110301183614j:plain" title="f:id:yoshi-ken:20110301183614j:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%EA%A5%B8%A5%A6%A5%E0">イリジウム</a>に比べるとカバーエリアは狭いですが、それでも2機の衛星でここまでカバーしているとはすごいですね。</p>
<ul>
<li>Thuraya-1(現在、バックアップ衛星)</li>
<li>Thuraya-2(アフリカ・中東・ヨーロッパ地域をカバー)</li>
<li>Thuraya-3(アジア・ユーラシア・<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%BB%A5%A2%A5%CB%A5%A2">オセアニア</a>地域をカバー)</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219173834.jpg" alt="f:id:yoshi-ken:20141219173834j:plain" title="f:id:yoshi-ken:20141219173834j:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>画像引用元: <a href="http://www.jdc.ne.jp/thuraya_sg-2520.html">http://www.jdc.ne.jp/thuraya_sg-2520.html</a></p>
<h2>通信速度・課金単位</h2>
<p>データ通信速度の仕様は下り60kbps/上り15kbpsとなっております。<br />
実際の体感速度としては、ダイアルアップと<a class="keyword" href="http://d.hatena.ne.jp/keyword/ISDN">ISDN</a>の間くらいです。<br />
<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSH">SSH</a>作業は日本とアメリカ間程度のレインテンシを感じながらも、不自由なく出来ました。</p>
<p>課金単位はありがちな通信時間ではなくパケット単位のため、常時接続が可能です。<br />
なお、<a href="http://www.jdc.ne.jp/thuraya_ip.html">THURAYA IP</a>であれば最大444kbpsの高速通信が定額で出来ます。</p>
<h2>衛星の方角</h2>
<p>地上で使える無線通信とは異なり、衛星通信を行う際はアンテナの方角が重要です。<br />
屋外の南西方向に開けた場所にて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%D8%B8%FE%C0%AD%A5%A2%A5%F3%A5%C6%A5%CA">指向性アンテナ</a>を衛星の方向に向けて使います。<br />
東京では南西仰角30度ですが、これは方位磁石を使わなくともおおよその方向を知るテクニックがあります。</p>
<table>
<thead>
<tr>
<th> 時間帯 </th>
<th> 方角の確認方法 </th>
</tr>
</thead>
<tbody>
<tr>
<td> 昼(正午) </td>
<td> 正午に太陽がある方向が南です </td>
</tr>
<tr>
<td> 日中 </td>
<td> アナログ腕時計の短針を太陽の方向に向け、文字版の12時と短針の角度の半分の方向が南です </td>
</tr>
<tr>
<td> 夜間 </td>
<td> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%CB%CC%B6%CB%C0%B1">北極星</a>の位置が北です </td>
</tr>
</tbody>
</table>
<p>参考: <a href="http://www.popxpop.com/archives/2007/08/post_341.html">http://www.popxpop.com/archives/2007/08/post_341.html</a></p>
<h2>接続方法</h2>
<p>通信状況の良い場所に衛星電話を角度を調整して設置(荷物に立てかける等)し、<br />
室内の暖かいところから<a class="keyword" href="http://d.hatena.ne.jp/keyword/Bluetooth">Bluetooth</a>接続するのがおすすめです。<br />
事前に本体への設定を次のように済ませておきます。</p>
<pre class="code" data-lang="" data-unlink># Connectivity > Bluetooth
Bluetooth : On
My Visibility : On
Modem : Dial up Network
Authorization : Normal Profile / DUN Profile
# Network > System preference
SAT only</pre>
<p>衛星電話の設定が済んだら次は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>側の設定です。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219163931.png" alt="f:id:yoshi-ken:20141219163931p:plain" title="f:id:yoshi-ken:20141219163931p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219163929.png" alt="f:id:yoshi-ken:20141219163929p:plain" title="f:id:yoshi-ken:20141219163929p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219163927.png" alt="f:id:yoshi-ken:20141219163927p:plain" title="f:id:yoshi-ken:20141219163927p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219163924.png" alt="f:id:yoshi-ken:20141219163924p:plain" title="f:id:yoshi-ken:20141219163924p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219163922.png" alt="f:id:yoshi-ken:20141219163922p:plain" title="f:id:yoshi-ken:20141219163922p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Bluetooth">Bluetooth</a>経由でのインターネット接続</h2>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20110301/20110301185300.jpg" alt="f:id:yoshi-ken:20110301185300j:plain" title="f:id:yoshi-ken:20110301185300j:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>ネットワーク環境設定に端末が追加されているので、それを用いて接続してみましょう。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219163923.png" alt="f:id:yoshi-ken:20141219163923p:plain" title="f:id:yoshi-ken:20141219163923p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>メニューバーからも接続/切断の操作ができます。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219163925.png" alt="f:id:yoshi-ken:20141219163925p:plain" title="f:id:yoshi-ken:20141219163925p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BF%CD%B9%A9%B1%D2%C0%B1">人工衛星</a>経由で<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSH">SSH</a>も出来る</h2>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219154525.png" alt="f:id:yoshi-ken:20141219154525p:plain" title="f:id:yoshi-ken:20141219154525p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>インターネットの一般的な利用方法である<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D6%A5%E9%A5%A6%A5%B8%A5%F3%A5%B0">ブラウジング</a>やメールはもちろん、<br />
Thurayaはポート制限が掛かっていないので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSH">SSH</a>接続もできます。(他社の状況は不明)<br />
確認君での結果は次の通りです。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141219/20141219154340.png" alt="f:id:yoshi-ken:20141219154340p:plain" title="f:id:yoshi-ken:20141219154340p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>THURAYAはこのあたりのIP帯域を持っているようです。<br />
事前に踏み台サーバや<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPN">VPN</a>機器の<a class="keyword" href="http://d.hatena.ne.jp/keyword/ACL">ACL</a>リストなどに追加しておけば使えそうですね。</p>
<table>
<thead>
<tr>
<th> Prefix </th>
<th> Description </th>
</tr>
</thead>
<tbody>
<tr>
<td> 85.115.64.0/24 </td>
<td> IP range for routers and others United Arab Emirates </td>
</tr>
<tr>
<td> 85.115.65.0/24 </td>
<td> Thuraya Telecommunications Private Joint-Stock Company United Arab Emirates </td>
</tr>
<tr>
<td> 85.115.70.0/24 </td>
<td> Thuraya Information Security United Arab Emirates </td>
</tr>
<tr>
<td> 85.115.71.0/24 </td>
<td> Thuraya Information Security United Arab Emirates </td>
</tr>
<tr>
<td> 85.115.72.0/21 </td>
<td> IP range for <a class="keyword" href="http://d.hatena.ne.jp/keyword/DSL">DSL</a> Terminals United Arab Emirates </td>
</tr>
<tr>
<td> 85.115.80.0/21 </td>
<td> IP range for <a class="keyword" href="http://d.hatena.ne.jp/keyword/DSL">DSL</a> Terminals United Arab Emirates </td>
</tr>
<tr>
<td> 195.229.15.0/24 </td>
<td> Emirates Telecommunications Corporation </td>
</tr>
</tbody>
</table>
<p>引用元: <a href="http://bgp.he.net/AS44703#_prefixes">http://bgp.he.net/AS44703#_prefixes</a></p>
<h2>まとめ</h2>
<p>端末は<a href="http://www.jdc.ne.jp/index.html">日本デジコム</a>からレンタル出来ます。<br />
意外とお手軽プライスで使えるので、是非必要になった時にはご検討ください。</p>
<h2>注記</h2>
<p>現在は弊社も大きくなり、長期休暇中に運用ケータイの当番は回ってきませんのでご安心を。</p>
yoshi-ken
FluentdでURL付きツイートを漏れなく収集する方法
hatenablog://entry/8454420450077503661
2014-12-22T12:00:00+09:00
2014-12-22T12:00:12+09:00 Twitterで言及されている様々な記事のURLを収集したいと考えた時、次の方法が選択肢となります。 定期的にAPIを叩く ストリーミングAPIを使う 前者の方法では単位時間毎のAPIコール制限を容易に超えてしまうので避けたいところですね。 そこでストリーミングAPIを使いたい所ですが、URLのトラッキングを行う方法がわかりにくかったので調べてみました。
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>で言及されている様々な記事のURLを収集したいと考えた時、次の方法が選択肢となります。</p>
<ul>
<li>定期的に<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を叩く</li>
<li>ストリーミング<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を使う</li>
</ul>
<p>前者の方法では単位時間毎の<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>コール制限を容易に超えてしまうので避けたいところですね。<br />
そこでストリーミング<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を使いたい所ですが、URLのト<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%C3%A5%AD%A5%F3%A5%B0">ラッキング</a>を行う方法がわかりにくかったので調べてみました。</p>
<h2>ストリーミング<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>でのURLト<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%C3%A5%AD%A5%F3%A5%B0">ラッキング</a>方法</h2>
<p>その方法は意外なほどシンプルでした。<br />
ドットやスラッシュなどの記号を半角スペースにして、コンマに並べるというものです。<br /></p>
<p>例えば、"example com"と指定すると、次のパターンにマッチします。</p>
<ul>
<li><code>example.com</code></li>
<li><code>www.example.com</code></li>
<li><code>foo.example.com</code></li>
<li><code>foo.example.com/bar</code></li>
<li><code>I hope my startup isn’t merely another example of a dot com boom!</code></li>
</ul>
<p>参考: <a href="https://dev.twitter.com/streaming/overview/request-parameters#track">https://dev.twitter.com/streaming/overview/request-parameters#track</a></p>
<h2>設定サンプル</h2>
<p>先ほどの手法を元に、<a href="https://github.com/y-ken/fluent-plugin-twitter">fluent-plugin-twitter</a>を用いてツイートを収集する方法はこちらです。<br />
なお、事前にFluentdを実行する環境および<a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>キーの準備が整っていることとします。</p>
<pre class="code" data-lang="" data-unlink><source>
type twitter
# APIキーを指定
consumer_key *******************
consumer_secret **************************************
oauth_token **************************************
oauth_token_secret **************************************
# タグを指定
tag twitter.keyword
# 取得タイムライン種別を指定
timeline tracking
# 収集したいキーワードを指定 (qiita.comとmatome.naver.jpのURL付きツイートを収集)
keyword qiita com,matome naver jp
# もしツイートの言語を絞る際は指定する
#lang ja,en
# データ構造
output_format nest
</source>
# JSON形式でローカルディスクに保存する
<match twitter.keyword>
type file
path /var/log/td-agent/twitter_keyword_*.json
symlink_path /var/log/td-agent/twitter_keyword.json
format json
append true
compress gzip
</match></pre>
<p>なお、もし<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CF%A5%C3%A5%B7%A5%E5%A5%BF%A5%B0">ハッシュタグ</a>を検索したい場合にはトリッキーですが、次のように<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>を指定してみてください。
"#matome" であれば、<code>keyword ${hashtag}matome</code>と設定しましょう。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>内で自動的に展開されて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CF%A5%C3%A5%B7%A5%E5%A5%BF%A5%B0">ハッシュタグ</a>として扱われます。</p>
<h2>まとめ</h2>
<p>Fluentd Advent Calendar 22日目の内容は、Fluentd+<a class="keyword" href="http://d.hatena.ne.jp/keyword/twitter">twitter</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>のTips紹介でした。<br />
<a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>のデータ収集など、オンライン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%C3%A5%C1%BD%E8%CD%FD">バッチ処理</a>にもってこいのデータソースですね。<br />
是非何かに役立ててみてください。</p>
yoshi-ken
要確認!GitHubでうっかり放置してしまったIssueやPullRequestを検索する方法
hatenablog://entry/8454420450076533544
2014-12-09T11:31:12+09:00
2014-12-09T12:03:45+09:00 GitHubで後で見ておこうと放置してしまったIssueやPullRequestはございませんか? ブラウザUIで見られるダッシュボードからはPull RequestsやIssuesが見られますが、 その一覧には自分のリポジトリへ第三者が発行したIssueやPull Requestはありません。 この画面に検索クエリが打ち込めそうなフィールドがあるので、ここにヒントがありそうです。
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>で後で見ておこうと放置してしまったIssueやPullRequestはございませんか?</p>
<p>ブラウザUIで見られるダッシュボードからはPull RequestsやIssuesが見られますが、
その一覧には自分の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>へ第三者が発行したIssueやPull Requestはありません。</p>
<p>この画面に検索クエリが打ち込めそうなフィールドがあるので、ここにヒントがありそうです。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20141209/20141209111957.png" alt="f:id:yoshi-ken:20141209111957p:plain" title="f:id:yoshi-ken:20141209111957p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<h1><a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>の検索で使える修飾子</h1>
<p>次のドキュメントを読むと、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>での検索にはこういった検索修飾子がありました。<br />
これらを組み合わせるとさまざまな検索が出来そうです。</p>
<ul>
<li>is</li>
<li>type</li>
<li>user</li>
<li>team</li>
<li>author</li>
<li>created</li>
<li>merged</li>
</ul>
<p>Searching issues - User Documentation<br />
<a href="https://help.github.com/articles/searching-issues/">https://help.github.com/articles/searching-issues/</a></p>
<h2>自分の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>へ起票されたIssue/PRを見る方法</h2>
<p>例えば、次の条件で調べるクエリは<code>is:open user:fluent</code>となります。</p>
<ul>
<li>fluent<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>以下を対象とする <a href="https://github.com/fluent/">https://github.com/fluent/</a></li>
<li>誰かに起票されたがクローズされていないIssueとPull Requestを探す</li>
</ul>
<p><a href="https://github.com/pulls?q=is%3Aopen+user%3Afluent">https://github.com/pulls?q=is%3Aopen+user%3Afluent</a></p>
<p>早速このURLを開いて、userの値を自分の<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>ユーザ名に書き換えてみましょう。<br />
これで、忘れかけていたIssue達を掘り出せますね!</p>
<h2>おまけ</h2>
<p>Organizationで利用の際は、teamを作って権限管理などを行うと思います。<br />
先ほどのuserの代わりに、任意のチーム名を<code>team:fluent/team-foo-bar</code>という具合に指定して検索しても良いでしょう。</p>
yoshi-ken
実は簡単なFluentdプラグインのv1-config対応テストの書き方
hatenablog://entry/8454420450076128230
2014-12-04T19:40:53+09:00
2014-12-04T19:40:53+09:00 Fluentd Advent Calendarの4日目は、Fluentdプラグインを数多くメンテナンスする@yoshi_kenがお届けします。 Fluentdはその拡張性の高さから、数多くのプラグインがリリースされております。 これをご覧になる方の中には、プラグインを自作された方もいらっしゃるかもしれません。 本日はこれからプラグインを書かれる方にも、既に自作プラグインを公開されている方にも便利なTipsをお届けします。
<p>Fluentd Advent Calendarの4日目は、<a href="http://rubygems.org/profiles/y-ken">Fluentdプラグイン</a>を数多くメンテナンスする<a href="https://twitter.com/yoshi_ken">@yoshi_ken</a>がお届けします。</p>
<p>Fluentdはその拡張性の高さから、数多くの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>がリリースされております。<br />
これをご覧になる方の中には、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を自作された方もいらっしゃるかもしれません。</p>
<p>本日はこれから<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を書かれる方にも、既に自作<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を公開されている方にも便利なTipsをお届けします。</p>
<p>さて、設定ファイルの記法が拡張された、<a href="http://docs.fluentd.org/articles/config-file#v1-format">V1 Format</a>環境下での動作を保証するためのテストコードの準備はいかがでしょうか。<br />
筆者自身がメンテナンスする<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>もこれから対応を進めていくといった状況です。</p>
<p>手を付ける前は実装の仕方は意外と大変なのでは無いかと不安でしたが、実際はとても簡単です。</p>
<h2>STEP-1 : 既存のconfigure<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9">メソッド</a>を拡張する</h2>
<p>configure<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9">メソッド</a>の第2引数にtrueを指定すると設定がv1 configとして処理されるようになります。<br />
Fluentd本体の対応は <a href="https://github.com/fluent/fluentd/commit/09156a364893a10e1ef08bdcd0e3b426832f8a5c">Support use_v1 argument to enable V1 configuration in test module. fixes... · 09156a3 · fluent/fluentd</a> にて済んでおりますので、fluentd v0.10.51以降であれば使えます。</p>
<p>具体的には、<code>test/plugin/test_*****.rb</code> にある記述を修正します。<br />
<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>のクラス名がGeoipOutputの場合は次のような呼び出し方となります。</p>
<pre class="code lang-diff" data-lang="diff" data-unlink><span class="synSpecial">-def create_driver(conf=CONFIG,tag='test')</span>
<span class="synSpecial">- Fluent::Test::OutputTestDriver.new(Fluent::GeoipOutput, tag).configure(conf)</span>
<span class="synIdentifier">+def create_driver(conf=CONFIG,tag='test',use_v1=false)</span>
<span class="synIdentifier">+ Fluent::Test::OutputTestDriver.new(Fluent::GeoipOutput, tag).configure(conf, use_v1)</span>
end
</pre>
<h2>STEP-2 : V1-Formatで設定をパースして処理するテストを追加する</h2>
<p>各テストの中でv1-configとして設定をパースする箇所は、次のように第3引数にtrueを付けます。</p>
<pre class="code lang-ruby" data-lang="ruby" data-unlink>d1 = create_driver(<span class="synType">CONFIG</span>, <span class="synSpecial">'</span><span class="synConstant">input.access</span><span class="synSpecial">'</span>, <span class="synConstant">true</span>)
</pre>
<p>この1点の違いの他はこれまで通りに書けばテストを走らせられます。
今回実装した fluent-plugin-geoip のV1 Format対応のテストは次の通りです。</p>
<ul>
<li><a href="https://github.com/y-ken/fluent-plugin-geoip/blob/943f2bb/test/plugin/test_out_geoip.rb#L378">https://github.com/y-ken/fluent-plugin-geoip/blob/943f2bb/test/plugin/test_out_geoip.rb#L378</a></li>
</ul>
<p>併せて、コミットと同時に自動的にテストが走るCIサービス、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Travis">Travis</a>-CIとの連携も行っておくと良いと思います!<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>アカウントがあればすぐ使い始められますし、無料ですよ〜。</p>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Travis">Travis</a>-CIとの連携方法は、こちらの記事が参考になります。</p>
<ul>
<li><a href="http://sue445.hatenablog.com/entry/2014/07/16/194810">bundler + rspecでfluentdプラグインを作るための手順 - くりにっき</a></li>
</ul>
<h2>まとめ</h2>
<p>V1 Format (V1-Config)に対応するためのテストは思いの外簡単に書けます。<br />
未対応の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>があればこの機会に是非、Pull-Requestを送ってみても良いかもしれませんね!</p>
<p>私は年末年始休暇中にまとめて対応を進めようと画策中です!<br />
それでは良いクリスマス・年末をお過ごしください。</p>
<p>ではっ (。・_・)ノ</p>
<h2>宣伝</h2>
<p>年末年始にFluentdを触ってみよう!という方にはこちらの書籍が手元にあると心強いですよ。
<div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/"><img src="http://ecx.images-amazon.com/images/I/51lSb2Ie7WL._SL160_.jpg" class="hatena-asin-detail-image" alt="サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)" title="サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/">サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%CE%EB%CC%DA%B7%F2%C2%C0">鈴木健太</a>,吉田健太郎,大谷純,道井俊介</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2014/08/08</li><li><span class="hatena-asin-detail-label">メディア:</span> 大型本</li><li><a href="http://d.hatena.ne.jp/asin/4774169838/y_ken_studio-22" target="_blank">この商品を含むブログを見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p>
yoshi-ken
elasticsearchのクラスタで利用するNICをインターフェース名で指定する方法
hatenablog://entry/8454420450071653530
2014-10-31T17:49:01+09:00
2015-05-22T13:50:51+09:00 複数のインターフェースを搭載するマシンでelasticsearchをクラスタ稼働させると、1つ目のインターフェースのIPを対向クラスタへ返します。そのため、1つ目のインターフェースでクラスタ同士の疎通が出来ない構成で稼働させるには、network.publish_hostの調整が必要です。 もちろんサーバ毎の設定ファイルに個別にIPアドレスを書けば動きますが、そんな運用の手間となる設定は入れたくないですよね。 そういった時に便利に使える論理名(プレースホルダ)が用意されているので、それを使いましょう。
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%A3%BF%F4">複数</a>のインターフェースを搭載するマシンでelasticsearchを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF">クラスタ</a>稼働させると、1つ目のインターフェースのIPを対向<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF">クラスタ</a>へ返します。そのため、1つ目のインターフェースで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF">クラスタ</a>同士の疎通が出来ない構成で稼働させるには、<code>network.publish_host</code>の調整が必要です。</p>
<p>もちろんサーバ毎の設定ファイルに個別に<a class="keyword" href="http://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a>を書けば動きますが、そんな運用の手間となる設定は入れたくないですよね。<br />
そういった時に便利に使える論理名(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>)が用意されているので、それを使いましょう。</p>
<h2>elasticsearchのネットワーク設定で使える論理名</h2>
<p>これらの論理名は<code>network.bind_host</code> や <code>network.publish_host</code>で利用できます。
<a class="keyword" href="http://d.hatena.ne.jp/keyword/CentOS">CentOS</a>環境では<a class="keyword" href="http://d.hatena.ne.jp/keyword/YAML">YAML</a>ファイル <code>/etc/elasticsearch/elasticsearch.yml</code> にて設定します。</p>
<table>
<thead>
<tr>
<th> ホストの論理名 </th>
<th> 説明 </th>
</tr>
</thead>
<tbody>
<tr>
<td> <code>_local_</code> </td>
<td> ローカル<a class="keyword" href="http://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a> </td>
</tr>
<tr>
<td> <code>_non_loopback_</code> </td>
<td> 1つ目のループバックでない<a class="keyword" href="http://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a> </td>
</tr>
<tr>
<td> <code>_non_loopback:ipv4_</code> </td>
<td> 1つ目のループバックでない<a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv4">IPv4</a>アドレス </td>
</tr>
<tr>
<td> <code>_non_loopback:ipv6_</code> </td>
<td> 1つ目のループバックでない<a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv6">IPv6</a>アドレス </td>
</tr>
<tr>
<td> <code>_[networkInterface]_</code> </td>
<td> 指定されたネットワークインターフェースの<a class="keyword" href="http://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a>(例: <code>_en0_</code> ) </td>
</tr>
<tr>
<td> <code>_[networkInterface]:ipv4_</code> </td>
<td> 指定されたネットワークインターフェースの<a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv4">IPv4</a>アドレス(例: <code>_en0:ipv4_</code> ) </td>
</tr>
<tr>
<td> <code>_[networkInterface]:ipv6_</code> </td>
<td> 指定されたネットワークインターフェースの<a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv4">IPv4</a>アドレス(例: <code>_en0:ipv6_</code> ) </td>
</tr>
</tbody>
</table>
<p><a href="http://dev.classmethod.jp/cloud/aws/use-elasticsearch-3-use-awscloudplugin/">cloud-awsプラグイン</a>が入った環境では、次のネットワーク設定の論理名が利用できます。</p>
<table>
<thead>
<tr>
<th> EC2ホストの論理名 </th>
<th> 説明 </th>
</tr>
</thead>
<tbody>
<tr>
<td> <code>_ec2:privateIpv4_</code> </td>
<td> プライベート<a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv4">IPv4</a>アドレス </td>
</tr>
<tr>
<td> <code>_ec2:privateDns_</code> </td>
<td> プライベートホスト名 </td>
</tr>
<tr>
<td> <code>_ec2:publicIpv4_</code> </td>
<td> パブリックな<a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv4">IPv4</a>アドレス </td>
</tr>
<tr>
<td> <code>_ec2:publicDns_</code> </td>
<td> パブリックホスト名 </td>
</tr>
<tr>
<td> <code>_ec2_</code> </td>
<td> 短縮設定名のプライベート<a class="keyword" href="http://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a> </td>
</tr>
<tr>
<td> <code>_ec2:privateIp_</code> </td>
<td> 短縮設定名のプライベート<a class="keyword" href="http://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a> </td>
</tr>
<tr>
<td> <code>_ec2:publicIp_</code> </td>
<td> 短縮設定名のパブリック<a class="keyword" href="http://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a> </td>
</tr>
</tbody>
</table>
<h2>設定例</h2>
<p>eth0ではなくeth1で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF%A5%EA%A5%F3%A5%B0">クラスタリング</a>したいという例とともに、正しい設定と誤った設定を紹介します。</p>
<h4>eth1のネットワーク設定</h4>
<pre class="code" data-lang="" data-unlink>$ ifconfig eth1
eth1 Link encap:Ethernet HWaddr 52:54:13:00:36:08
inet addr:192.168.40.42 Bcast:192.168.40.255 Mask:255.255.255.0
inet6 addr: fe80::5054:13ff:fe00:3608/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:5611 errors:0 dropped:0 overruns:0 frame:0
TX packets:2268 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:515759 (503.6 KiB) TX bytes:775476 (757.3 KiB)</pre>
<h4>設定例の紹介</h4>
<p>デフォルトで利用されるeth0ではなくeth1を使う例を書く設定と共に紹介します。<br />
なお、設定は<a class="keyword" href="http://d.hatena.ne.jp/keyword/YAML">YAML</a>なので、<code>_eth1_</code>だけでなく<code>'_eth1_'</code>としても同様に動きますので、好みに合わせて調整しましょう。</p>
<h6>loopbackアドレスへの紐付け</h6>
<p><code>network.publish_host: _local_</code> とすると次のように、<code>localhost/127.0.0.1:9300</code>にてpublishされます。<br />
最初のlocal ip addressのloopbackでないものが利用されると想定しましたが、そうではないようです。</p>
<blockquote><p>[2014-10-31 16:21:11,044][INFO ][transport ] [labo-es01] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[<a class="keyword" href="http://d.hatena.ne.jp/keyword/localhost">localhost</a>/<a class="keyword" href="http://d.hatena.ne.jp/keyword/127.0.0.1">127.0.0.1</a>:9300]}</p></blockquote>
<h6><a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv4">IPv4</a>アドレスへの紐付け</h6>
<p><code>network.publish_host</code>の値を <code>_eth1:ipv4_</code> とすると次のように、eth1の<a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv4">IPv4</a>アドレスを用いてpublishされます。</p>
<blockquote><p>[2014-10-31 15:51:18,848][INFO ][transport ] [labo-es01] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/192.168.40.42:9300]}</p></blockquote>
<h6><a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv6">IPv6</a>アドレスへの紐付け</h6>
<p><code>network.publish_host</code>の値を <code>_eth1_</code> や <code>_eth1:ipv6_</code> とすると次のように、eth1の<a class="keyword" href="http://d.hatena.ne.jp/keyword/IPv6">IPv6</a>アドレスを用いてpublishされます。</p>
<blockquote><p>[2014-10-31 15:55:12,949][INFO ][transport ] [labo-es01] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/fe80:0:0:0:5054:13ff:fe00:3608%eth1:9300]}</p></blockquote>
<h4>その他の設定ミス例</h4>
<p>インターフェース名の前後を<code>_</code>を1つにするべきですが、<code>__</code>という具合に2つにしてしまうと次のように動きません。</p>
<blockquote>
$ <a class="keyword" href="http://d.hatena.ne.jp/keyword/grep">grep</a> " Startup Failed" -A2 /var/log/elasticsearch/elasticsearch.log <br>
[2014-10-31 15:45:59,609][<a class="keyword" href="http://d.hatena.ne.jp/keyword/ERROR">ERROR</a>][bootstrap ] [labo-es01] {1.3.4}: Startup Failed<br> ...<br>
- BindTransportException[Failed to resolve publish address]<br>
IOException[Failed to find network interface for [__eth1__]]<br>
--<br>
[2014-10-31 15:48:13,317][<a class="keyword" href="http://d.hatena.ne.jp/keyword/ERROR">ERROR</a>][bootstrap ] [labo-es01] {1.3.4}: Startup Failed<br> ...<br>
- BindTransportException[Failed to resolve publish address]<br>
IOException[Failed to find network interface for [__eth1:<a class="keyword" href="http://d.hatena.ne.jp/keyword/ipv4">ipv4</a>__]]<br>
</blockquote>
<h2>まとめ</h2>
<p><code>_eth1:ipv4_</code>あたりを使っておくと設定ファイルの統一も図れて良さそうですね。</p>
yoshi-ken
ElasticsearchのLogstash形式インデックスをお手軽に削除するワンライナー
hatenablog://entry/8454420450069766956
2014-10-22T12:42:24+09:00
2014-10-27T09:50:49+09:00 photo by Irina Souiki elasticsearchのlogstash形式インデックスを、定期的にcronで削除したいときに便利なワンライナーを紹介します。 使うコマンドはdateとcurlのみという大変シンプルなものですので、環境を選びません。
<p><a href="http://www.flickr.com/photos/36101699447@N01/70900580"><img src="http://farm1.staticflickr.com/20/70900580_a165e935bb.jpg" alt="" /></a></p>
<p><a href="http://www.flickr.com/photos/36101699447@N01/70900580">photo by Irina Souiki</a></p>
<p>elasticsearchのlogstash形式インデックスを、定期的にcronで削除したいときに便利な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EF%A5%F3%A5%E9%A5%A4%A5%CA%A1%BC">ワンライナー</a>を紹介します。
使うコマンドはdateと<a class="keyword" href="http://d.hatena.ne.jp/keyword/curl">curl</a>のみという大変シンプルなものですので、環境を選びません。</p>
<h2>既存<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a></h2>
<p>同様の目的を達成するための<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>はいくつかあります。<br />
いずれも、インストールや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>の設置が必要なものです。</p>
<h3>1. <a href="https://github.com/elasticsearch/curator">elasticsearch-curator</a></h3>
<p>elasticsearchが公式に開発している多機能な運用管理<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>です。<br />
しかしながら<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>であることと、筆者の<a class="keyword" href="http://d.hatena.ne.jp/keyword/CentOS">CentOS</a> 6.5の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> 2.6環境ではうまく動きませんでした。</p>
<p>次のように利用します。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ curator <span class="synSpecial">--host</span> my-elasticsearch delete <span class="synSpecial">--older-than</span> <span class="synConstant">14</span> <span class="synSpecial">--prefix</span> logstash-
</pre>
<p>使い方は次のページが参考になります。</p>
<ul>
<li><a href="http://qiita.com/ise_daisuke/items/266461ffc91246deb9ad">http://qiita.com/ise_daisuke/items/266461ffc91246deb9ad</a></li>
<li><a href="http://blog.johtani.info/blog/2014/01/24/curator-tending-your-time-series-indices-in-japanese/">http://blog.johtani.info/blog/2014/01/24/curator-tending-your-time-series-indices-in-japanese/</a></li>
</ul>
<h4>2. <a href="https://github.com/bloonix/logstash-delete-index">logstash-delete-index</a></h4>
<p>インデックスの削除に特化した<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>です。</p>
<p>次のようにどこかに設置した<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>を利用します。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ ./logstash_index_cleaner.py <span class="synSpecial">-d</span> <span class="synConstant">14</span> <span class="synSpecial">--host</span> my-elasticsearch <span class="synSpecial">--prefix</span> logstash-
</pre>
<h2>インデックスを削除する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EF%A5%F3%A5%E9%A5%A4%A5%CA%A1%BC">ワンライナー</a></h2>
<p>それでは本題の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EF%A5%F3%A5%E9%A5%A4%A5%CA%A1%BC">ワンライナー</a>を紹介します。こちら、<a class="keyword" href="http://d.hatena.ne.jp/keyword/CentOS">CentOS</a> 6.5にて動作を確認しております。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># PREFIXで接頭辞(普通は`logstash-`ですね)を指定</span>
<span class="synIdentifier">PREFIX</span>=<span class="synStatement">"</span><span class="synConstant">apache-</span><span class="synStatement">"</span>
<span class="synComment"># DAYで何日前のインデックスを削除するか指定</span>
<span class="synIdentifier">DAY</span>=<span class="synConstant">20</span>
<span class="synComment"># dateコマンドと先ほど指定したDAY変数で削除対象インデックスを求める</span>
<span class="synIdentifier">INDEX</span>=<span class="synSpecial">`date +</span><span class="synPreProc">$PREFIX</span><span class="synSpecial">%Y.%m.%d --date </span><span class="synStatement">"</span><span class="synPreProc">${DAY}</span><span class="synConstant"> days ago</span><span class="synStatement">"</span><span class="synSpecial">`</span>
<span class="synComment"># curlコマンドを用いてリクエストを発行する</span>
<span class="synComment"># 引数にあるホスト名は、環境に応じて書き換えましょう</span>
<span class="synComment"># -w引数は省略しても良いです。自動的にcurlコマンドの末尾に改行を追加するものです</span>
curl <span class="synSpecial">-XDELETE</span> <span class="synSpecial">-w</span><span class="synStatement">'</span><span class="synConstant">\n</span><span class="synStatement">'</span> <span class="synStatement">"</span><span class="synConstant">http://localhost:9200/</span><span class="synPreProc">${INDEX}</span><span class="synStatement">"</span>
</pre>
<p>これを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EF%A5%F3%A5%E9%A5%A4%A5%CA%A1%BC">ワンライナー</a>にすると、次のコードになります。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ <span class="synIdentifier">PREFIX</span>=<span class="synStatement">"</span><span class="synConstant">apache-</span><span class="synStatement">"</span>; <span class="synIdentifier">DAY</span>=<span class="synConstant">20</span>; <span class="synIdentifier">INDEX</span>=<span class="synSpecial">`date +</span><span class="synPreProc">$PREFIX</span><span class="synSpecial">%Y.%m.%d --date </span><span class="synStatement">"</span><span class="synPreProc">${DAY}</span><span class="synConstant"> days ago</span><span class="synStatement">"</span><span class="synSpecial">`</span>; curl <span class="synSpecial">-XDELETE</span> <span class="synSpecial">-w</span><span class="synStatement">'</span><span class="synConstant">\n</span><span class="synStatement">'</span> <span class="synStatement">"</span><span class="synConstant">http://localhost:9200/</span><span class="synPreProc">${INDEX}</span><span class="synStatement">"</span>
</pre>
<h4>cronへの設定例</h4>
<p>次に、20日前のインデックスを削除する設定例を次に紹介します。<br />
logstash形式のインデックスは<a class="keyword" href="http://d.hatena.ne.jp/keyword/UTC">UTC</a>で作られるため、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GMT">GMT</a>+9である日本にあわせて毎朝9時に実行しています。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synConstant">0</span> <span class="synConstant">9</span> * * * <span class="synIdentifier">PREFIX</span>=<span class="synStatement">"</span><span class="synConstant">apache-</span><span class="synStatement">"</span>; <span class="synIdentifier">DAY</span>=<span class="synConstant">20</span>; <span class="synIdentifier">INDEX</span>=<span class="synSpecial">`date +</span><span class="synPreProc">$PREFIX</span><span class="synSpecial">\%Y.\%m.\%d --date </span><span class="synStatement">"</span><span class="synPreProc">${DAY}</span><span class="synConstant"> days ago</span><span class="synStatement">"</span><span class="synSpecial">`</span>; curl <span class="synSpecial">-XDELETE</span> <span class="synSpecial">-w</span><span class="synStatement">'</span><span class="synConstant">\n</span><span class="synStatement">'</span> <span class="synStatement">"</span><span class="synConstant">http://localhost:9200/</span><span class="synPreProc">${INDEX}</span><span class="synStatement">"</span>
</pre>
<p>Crontabではパーセント記号はコマンドの終わりとして解釈されるのでエスケープしましょう。</p>
<h2>インデックスをclose/openする<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EF%A5%F3%A5%E9%A5%A4%A5%CA%A1%BC">ワンライナー</a></h2>
<p>closeするとき</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ <span class="synIdentifier">PREFIX</span>=<span class="synStatement">"</span><span class="synConstant">apache-</span><span class="synStatement">"</span>; <span class="synIdentifier">DAY</span>=<span class="synConstant">20</span>; <span class="synIdentifier">INDEX</span>=<span class="synSpecial">`date +</span><span class="synPreProc">$PREFIX</span><span class="synSpecial">\%Y.\%m.\%d --date </span><span class="synStatement">"</span><span class="synPreProc">${DAY}</span><span class="synConstant"> days ago</span><span class="synStatement">"</span><span class="synSpecial">`</span>; curl <span class="synSpecial">-XPOST</span> <span class="synSpecial">-w</span><span class="synStatement">'</span><span class="synConstant">\n</span><span class="synStatement">'</span> <span class="synStatement">"</span><span class="synConstant">http://localhost:9200/</span><span class="synPreProc">${INDEX}</span><span class="synConstant">/_close</span><span class="synStatement">"</span>
</pre>
<p>openするとき</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ <span class="synIdentifier">PREFIX</span>=<span class="synStatement">"</span><span class="synConstant">apache-</span><span class="synStatement">"</span>; <span class="synIdentifier">DAY</span>=<span class="synConstant">20</span>; <span class="synIdentifier">INDEX</span>=<span class="synSpecial">`date +</span><span class="synPreProc">$PREFIX</span><span class="synSpecial">\%Y.\%m.\%d --date </span><span class="synStatement">"</span><span class="synPreProc">${DAY}</span><span class="synConstant"> days ago</span><span class="synStatement">"</span><span class="synSpecial">`</span>; curl <span class="synSpecial">-XPOST</span> <span class="synSpecial">-w</span><span class="synStatement">'</span><span class="synConstant">\n</span><span class="synStatement">'</span> <span class="synStatement">"</span><span class="synConstant">http://localhost:9200/</span><span class="synPreProc">${INDEX}</span><span class="synConstant">/_open</span><span class="synStatement">"</span>
</pre>
<h2>まとめ</h2>
<p>今回は主にlogstash形式のインデックスの定期的な削除方法を紹介しました。<br />
logstash形式のインデックスをストアするelasticsearchを運用する上で、定期的に行った方がよいとされることは次の通りです。</p>
<ul>
<li>delete : 不要となったindexを削除し、関連するキャッシュもメモリから解放する</li>
<li>close : 存在はするが検索はしないときに使い、メモリから<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%BF%A5%C7%A1%BC%A5%BF">メタデータ</a>以外を解放する</li>
<li>bloom : クエリ実行を高速化するためのキャッシュをメモリから解放する</li>
</ul>
<p>まずはディスク容量の確保が出来るdeleteを利用し始めて、次に検索対象期間外のインデックスをcloseしましょう。<br />
その後にメモリ利用効率向上のため、検索対象ではあるがメモリには載せないようにするためのbloom filter cacheの利用も検討すると良いでしょう。</p>
yoshi-ken
データ可視化に便利なkibanaは、elasticsearchのsiteプラグインとして構成すると便利 #fluentd
hatenablog://entry/8454420450066641544
2014-09-30T12:26:36+09:00
2014-12-29T01:27:51+09:00 Fluentdなどから収集したメッセージをelasticsearchへ格納してKibanaで可視化するソリューションは素晴らしく、とても人気があります。
しかしそれだけのためにApacheやNginxなどのWEBサーバを新たに起ち上げるのは手間ですよね。
実は新たに起ち上げない方法もあるのです。こんな時に役立つTipsを紹介します。
<p>Fluentdなどから収集したメッセージをelasticsearchへ格納してKibanaで可視化するソリューションは素晴らしく、とても人気があります。次の画像のように見栄えが良いことも特徴です。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140930/20140930101026_original.png" alt="f:id:yoshi-ken:20140930101026p:plain" title="f:id:yoshi-ken:20140930101026p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>このダッシュボードアプリであるKibanaは<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>アプリケーションです。そのため静的ファイルを配置すればどこでも動きます。<br />
しかしそれだけのために<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apache">Apache</a>やNginxなどのWEBサーバを新たに起ち上げるのは手間ですよね。<br />
実は新たに起ち上げない方法もあるのです。こんな時に役立つTipsを紹介します。</p>
<h2>elasticsearchのsite<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a></h2>
<p>site<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は、ウェブベースのインターフェースを提供するものです。<br />
elasticsearchの挙動へ変更を加えるものではないため、サービス停止(再起動)を行わずにインストール・アップデート・アンインストールができます。<br />
<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%CB%A5%BF%A5%EA%A5%F3%A5%B0">モニタリング</a>や管理のための画面を提供する用途で使われており、次のような<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>が有名です。</p>
<ul>
<li>Marvel Plugin</li>
<li>Inquisitor Plugin</li>
<li>Elasticsearch HQ Plugin</li>
<li>Head Plugin</li>
</ul>
<p>それぞれのsite<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>については次のサイトの「Site Plugins.」に用途が記載されています。<br />
<a href="https://medium.com/hello-elasticsearch/elasticsearch-57c321354911">Elasticsearch プラグイン — Hello! Elasticsearch. — Medium</a></p>
<h3>Kibanaをsite<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>としてインストール</h3>
<p>それでは早速、Kibanaをelasticsearchへ、無停止でsite<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>としてインストールしてみましょう。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># 安定版としてリリースされた最新版のKibanaをインストールするコマンド</span>
$ <span class="synStatement">cd</span> /usr/share/elasticsearch
$ sudo bin/plugin <span class="synSpecial">-url</span> http://download.elasticsearch.org/kibana/kibana/kibana-latest.zip <span class="synSpecial">-install</span> elasticsearch/kibana3
-<span class="synStatement">></span> Installing elasticsearch/kibana3...
Trying http://download.elasticsearch.org/kibana/kibana/kibana-latest.zip...
Downloading ..................................................DONE
Installed elasticsearch/kibana3 into /usr/share/elasticsearch/plugins/kibana3
Identified as a _site plugin, moving to _site structure ...
</pre>
<p>なお、url引数にダウンロード先を指定しないと、次のURLからダウンロードできる<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>のmasterブランチのファイル群が利用されます。</p>
<ul>
<li><a href="https://github.com/elasticsearch/kibana/archive/master.zip">https://github.com/elasticsearch/kibana/archive/master.zip</a></li>
</ul>
<p>まれにmasterブランチでリグレッションや不具合が起きていることがあります。<br />
そのため、ここでは上記コマンド例のように、明示的に安定版としてリリースされたファイルを指定すると良いでしょう。</p>
<p>もしバージョンを固定する際は<a href="http://www.elasticsearch.org/overview/elkdownloads/#kibana">Kibanaのダウンロードページを参考に</a>、次のように指定します。</p>
<ul>
<li><a href="http://download.elasticsearch.org/kibana/kibana/kibana-latest.zip">http://download.elasticsearch.org/kibana/kibana/kibana-latest.zip</a></li>
<li><a href="https://download.elasticsearch.org/kibana/kibana/kibana-3.1.0.zip">https://download.elasticsearch.org/kibana/kibana/kibana-3.1.0.zip</a></li>
</ul>
<h3>動作確認</h3>
<p>次のURLを、elasticsearchが動くサーバの<a class="keyword" href="http://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a>に書き換えてアクセスしてみましょう。</p>
<pre class="code" data-lang="" data-unlink># スタートページ
# なお、url引数無しにインストールした場合は、ファイルパスが次の通り変更となります
# _plugin/kibana3/src/index.html
http://サーバのIPアドレス:9200/_plugin/kibana3/index.html
# Fluentdからlogstash形式のインデックス名で流し込んでいる場合
http://サーバのIPアドレス:9200/_plugin/kibana3/index.html#/dashboard/file/logstash.json</pre>
<p>Logstash形式とは、インデックス名を<code>logstash-YYYY.MM.DD</code>と動的に命名する形式です。<br />
もしFluentdの設定にてlogstash_prefixをカスタマイズしている場合には、Kibana画面右上の歯車アイコンを押すと開く画面からインデックス名の設定のカスタマイズを行いましょう。</p>
<h2>まとめ</h2>
<p>Kibanaの静的ファイルをelasticsearchの上にホストすることで、新たにWEBサーバを構築・管理しなくてよくなります。<br />
特に1台構成の開発環境などでは構成がシンプルになるので便利なのではないでしょうか!</p>
<h2>参考サイト</h2>
<ul>
<li>Elasticsearch Kibana でデータの可視化 — Hello! Elasticsearch. — Medium<br />
<a href="https://medium.com/hello-elasticsearch/elasticsearch-kibana-6ad80550939f">https://medium.com/hello-elasticsearch/elasticsearch-kibana-6ad80550939f</a></li>
</ul>
yoshi-ken
Fluentdのお勧めシステム構成パターンについて発表しました
hatenablog://entry/12921228815732641594
2014-09-12T12:04:22+09:00
2014-09-12T15:07:43+09:00 2014年9月9日開催の『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!にて発表してきました。 今回は「Fluentdのお勧めシステム構成パターン」というタイトルで、ユースケース毎にどのようなシステム構成をすると運用しやすいかのノウハウをお話しさせていただきました。 また、パネルディスカッションではラジオ番組のようなスタイルで、モデレータに @naoya_ito(伊藤直也氏)をお招きして行い、Kibana以前の可視化はどうしていたの?など、ざっくばらんなトークが出来てとても楽しい経験でした。
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140909/20140909195010.jpg" alt="f:id:yoshi-ken:20140909195010j:plain" title="f:id:yoshi-ken:20140909195010j:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>2014年9月9日開催の<a href="http://eventdots.jp/event/137658">『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!</a>にて発表してきました。</p>
<p>今回は「<a href="https://www.slideshare.net/y-ken/fluentd-system-design-pattern">Fluentdのお勧めシステム構成パターン</a>」というタイトルで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B9%A5%B1%A1%BC%A5%B9">ユースケース</a>毎にどのようなシステム構成をすると運用しやすいかのノウハウをお話しさせていただきました。</p>
<p>また、パネルディスカッションではラジオ番組のようなスタイルで、モデレータに @naoya_ito(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B0%CB%C6%A3%C4%BE%CC%E9">伊藤直也</a>氏)をお招きして行い、Kibana以前の可視化はどうしていたの?など、ざっくばらんなトークが出来てとても楽しい経験でした。</p>
<h2>発表資料</h2>
<p>今回は書籍に書かれた内容をざっとおさらいしつつ、システム構成パターンについて解説しました。<br />
発表資料は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Slideshare">Slideshare</a>にアップしております。</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/38996408?rel=0" width="597" height="486" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
<p> <div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/y-ken/fluentd-system-design-pattern" title="Fluentdのお勧めシステム構成パターン" target="_blank">Fluentdのお勧めシステム構成パターン</a> </strong> </div></p>
<h2>書籍</h2>
<p>本書は<a class="keyword" href="http://d.hatena.ne.jp/keyword/WEB%2BDB%20Press">WEB+DB Press</a>を取り扱う書店のほか、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>などから購入できます。
<div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/"><img src="http://ecx.images-amazon.com/images/I/51lSb2Ie7WL._SL160_.jpg" class="hatena-asin-detail-image" alt="サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)" title="サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/">サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%CE%EB%CC%DA%B7%F2%C2%C0">鈴木健太</a>,吉田健太郎,大谷純,道井俊介</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2014/08/08</li><li><span class="hatena-asin-detail-label">メディア:</span> 大型本</li><li><a href="http://d.hatena.ne.jp/asin/4774169838/y_ken_studio-22" target="_blank">この商品を含むブログを見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p>
<p>なお、インフラエンジニアだという執筆者は4人のうち1人ということもあり、本書に"インフラエンジニア養成読本"とありながら、案外アプリエンジニア(フロントエンジニア)向けの書籍です。</p>
<h2>謝辞</h2>
<p>会場提供していただいた<a class="keyword" href="http://d.hatena.ne.jp/keyword/GMO">GMO</a>のみなさま、主催のトレジャーデータ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a>のみなさま、そして聴きに来てくださった方々、ありがとうございました。</p>
<h2>他に参加された方の記事</h2>
<ul>
<li><p>サービス改善とログデータ解析について発表してきました - すずけんメモ<br />
<a href="http://suzuken.hatenablog.jp/entry/2014/09/11/210059">http://suzuken.hatenablog.jp/entry/2014/09/11/210059</a></p></li>
<li><p>『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編 出版記念!執筆者が語る大講演会!』 聴講メモ - べにやまぶろぐ<br />
<a href="http://beniyama.hatenablog.jp/entry/2014/09/10/001022">http://beniyama.hatenablog.jp/entry/2014/09/10/001022</a></p></li>
<li><p>サーバ・インフラエンジニア養成読本 ログ収集~可視化編 勉強会 - はやさがたりない。<br />
<a href="http://arika.hateblo.jp/entry/2014/09/12/001740">http://arika.hateblo.jp/entry/2014/09/12/001740</a></p></li>
<li><p>Kibanaではじめるダッシュボードについて発表してきました #gihyo_efk - BLOG::はるかさん<br />
<a href="http://blog.harukasan.jp/entry/2014/09/12/144217">http://blog.harukasan.jp/entry/2014/09/12/144217</a></p></li>
</ul>
yoshi-ken
Fluentd、Kibana、Elasticsearch本の電子書籍版が発売開始&Fluentdステッカーが購入特典で付録する都内某書店を紹介
hatenablog://entry/12921228815730747724
2014-08-20T12:00:00+09:00
2014-08-22T16:44:34+09:00 Fluentd、Kibana、Elasticsearchを大特集した本書は好評を集め、Amazonを始めとする大手書店でもベストセラー入りしております!
そんなログ収集から可視化を実現するためのノウハウが凝縮された本書は、フロントエンジニアの方にも大変おすすめです。
さらにいまなら、某書店では購入特典にFluentdステッカーが付いてきます!
その店舗を一部とはなりますが、こっそり紹介したいと思います♪
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140820/20140820111218.jpg" alt="f:id:yoshi-ken:20140820111218j:plain" title="f:id:yoshi-ken:20140820111218j:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>Fluentd、Kibana、Elasticsearchを大特集した本書は好評を集め、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>を始めとする大手書店でもベストセラー入りしております!<br />
そんなログ収集から可視化を実現するためのノウハウが凝縮された本書は、フロントエンジニアの方にも大変おすすめです。<br /></p>
<ul>
<li><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/ref=nosim/" name="amazletlink" target="_blank">サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)</a></li>
</ul>
<p>私は第2特集「ログ収集<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DF%A5%C9%A5%EB%A5%A6%A5%A7%A5%A2">ミドルウェア</a>Fluentd徹底攻略」を書き下ろしで担当しました。<br />
このノウハウを用いれば、手間のかかるログ収集をスマートに解決できることでしょう。</p>
<p>さらにいまなら、某書店では購入特典にFluentdステッカーが付いてきます!<br />
その店舗を一部とはなりますが、こっそり紹介したいと思います♪<br />
また、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%C5%BB%D2%BD%F1%C0%D2">電子書籍</a>版の発売も始まりましたので、記事末尾にて紹介します。</p>
<h2>Fluentdステッカーが購入特典に付く店舗</h2>
<p>次の書店をはじめとする都内大手書店にて、購入特典ステッカーが付録しています。<br />
もちろん、このFluentdステッカー特典には数に限りがあるため、8月中の購入がお勧めです!</p>
<ul>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%AA%B0%CB%D4%A2%B2%B0%BD%F1%C5%B9">紀伊國屋書店</a>新宿本店さま</li>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%AA%B0%CB%D4%A2%B2%B0%BD%F1%C5%B9">紀伊國屋書店</a>新宿南店さま</li>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%CD%AD%CE%D9%C6%B2">有隣堂</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E8%A5%C9%A5%D0%A5%B7">ヨドバシ</a>AKIBA店さま</li>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%F1%C0%F4%A5%D6%A5%C3%A5%AF%A5%BF%A5%EF%A1%BC">書泉ブックタワー</a>さま(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A9%CD%D5%B8%B6">秋葉原</a>)</li>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%E5%A5%F3%A5%AF%C6%B2">ジュンク堂</a>池袋本店</li>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%E5%A5%F3%A5%AF%C6%B2">ジュンク堂</a>渋谷店</li>
<li>あおい書店六本木店</li>
</ul>
<p>※ 随時更新中</p>
<p><blockquote class="twitter-tweet" lang="ja"><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%CD%AD%CE%D9%C6%B2">有隣堂</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E8%A5%C9%A5%D0%A5%B7">ヨドバシ</a>AKIBA店さま『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』PC書週間売上1位です!今ならfluentdステッカーが付いてます! <a href="http://t.co/oQfXuRMdV8">pic.twitter.com/oQfXuRMdV8</a></p>— 高屋 卓也 (@GHtakaya) <a href="https://twitter.com/GHtakaya/statuses/501637647178006528">2014, 8月 19</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%C5%BB%D2%BD%F1%C0%D2">電子書籍</a>版、発売開始</h2>
<p>ご要望が多かった、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%C5%BB%D2%BD%F1%C0%D2">電子書籍</a>版の発売を次のショップで開始しました。</p>
<ul>
<li><a href="https://gihyo.jp/dp/ebook/2014/978-4-7741-6698-8">Gihyo Digital Publishing</a>・・・書籍のレイアウトそのままのPDFが入手できます!</li>
<li><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00MPDUQQI/y_ken_studio-22/">Amazon Kindle版</a></li>
<li><a href="http://books.rakuten.co.jp/rk/6aa27cbb3de238588a1973b046aed636/">楽天Kobo</a></li>
</ul>
<h2>紙の書籍、送料無料</h2>
<p>紙の本も良いですよね。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%DA%C5%B7%A5%D6%A5%C3%A5%AF%A5%B9">楽天ブックス</a>では翌日自宅配送です!<br />
ただ物流の都合上、ステッカーの特典はございません。あしからず。</p>
<ul>
<li><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/">Amazon</a></li>
<li><a href="http://books.rakuten.co.jp/rb/12860790/">楽天ブックス</a></li>
<li><a href="http://www.honyaclub.com/shop/g/g16410892/">ホンヤクラブ</a></li>
<li><a href="http://www.7netshopping.jp/books/detail/-/accd/1106437631">セブンネットショッピング</a>なら近所の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BB%A5%D6%A5%F3%A5%A4%A5%EC%A5%D6%A5%F3">セブンイレブン</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%C8%A1%BC%A5%E8%A1%BC%A5%AB%A5%C9%A1%BC">イトーヨーカドー</a>で受け取れます</li>
</ul>
<p>最寄り書店に取り扱いがない場合には、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%F3%A5%E9%A5%A4%A5%F3%BD%F1%C5%B9">オンライン書店</a>よりお求めください。</p>
<p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/"><img src="http://ecx.images-amazon.com/images/I/51lSb2Ie7WL._SL160_.jpg" class="hatena-asin-detail-image" alt="サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)" title="サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/">サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%CE%EB%CC%DA%B7%F2%C2%C0">鈴木健太</a>,吉田健太郎,大谷純,道井俊介</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2014/08/08</li><li><span class="hatena-asin-detail-label">メディア:</span> 大型本</li><li><a href="http://d.hatena.ne.jp/asin/4774169838/y_ken_studio-22" target="_blank">この商品を含むブログを見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p>
<h2>まとめ</h2>
<p>ようやく<a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>の書籍在庫も安定し、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%C5%BB%D2%BD%F1%C0%D2">電子書籍</a>版も発売となりました!<br />
編集の高屋さまを始めとする執筆関係者の皆様、ありがとうございました。<br />
本書を通じて、多くの方の役に立てれば幸いです。</p>
yoshi-ken
ログ収集や可視化で話題のFluentd、Elasticsearch、Kibanaを徹底解説したムック本が発売となります
hatenablog://entry/12921228815728836679
2014-07-28T09:58:34+09:00
2014-08-12T14:55:52+09:00 2014年8月8日、ログ収集や可視化を始めたいエンジニア必携の書籍が技術評論社より刊行されます。 本邦初公開となる、全編書き下ろしの特集で構成された本書を読むことで、ログ解析の有用性からログ収集、保存、可視化手法を習得できます。 私はこの第2特集「ログ収集ミドルウェアFluentd徹底攻略」の執筆を担当しました。 サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus) それでは、それぞれの特集について簡単に紹介したいと思います。
<p><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/61vwvFp6EEL._SL160_.jpg" alt="サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)" style="border: none;" /></a></p>
<p>2014年8月8日、ログ収集や可視化を始めたいエンジニア必携の書籍が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a>より刊行されます。<br />
本邦初公開となる、全編書き下ろしの特集で構成された本書を読むことで、ログ解析の有用性からログ収集、保存、可視化手法を習得できます。<br />
私はこの第2特集「ログ収集<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DF%A5%C9%A5%EB%A5%A6%A5%A7%A5%A2">ミドルウェア</a>Fluentd徹底攻略」の執筆を担当しました。</p>
<ul>
<li><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/ref=nosim/" name="amazletlink" target="_blank">サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)</a></li>
</ul>
<p>それでは、それぞれの特集について簡単に紹介したいと思います。</p>
<h3>サーバ/インフラエンジニア養成読本 ログ収集〜可視化編</h3>
<h4><strong>特集1</strong> ログ解析からはじめるサービス改善 (鈴木 健太)</h4>
<p>第1特集では、ログを蓄積して解析する意義とは何か、コーヒーショップの<a class="keyword" href="http://d.hatena.ne.jp/keyword/EC%A5%B5%A5%A4%A5%C8">ECサイト</a>を例に、データ分析の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B1%A1%BC%A5%B9%A5%B9%A5%BF%A5%C7%A5%A3">ケーススタディ</a>と共に解説されています。</p>
<ul>
<li>第1章 はじめに</li>
<li>第2章 サービス改善に必要なこと</li>
<li>第3章 なぜ今可視化なのか</li>
<li>第4章 ログデータ入門</li>
<li>第5章 はじめてのFluentd、Elasticsearch、Kibana</li>
<li>第6章 ElasticsearchとKibanaを超えて</li>
<li>第7章 まとめと参考文献</li>
</ul>
<h4><strong>特集2</strong> ログ収集<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DF%A5%C9%A5%EB%A5%A6%A5%A7%A5%A2">ミドルウェア</a>Fluentd徹底攻略 (吉田 健太郎)</h4>
<p>第2特集では、Fluentdを実践運用する上では欠かせない設定ファイルの書き方や概念、ノード構成パターンを解説した後に、運用・監視ノウハウについて解説しています。<br />
そして第5章には「逆引きFluentd<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>集」が収録されています。Fluentd<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は数多く公開されていますが、利用したい機能ジャンル毎にどのような<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>があるのか、そしてそれがどのような機能を持つのかまとまった情報がありませんでした。本書では、250以上に及ぶ主要<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>をジャンル毎に解説しています。この逆引き<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>集のためだけでも本書を購入する価値はあるのではないでしょうか。</p>
<ul>
<li>第1章 ログ収集の目的と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DF%A5%C9%A5%EB%A5%A6%A5%A7%A5%A2">ミドルウェア</a>の特徴</li>
<li>第2章 はじめてみようFluentd</li>
<li>第3章 Fluentd設計のコツ</li>
<li>第4章 Fluentd運用ノウハウ</li>
<li>第5章 逆引きFluentd<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a></li>
</ul>
<h4><strong>特集3</strong> Elasticsearch入門 (大谷 純)</h4>
<p>第3特集では、NoSQLデータベースであるElasticsearchの基礎から応用までを幅広く解説しています。これから使い始める方にも既に運用中の方にもお勧めな内容となっています。<br />
また、Kibanaと共に利用する際の運用方法や、Elasticsearchと<a class="keyword" href="http://d.hatena.ne.jp/keyword/Hadoop">Hadoop</a>を組み合わせて検索基盤を作る<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の利用ガイドなども充実しています。</p>
<ul>
<li>第1章 データストア入門</li>
<li>第2章 Elasticsearchの基礎</li>
<li>第3章 Elasticsearchのはじめ方</li>
<li>第4章 運用TIPS</li>
<li>第5章 インデックス管理<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>と厳選<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a></li>
<li>第6章 elasticsearch-<a class="keyword" href="http://d.hatena.ne.jp/keyword/hadoop">hadoop</a></li>
</ul>
<h4><strong>特集4</strong> 可視化<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>Kibanaスタートガイド (道井 俊介)</h4>
<p>第4特集では、ログ検索結果を元にしたデータの可視化を行うダッシュボード<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>“Kibana”を用いたログの検索や、可視化を行う機能をフルカラーで一通り紹介しています。<br />
Kibanaには様々なパネルや機能があるので、これから使おうとしている方にも、既に使ったことのある方にも新しい発見があることでしょう。</p>
<ul>
<li>第1章 Kibanaの基礎知識</li>
<li>第2章 インストールと設定</li>
<li>第3章 ダッシュボードとパネルの操作</li>
<li>第4章 データのフィルタリング</li>
<li>第5章 基本的なパネル</li>
<li>第6章 パネルのスタイルとダッシュボードの運用</li>
<li>第7章 Fluentdによるデータ入力</li>
</ul>
<h3>まとめ</h3>
<p>実際にプロダクション環境での運用も進みつつある<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>(Elasticsearch)、ログ収集(Fluentd)や可視化(Kibana)という人気構成<a href="#f-81fbab0c" name="fn-81fbab0c" title="これらを総称してEFK構成や、EFKスタックと呼ぶ。Elasticsearch、Fluentd、Kibanaの頭文字を取ったもの">*1</a>を、それぞれの観点から詳細に解説した初の書籍ではないでしょうか。<br />
もちろん本書はFluentdを手堅く使いこなしたいという方にも満足できるでしょうし、ElasticsearchとFluentd、Kibanaを組み合わせたログ解析基盤の構築と運用に関心のある方にも大変オススメです。<br />
実践運用しているエンジニアによるノウハウがこれだけ満載されて2,138円とは、とてもお買い得ですね。</p>
<p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/"><img src="http://ecx.images-amazon.com/images/I/51lSb2Ie7WL._SL160_.jpg" class="hatena-asin-detail-image" alt="サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)" title="サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774169838/y_ken_studio-22/">サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%CE%EB%CC%DA%B7%F2%C2%C0">鈴木健太</a>,吉田健太郎,大谷純,道井俊介</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2014/08/08</li><li><span class="hatena-asin-detail-label">メディア:</span> 大型本</li><li><a href="http://d.hatena.ne.jp/asin/4774169838/y_ken_studio-22" target="_blank">この商品を含むブログを見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>にて在庫切れの場合は、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%DA%C5%B7%A5%D6%A5%C3%A5%AF%A5%B9">楽天ブックス</a>からも購入できます<br />
<a href="http://books.rakuten.co.jp/rb/12860790/">http://books.rakuten.co.jp/rb/12860790/</a></p>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%C5%BB%D2%BD%F1%C0%D2">電子書籍</a>版(PDF)は"Gihyo Digital Publishing"より購入できます<br />
<a href="https://gihyo.jp/dp/ebook/2014/978-4-7741-6698-8">https://gihyo.jp/dp/ebook/2014/978-4-7741-6698-8</a></p>
<h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%A2%A4%EF%A4%BB%A4%C6%C6%C9%A4%DF%A4%BF%A4%A4">あわせて読みたい</a></h3>
<ul>
<li><p>サーバ/インフラエンジニア養成読本 ログ収集~可視化編 を書きました - すずけんメモ<br />
<a href="http://suzuken.hatenablog.jp/entry/2014/07/18/084555">http://suzuken.hatenablog.jp/entry/2014/07/18/084555</a></p></li>
<li><p>書きました: サーバ/インフラエンジニア養成読本 ログ収集~可視化編 - BLOG.harukasan<br />
<a href="http://blog.harukasan.jp/entry/2014/07/18/180351">http://blog.harukasan.jp/entry/2014/07/18/180351</a></p></li>
</ul>
<h3>変更履歴</h3>
<p>2014年8月12日:<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%C5%BB%D2%BD%F1%C0%D2">電子書籍</a>版の購入リンクを追加</p>
<div class="footnote">
<p class="footnote"><a href="#fn-81fbab0c" name="f-81fbab0c" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">これらを総称してEFK構成や、EFKスタックと呼ぶ。Elasticsearch、Fluentd、Kibanaの頭文字を取ったもの</span></p>
</div>
yoshi-ken
SoftBank携帯とnet.ipv4.tcp_tw_recycle=1の相性が悪い本当の理由
hatenablog://entry/12921228815726275286
2014-06-17T11:52:14+09:00
2014-06-20T16:02:09+09:00 photo by saschaaa LinuxにおいてTIME_WAITなコネクションを減らす手法としてnet.ipv4.tcp_tw_recycle=1にするテクニックは有名です。 しかし環境によってはSoftBankに限らず問題が起きるため、利用には注意が必要です。 一体どのような問題が起きるのか、詳細に解説されたブログを見つけたので紹介します。
<p><a href="http://www.flickr.com/photos/69697083@N00/152502539"><img src="http://farm1.staticflickr.com/51/152502539_c4cb9121eb.jpg" alt="" /></a></p>
<p><a href="http://www.flickr.com/photos/69697083@N00/152502539">photo by saschaaa</a></p>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>においてTIME_WAITなコネクションを減らす手法として<code>net.ipv4.tcp_tw_recycle=1</code>にするテクニックは有名です。<br />
しかし環境によっては<a class="keyword" href="http://d.hatena.ne.jp/keyword/SoftBank">SoftBank</a>に限らず問題が起きるため、利用には注意が必要です。</p>
<p>一体どのような問題が起きるのか、詳細に解説されたブログを見つけたので紹介します。</p>
<h2>検証記事</h2>
<h4>記事1</h4>
<p><a href="http://oopsops.hatenablog.com/entry/2012/03/29/202433">kernel: TCP: time wait bucket table overflow の解消とTIME_WAITを減らすチューニング</a>という記事では次の言及がされています。(抜粋)<br /></p>
<blockquote>
サーバ側で net.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ipv4">ipv4</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/tcp">tcp</a>_tw_recycle が有効で、クライアント側で<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>のタイムスタンプオプションが有効(<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>の場合net.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ipv4">ipv4</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/tcp">tcp</a>_timestamps = 1)だと、NAT/LBを超えたときにSYNを落としてしまい、接続障害になる。<br />
ユーザー向けに使っているとSB携帯などで障害が発生してしまうようなので、使わないほうがいいかも。
</blockquote>
<ul>
<li>引用元 : <a href="http://oopsops.hatenablog.com/entry/2012/03/29/202433">http://oopsops.hatenablog.com/entry/2012/03/29/202433</a></li>
</ul>
<h4>記事2</h4>
<p>net.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ipv4">ipv4</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/tcp">tcp</a>_tw_recycleを有効にしたことでのトラブル事例として、次の言及がされています。(抜粋)</p>
<blockquote>
いくつかの回避手段を以下に。
<li>サーバ側で net.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ipv4">ipv4</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/tcp">tcp</a>_tw_recycle を無効にする</li>
<ul>
<li>すべての元凶
<li>どうやら <a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a> の独自機能で、ほかの OS ではやってないようだ<br />
<li>man の <a href="http://linuxjm.sourceforge.jp/html/LDP_man-pages/man7/tcp.7.html">tcp(7)</a>によるとデフォルト無効でそれが推奨設定なのに、 <a href="http://linuxjf.sourceforge.jp/JFdocs/Adv-Routing-HOWTO/lartc.kernel.obscure.html">HOWTO</a>によるとデフォルト有効で「専門技術者のアドバイスか要求がなければ、変更すべきではありません」という素敵な矛盾。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%B7%A5%E7%A5%F3">ディストリビューション</a>によっても違うかもしれんし、ほんとのデフォルトがどっちかは知らん。
</ul>
</li>
</blockquote>
<ul>
<li>引用元 : <a href="http://ya.maya.st/d/200804c.html#s20080430_2">http://ya.maya.st/d/200804c.html#s20080430_2</a></li>
</ul>
<h4>記事3</h4>
<p>kernelの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>と共にその現象が起きる理由を詳細に解説されています。(抜粋)</p>
<blockquote>
今回問題になっていたのは最後の<a class="keyword" href="http://d.hatena.ne.jp/keyword/tcp">tcp</a>_tw_recycleへの抵触だった。<br />
<br />
現象として発生しうるのは、以下の条件をすべて満たす場合<br />
<ul>
<li>サーバ側でnet.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ipv4">ipv4</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/tcp">tcp</a>_tw_recycleが有効
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>タイムスタンプオプションを使用
<li>同一IPからの接続でセッションを跨ぐとセットされる<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>タイムスタンプの値が戻る場合がある</ul>
<br />
最後の条件が微妙だが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>タイムスタンプの値としてセットされる値は起動時を起算時にしていたりと実装によって初期値は異なり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%A3%BF%F4">複数</a>台のホストの場合は同一OSで全く同一タイミングで起動したりしない限りまず一致しない。<br />
そのため、<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>タイムスタンプオプションのフィールドを書き換えないNATやロードバランサ経由の接続の場合、セッションを跨ぐとセットされる値の増加が保証されない。
</blockquote>
<ul>
<li>引用元 : <a href="http://d.hatena.ne.jp/nice20/20070521#p1">http://d.hatena.ne.jp/nice20/20070521#p1</a></li>
</ul>
<h2>まとめ</h2>
<p>様々な記事で<a class="keyword" href="http://d.hatena.ne.jp/keyword/tcp">tcp</a>_tw_recycleを1にするノウハウが紹介されています。<br />
しかし<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>ではRFC1323での想定とは異なる箇所にtimestamp optionを実装しているため、利用には注意が必要ですね。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>同士であれば使えるシーンもあるとは思いますが、特に外向きWebサーバでは<code>net.ipv4.tcp_tw_recycle=1</code>を使わない方が堅実です。</p>
<h2>補足</h2>
<p>fluentdのインストールマニュアル「ネットワーク関係の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AB%A1%BC%A5%CD%A5%EB">カーネル</a>パラメータの最適化」にて、このパラメータを推奨する記載もありますが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>以外と通信を行うサーバにはこのパラメータを設定しない方が良さそうだと思います。</p>
<ul>
<li>Fluentdインストールの前に | Fluentd<br />
<a href="http://docs.fluentd.org/ja/articles/before-install">http://docs.fluentd.org/ja/articles/before-install</a></li>
</ul>
yoshi-ken
5分あれば出来る、Muninでelasticsearch 1.xのリソース監視を行う方法
hatenablog://entry/12921228815722573432
2014-04-24T11:55:56+09:00
2015-01-21T14:19:49+09:00 JVMで動くelasticsearchを安定運用させるにはリソース監視も欠かせません。 今回は手軽なリソース監視が出来るMuninを用いて、インストール方法から作られるグラフサンプルの紹介まで行います。 利用プラグイン elasticsearch 1.x系で動くプラグインは現状これ1つのみです。Perlで書かれているため外部依存無しで動きます。 y-ken/munin-plugin-elasticsearch A useful Munin plugin for monitoring elasticsearch 1.x nodes in Perl. https://github.com/y-ke…
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/JVM">JVM</a>で動くelasticsearchを安定運用させるにはリソース監視も欠かせません。<br />
今回は手軽なリソース監視が出来るMuninを用いて、インストール方法から作られるグラフサンプルの紹介まで行います。</p>
<h2>利用<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a></h2>
<p>elasticsearch 1.x系で動く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は現状これ1つのみです。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Perl">Perl</a>で書かれているため外部依存無しで動きます。</p>
<ul>
<li>y-ken/munin-plugin-elasticsearch <iframe src="http://ghbtns.com/github-btn.html?user=y-ken&repo=munin-plugin-elasticsearch&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe><br />
A useful Munin plugin for monitoring elasticsearch 1.x nodes in <a class="keyword" href="http://d.hatena.ne.jp/keyword/Perl">Perl</a>.<br />
<a href="https://github.com/y-ken/munin-plugin-elasticsearch">https://github.com/y-ken/munin-plugin-elasticsearch</a></li>
</ul>
<p>次の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>が同封されています。</p>
<ul>
<li>elasticsearch_cache - フィールドとフィルタのキャッシュ状況</li>
<li>elasticsearch_cluster_shards - <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF">クラスタ</a>のシャード状況</li>
<li>elasticsearch_docs - 格納されているドキュメントの数</li>
<li>elasticsearch_<a class="keyword" href="http://d.hatena.ne.jp/keyword/gc">gc</a>_time - <a class="keyword" href="http://d.hatena.ne.jp/keyword/GC">GC</a>する際に掛かった時間</li>
<li>elasticsearch_index_size - インデックスのサイズ</li>
<li>elasticsearch_index_total - インデックスの総数</li>
<li>elasticsearch_<a class="keyword" href="http://d.hatena.ne.jp/keyword/jvm">jvm</a>_memory - <a class="keyword" href="http://d.hatena.ne.jp/keyword/JVM">JVM</a> ヒープ状況</li>
<li>elasticsearch_<a class="keyword" href="http://d.hatena.ne.jp/keyword/jvm">jvm</a>_pool_size - <a class="keyword" href="http://d.hatena.ne.jp/keyword/JVM">JVM</a> プールサイズ状況</li>
<li>elasticsearch_<a class="keyword" href="http://d.hatena.ne.jp/keyword/jvm">jvm</a>_threads - <a class="keyword" href="http://d.hatena.ne.jp/keyword/JVM">JVM</a> スレッド状況</li>
<li>elasticsearch_open_files - 開いているファイル数の数</li>
</ul>
<h2>環境</h2>
<ul>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/CentOS">CentOS</a> 6.5 (64bit)</li>
<li>elasticsearch 1.1.1 および 1.4.2</li>
<li>Munin 2.0.12 (munin-node-2.0.12-2.el6)</li>
</ul>
<h2>インストール</h2>
<p>次の手順にてインストールします。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># /usr/local/src/ディレクトリにリポジトリをクローン</span>
$ <span class="synStatement">cd</span> /usr/<span class="synStatement">local</span>/src/
$ sudo git clone https://github.com/y-ken/munin-plugin-elasticsearch.git
<span class="synComment"># クローン下リポジトリに同封されているプラグインをmuninのプラグインディレクトリへコピー</span>
$ <span class="synStatement">cd</span> munin-plugin-elasticsearch
$ sudo cp <span class="synSpecial">-p</span> elasticsearch_* /usr/share/munin/plugins/
<span class="synComment"># 既存プラグインと同様に、シンボリックリンクを作成</span>
$ sudo ln <span class="synSpecial">-s</span> /usr/share/munin/plugins/elasticsearch_* /etc/munin/plugins/
<span class="synComment"># munin-node-configureコマンドを用いてプラグインの適応テストと自動登録を行う</span>
$ sudo <span class="synSpecial">-H</span> munin-node-configure <span class="synSpecial">--shell</span> | <span class="synStatement">grep</span> elasticsearch | sudo <span class="synSpecial">-H</span> sh
</pre>
<h2>設定</h2>
<p>標準では <a class="keyword" href="http://d.hatena.ne.jp/keyword/localhost">localhost</a>:9200 で動くelasticsearchへ接続してメトリクス収集を行います。
もし別IPやportを対象に監視を行う場合には、<code>env.host</code>や<code>env.port</code>設定を書きます。</p>
<pre class="code" data-lang="" data-unlink>[elasticsearch_*]
env.host localhost
env.port 9200</pre>
<p>次のいずれかのファイルに設定を書き込みます。</p>
<ul>
<li>既存ファイル <code>/etc/munin/plugin-conf.d/munin-node</code> へ追記</li>
<li>新規ファイル <code>/etc/munin/plugin-conf.d/elasticsearch</code> を作成</li>
</ul>
<p>最後にMuninのclientデーモンを再起動すれば完了です。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ sudo service munin-node <span class="synStatement">restart</span>
</pre>
<p>しばらくすると、ブラウザでアクセスする"Munin overview"の画面にこのように現れます。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140424/20140424100242.png" alt="f:id:yoshi-ken:20140424100242p:plain" title="f:id:yoshi-ken:20140424100242p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<h2>グラフ</h2>
<p>次に、この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>をインストールすることで可視化される<a class="keyword" href="http://d.hatena.ne.jp/keyword/RRDtool">RRDtool</a>グラフを紹介します。
毎日深夜にドキュメントが大幅に減るのは、logstashインデックス形式で格納している、とある実験データを日次で削除しているためです。</p>
<ul>
<li>elasticsearch_cache</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140424/20140424094448.png" alt="f:id:yoshi-ken:20140424094448p:plain" title="f:id:yoshi-ken:20140424094448p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<ul>
<li>elasticsearch_cluster_shards</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140424/20140424094449.png" alt="f:id:yoshi-ken:20140424094449p:plain" title="f:id:yoshi-ken:20140424094449p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<ul>
<li>elasticsearch_index_size</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140424/20140424094451.png" alt="f:id:yoshi-ken:20140424094451p:plain" title="f:id:yoshi-ken:20140424094451p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<ul>
<li>elasticsearch_docs</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140424/20140424094450.png" alt="f:id:yoshi-ken:20140424094450p:plain" title="f:id:yoshi-ken:20140424094450p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<ul>
<li>elasticsearch_<a class="keyword" href="http://d.hatena.ne.jp/keyword/jvm">jvm</a>_memory</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140424/20140424094453.png" alt="f:id:yoshi-ken:20140424094453p:plain" title="f:id:yoshi-ken:20140424094453p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<ul>
<li>elasticsearch_index_total</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140424/20140424094452.png" alt="f:id:yoshi-ken:20140424094452p:plain" title="f:id:yoshi-ken:20140424094452p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<ul>
<li>elasticsearch_<a class="keyword" href="http://d.hatena.ne.jp/keyword/jvm">jvm</a>_threads</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140424/20140424094454.png" alt="f:id:yoshi-ken:20140424094454p:plain" title="f:id:yoshi-ken:20140424094454p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<ul>
<li>elasticsearch_open_files</li>
</ul>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140424/20140424114153.png" alt="f:id:yoshi-ken:20140424114153p:plain" title="f:id:yoshi-ken:20140424114153p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<h2>まとめ</h2>
<p>elasticsearchは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>のため<a class="keyword" href="http://d.hatena.ne.jp/keyword/JVM">JVM</a>監視はもちろんのこと、これらのリソース監視を始めた上で運用したいですね。<br />
余裕があればさらに、処理に時間の掛かったスロークエリ量の可視化も行うと良いでしょう。それについては今後紹介したいと思います。</p>
<h2>更新履歴</h2>
<ul>
<li>2015年1月21日 : 設定無しに使えるようになったため、インストール手順を更新</li>
</ul>
yoshi-ken
プロキシを使わずにRuby-1.9/2.1混在環境も作れる、Apache2+Passenger4+rbenvを用いた混在環境の作り方
hatenablog://entry/12921228815722155988
2014-04-17T15:45:23+09:00
2014-04-17T16:04:48+09:00 Passenger 3.x で複数のRubyバージョンを使い分けるには、とてもトリッキーな対応が必要でした。 ところがPassenger 4.0.0 より公式に複数のRubyバージョンに対応しました。つまり、同一筐体のApacheで動く他アプリケーションへ影響を与えることなく、気軽にアプリ毎に使うRubyバージョンを変更できるようになります。
<p>Passenger 3.x で複数の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>バージョンを使い分けるには、とてもトリッキーな対応が必要でした。<br />
ところがPassenger 4.0.0 より公式に複数の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>バージョンに対応しました。つまり、同一筐体の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apache">Apache</a>で動く他アプリケーションへ影響を与えることなく、気軽にアプリ毎に使う<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>バージョンを変更できるようになります。</p>
<h2>これまでの手法</h2>
<p>mod_proxyを用いて、必要な<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>バージョン毎に単体起動させたpassengerに<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP">TCP</a>/Socketでプロキシするというものでした。なぜなら、読み込むモジュールだけでなく、グローバル値として指定する<code>PassengerRoot</code>や<code>PassengerRuby</code>の設定が衝突するためです。</p>
<ul>
<li>Phusion Passenger & running multiple <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> versions – Phusion Corporate Blog<br />
<a href="http://blog.phusion.nl/2010/09/21/phusion-passenger-running-multiple-ruby-versions/">http://blog.phusion.nl/2010/09/21/phusion-passenger-running-multiple-ruby-versions/</a></li>
</ul>
<h2>これからの手法</h2>
<p><a href="http://blog.phusion.nl/2012/10/24/phusion-passenger-4-0-beta-1-is-here/">Phusion Passenger 4.0 beta 1 is here – Phusion Corporate Blog</a>にて、次のように言及されています。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140417/20140417134331_original.png" alt="f:id:yoshi-ken:20140417134331p:plain" title="f:id:yoshi-ken:20140417134331p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>Passenger 4.0.0 よりモジュール本体と<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>との依存が無くなり、複数の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>バージョンおよび<a class="keyword" href="http://d.hatena.ne.jp/keyword/JRuby">JRuby</a>に対応しました。新しく追加されたオプション<code>PassengerDefaultRuby</code>がグローバル値として適用され、<code>PassengerRuby</code>をアプリケーション毎など、個別に指定できるようになりました。<br />
これらはVirtualHost、Directory、Locationと<a class="keyword" href="http://d.hatena.ne.jp/keyword/.htaccess">.htaccess</a>といったどのディレクティブでも設定できます。</p>
<h2>使い方</h2>
<p>これよりVirtualHosts毎に別の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>でアプリケーションを動かすサンプルを紹介します。</p>
<h4>step1. rbenvのインストール</h4>
<p>公式ドキュメントを参考にインストールします<br />
<a href="https://github.com/sstephenson/rbenv#installation">https://github.com/sstephenson/rbenv#installation</a></p>
<h4>step2. passengerのインストール</h4>
<p>rbenvで切り替えた各<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>にてそれぞれインストールを行います。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># rootで実行</span>
gem <span class="synStatement">install</span> passenger
passenger-<span class="synStatement">install</span>-apache2-module
</pre>
<h4>step3. <a class="keyword" href="http://d.hatena.ne.jp/keyword/Apache">Apache</a>へ設定ファイルを投入</h4>
<p>少なくとも3つの設定(LoadModule, PassengerRoot, PassengerDefaultRuby)を次のいずれかのファイルに書き込みます。
LoadModuleで指定できる.soファイルは、各バージョンの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>にて実行したgem install passengerでインストールされた場所に存在します。しかしどうやら、どちらの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>にインストールされたものを指定しても構わないようです。</p>
<ul>
<li>/etc/<a class="keyword" href="http://d.hatena.ne.jp/keyword/httpd">httpd</a>/conf/<a class="keyword" href="http://d.hatena.ne.jp/keyword/httpd">httpd</a>.conf または /etc/<a class="keyword" href="http://d.hatena.ne.jp/keyword/httpd">httpd</a>.d/conf/passenger.conf</li>
</ul>
<pre class="code lang-xml" data-lang="xml" data-unlink>$ cat /etc/httpd.d/conf/passenger.conf
LoadModule passenger_module /root/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/passenger-4.0.41/buildout/apache2/mod_passenger.so
<span class="synIdentifier"><IfModule </span><span class="synType">mod_passenger</span><span class="synIdentifier">.c></span>
PassengerRoot /root/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/passenger-4.0.41
PassengerDefaultRuby /root/.rbenv/versions/2.1.1/bin/ruby
<span class="synIdentifier"></IfModule></span>
Header always unset "X-Powered-By"
Header always unset "X-Rack-Cache"
Header always unset "X-Content-Digest"
</pre>
<p>次に、VIrtualHostの設定を行う準備を行います。<br />
各アプリケーションに<code>PassengerRuby</code>オプションを用いて<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>バイナリの位置を指定します。この値はrbenvコマンドで使う<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>バージョンに切り替えた後に、<code>passenger-config about ruby-command</code>コマンドを叩くと次のように分かります。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>passenger-config about ruby-command
passenger-config was invoked through the following Ruby interpreter:
Command: /root/.rbenv/versions/<span class="synConstant">1</span>.<span class="synConstant">9</span>.<span class="synConstant">3</span>-p545/bin/ruby
Version: ruby <span class="synConstant">1</span>.<span class="synConstant">9</span>.3p545 <span class="synPreProc">(</span><span class="synConstant">2014-02-24</span><span class="synSpecial"> revision </span><span class="synConstant">45159</span><span class="synPreProc">)</span> <span class="synStatement">[</span>x86_64-linux<span class="synStatement">]</span>
To use <span class="synError">in</span> Apache: PassengerRuby /root/.rbenv/versions/<span class="synConstant">1</span>.<span class="synConstant">9</span>.<span class="synConstant">3</span>-p545/bin/ruby
To use <span class="synError">in</span> Nginx : passenger_ruby /root/.rbenv/versions/<span class="synConstant">1</span>.<span class="synConstant">9</span>.<span class="synConstant">3</span>-p545/bin/ruby
To use with Standalone: /root/.rbenv/versions/<span class="synConstant">1</span>.<span class="synConstant">9</span>.<span class="synConstant">3</span>-p545/bin/ruby /root/.rbenv/versions/<span class="synConstant">1</span>.<span class="synConstant">9</span>.<span class="synConstant">3</span>-p545/lib/ruby/gems/<span class="synConstant">1</span>.<span class="synConstant">9</span>.<span class="synConstant">1</span>/gems/passenger<span class="synConstant">-4</span>.<span class="synConstant">0</span>.<span class="synConstant">41</span>/bin/passenger <span class="synStatement">start</span>
</pre>
<p>それぞれ調べた値をvirtualhost設定へ<code>PassengerRuby</code>オプションと共に指定します。</p>
<pre class="code lang-xml" data-lang="xml" data-unlink>$ cat /etc/httpd.d/conf/virtualhosts.conf
NameVirtualHost *:80
<span class="synIdentifier"><VirtualHost *:80></span>
ServerName ruby19.example.jp
DocumentRoot /var/www/ruby19.example.jp/public
<span class="synIdentifier"><Directory /</span><span class="synType">var</span><span class="synIdentifier">/</span><span class="synType">www</span><span class="synIdentifier">/</span><span class="synType">ruby19</span><span class="synComment">.</span><span class="synType">example</span><span class="synComment">.</span><span class="synType">jp</span><span class="synIdentifier">/public></span>
# This relaxes Apache security settings.
AllowOverride all
# MultiViews must be turned off.
Options -MultiViews
<span class="synIdentifier"></Directory></span>
AllowEncodedSlashes on
PassengerAllowEncodedSlashes on
# ruby19.example.jp では Ruby 1.9.3-p545 を利用する
PassengerRuby /root/.rbenv/versions/1.9.3-p545/bin/ruby
LimitRequestBody 41943040
<span class="synIdentifier"></VirtualHost></span>
<span class="synIdentifier"><VirtualHost *:80></span>
ServerName ruby21.example.jp
DocumentRoot /var/www/ruby21.example.jp/public
<span class="synIdentifier"><Directory /</span><span class="synType">var</span><span class="synIdentifier">/</span><span class="synType">www</span><span class="synIdentifier">/</span><span class="synType">ruby21</span><span class="synComment">.</span><span class="synType">example</span><span class="synComment">.</span><span class="synType">jp</span><span class="synIdentifier">/public></span>
# This relaxes Apache security settings.
AllowOverride all
# MultiViews must be turned off.
Options -MultiViews
<span class="synIdentifier"></Directory></span>
AllowEncodedSlashes on
PassengerAllowEncodedSlashes on
# ruby21.example.jp では Ruby 2.1.1 を利用する
PassengerRuby /root/.rbenv/versions/2.1.1/bin/ruby
LimitRequestBody 41943040
<span class="synIdentifier"></VirtualHost></span>
</pre>
<h4>step4. 設定の反映</h4>
<p>設定を反映させるため、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apache">Apache</a>を再起動します。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># rootで実行</span>
/etc/init.d/httpd <span class="synStatement">restart</span>
</pre>
<p>これで以上です。<br />
トリッキーな対応無しに複数バージョンの使い分けが出来るようになりましたね。</p>
<h4>手元の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vagrant">Vagrant</a>でも試せます</h4>
<p>本記事で紹介した環境を配布しています。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Virtualbox">Virtualbox</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vagrant">Vagrant</a>が入っている環境であれば、次の手順で試せます。
具体的な構築手順については、<a href="https://github.com/y-ken/multiple_ruby_version_in_apache_passenger/blob/master/provision.sh">provision.sh</a>ファイルをご覧ください。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ git clone https://github.com/y-ken/multiple_ruby_version_in_apache_passenger.git
$ <span class="synStatement">cd</span> multiple_ruby_version_in_apache_passenger
$ vagrant up
$ vagrant ssh
</pre>
<ul>
<li>Sample <a class="keyword" href="http://d.hatena.ne.jp/keyword/vagrant">vagrant</a> image to execute multiple versions of <a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a> in one <a class="keyword" href="http://d.hatena.ne.jp/keyword/Apache">Apache</a> Passenger<br />
<a href="https://github.com/y-ken/multiple_ruby_version_in_apache_passenger">https://github.com/y-ken/multiple_ruby_version_in_apache_passenger</a> <iframe src="http://ghbtns.com/github-btn.html?user=y-ken&repo=multiple_ruby_version_in_apache_passenger&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe></li>
</ul>
<p>構築完了後にはその端末へ<code>vagrant ssh</code>コマンドでログインし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/curl">curl</a>コマンドでサンプルアプリを叩いて結果を見てみましょう。<br />
ruby19.example.jp では<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>-1.9.3-p545が、ruby21.example.jp では<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>-2.1.1が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%BF%A5%D7%A5%EA%A5%BF">インタプリタ</a>として動いていることが確認できます。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ curl <span class="synSpecial">-s</span> <span class="synSpecial">-H</span> <span class="synStatement">"</span><span class="synConstant">Host: ruby19.example.jp</span><span class="synStatement">"</span> http://<span class="synConstant">127</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.<span class="synConstant">1</span>/ | <span class="synStatement">grep</span> exec_prefix
<span class="synStatement">"</span><span class="synConstant">exec_prefix</span><span class="synStatement">"=>"</span><span class="synConstant">/root/.rbenv/versions/1.9.3-p545</span><span class="synStatement">"</span>,
$ curl <span class="synSpecial">-s</span> <span class="synSpecial">-H</span> <span class="synStatement">"</span><span class="synConstant">Host: ruby21.example.jp</span><span class="synStatement">"</span> http://<span class="synConstant">127</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.<span class="synConstant">1</span>/ | <span class="synStatement">grep</span> exec_prefix
<span class="synStatement">"</span><span class="synConstant">exec_prefix</span><span class="synStatement">"=>"</span><span class="synConstant">/root/.rbenv/versions/2.1.1</span><span class="synStatement">"</span>,
</pre>
<h2>まとめ</h2>
<p>これでサーバ構成のシンプルさや運用の手間を抑えたまま、年に何度もにリリースされる最新の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>バージョンでも受け入れられるインフラが作れます。<br />
古いバージョンが必要なアプリケーションはそのままに、どんどん最新の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>を追いかけていけますね!</p>
yoshi-ken
MySQLからelasticsearchへ、レコードをネスト構造化しつつ同期出来る fluent-plugin-mysql-replicator v0.4.0 を公開しました
hatenablog://entry/12921228815721571078
2014-04-08T16:42:32+09:00
2014-04-14T15:14:32+09:00 elasticsearchは全文検索サーバとしても知名度を獲得しており、次のような記事も人気を集めています。 elasticsearchを全文検索サーバとして活用するなら読んでおきたい、6つのブログ記事をピックアップ - Y-Ken Studio http://y-ken.hatenablog.com/entry/essential-japanese-blogs-for-elasticsearch-study MySQLでは実現の難しかったLuceneならではの次のような特徴を兼ね備えたelasticsearchはとても魅力ですよね。 ファセット検索 (Facet) http://www.el…
<p>elasticsearchは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>サーバとしても知名度を獲得しており、次のような記事も人気を集めています。</p>
<ul>
<li>elasticsearchを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>サーバとして活用するなら読んでおきたい、6つのブログ記事をピックアップ - Y-Ken Studio<br />
<a href="http://y-ken.hatenablog.com/entry/essential-japanese-blogs-for-elasticsearch-study">http://y-ken.hatenablog.com/entry/essential-japanese-blogs-for-elasticsearch-study</a></li>
</ul>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>では実現の難しかった<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lucene">Lucene</a>ならではの次のような特徴を兼ね備えたelasticsearchはとても魅力ですよね。</p>
<ul>
<li>ファセット検索 (Facet)<br />
<a href="http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets.html">http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets.html</a></li>
<li>柔軟な日本語処理 (kuromoji)<br />
<a href="https://github.com/elasticsearch/elasticsearch-analysis-kuromoji">https://github.com/elasticsearch/elasticsearch-analysis-kuromoji</a></li>
<li>オートコンプリート (Completion Suggester)<br />
<a href="http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters-completion.html">http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters-completion.html</a></li>
</ul>
<p>しかしながらelasticsearchを中核となるデータベースとして扱うにはまだ日が浅いことは事実です。<br />
そこで、私と同様に<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>を補う形でelasticsearchを使いたいという方にとって有用な情報を本日お届けしたいと思います。</p>
<h2>fluent-plugin-<a class="keyword" href="http://d.hatena.ne.jp/keyword/mysql">mysql</a>-replicator v0.4.0</h2>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>テーブルへの更新/削除イベントを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C3%E0%BC%A1">逐次</a>取得するFluentd<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>です。</p>
<p><a href="https://github.com/y-ken/fluent-plugin-mysql-replicator">y-ken/fluent-plugin-mysql-replicator</a> <iframe src="http://ghbtns.com/github-btn.html?user=y-ken&repo=fluent-plugin-mysql-replicator&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe></p>
<ul>
<li><a href="https://github.com/y-ken/fluent-plugin-mysql-replicator">https://github.com/y-ken/fluent-plugin-mysql-replicator</a></li>
<li><a href="http://rubygems.org/gems/fluent-plugin-mysql-replicator">http://rubygems.org/gems/fluent-plugin-mysql-replicator</a></li>
</ul>
<h2>インストール/アップデート方法</h2>
<p>Fluentdの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>としての利用方法の他、独立した<a class="keyword" href="http://d.hatena.ne.jp/keyword/RPM">RPM</a>パッケージをYamabikoとして公開しております。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment">### システム側のRubyにインストールする場合</span>
gem <span class="synStatement">install</span> fluent-plugin-mysql-replicator
<span class="synComment">### td-agentにインストールする場合</span>
/usr/lib64/fluent/ruby/bin/fluent-gem <span class="synStatement">install</span> fluent-plugin-mysql-replicator
<span class="synComment">### RPMパッケージ、Yamabikoでアップデートする場合</span>
<span class="synComment"># インストールについては右記記事をご参照ください https://github.com/y-ken/yamabiko/releases</span>
/usr/lib64/yamabiko/ruby/bin/fluent-gem <span class="synStatement">install</span> fluent-plugin-mysql-replicator
</pre>
<p>利用方法についてはこちらの記事も参考になります。</p>
<ul>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>テーブルへの更新/削除イベントを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C3%E0%BC%A1">逐次</a>取得するFluentd<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>「fluent-plugin-<a class="keyword" href="http://d.hatena.ne.jp/keyword/mysql">mysql</a>-replicator」をリリースしました - Y-Ken Studio<br />
<a href="http://y-ken.hatenablog.com/entry/fluent-plugin-mysql-replicator-has-released">http://y-ken.hatenablog.com/entry/fluent-plugin-mysql-replicator-has-released</a></li>
</ul>
<h2>変更内容概要</h2>
<p>v0.4.0は、新機能の実装のみです。</p>
<ul>
<li>[新機能]ネスト構造化したドキュメントの生成に対応</li>
</ul>
<h2>新機能紹介</h2>
<p>今回、「ネスト構造化したドキュメントの生成」に対応しました。</p>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>などの<a class="keyword" href="http://d.hatena.ne.jp/keyword/RDBMS">RDBMS</a>では、1つの情報に複数のレコードが紐付く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AD%A1%BC%A5%DE">スキーマ</a>設計を利用し、JOINを用いて取り出す手法をよく使いますよね。<br />
しかしelasticsearchにはJOINに相当する機能は無く、近しい物として次の手段があります。</p>
<blockquote><h4>nested</h4>
<p>メリット - クエリのパフォーマンスが高い<br />
デメリット - 更新が多いときのオーバーヘッドが大きい<br />
用途 - 名前の通り入れ子なデータを扱いたいとき、(<a class="keyword" href="http://d.hatena.ne.jp/keyword/rails">rails</a> でいう has_many では使わないと思う)<br /></p>
<h4>parent/child</h4>
<p>メリット - nested と違って更新時に問題を抱えてない<br />
デメリット - クエリのパフォーマンスが落ちる、メモリを多く要する<br />
用途 - 名前の通り親子関係のもの、<a class="keyword" href="http://d.hatena.ne.jp/keyword/RDB">RDB</a> 的な relation はこちらに近い<br />
<br />
引用元: <a href="http://engineer.wantedly.com/2014/02/25/elasticsearch-at-wantedly-1.html">http://engineer.wantedly.com/2014/02/25/elasticsearch-at-wantedly-1.html</a></p></blockquote>
<p>parent/childはドキュメント登録時に1つまでの親子関係を予めセットする必要があるため、柔軟性がない事も使いづらいと感じました。<br />
そこでNested Typeと呼ばれる入れ子構造(ネスト構造)の出番です。例えば次のような検索を行う場合にもこのネスト構造を用いると便利です。</p>
<ul>
<li>ある会員に複数紐付くデータがある</li>
<li>そのいずれか1つがある値である</li>
</ul>
<p>そう、今回の新機能の目玉はこのネスト構造化対応です。</p>
<h4>使い方</h4>
<p>次の結果となる設定の作り方を、サンプルデータと共に解説します。
これはある会員に紐付く、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%B8%C0%B8%EC">プログラミング言語</a>のスキル情報です。</p>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>側のテーブル設計</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140414/20140414092459_original.png" alt="f:id:yoshi-ken:20140414092459p:plain" title="f:id:yoshi-ken:20140414092459p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140414/20140414092810_original.png" alt="f:id:yoshi-ken:20140414092810p:plain" title="f:id:yoshi-ken:20140414092504p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140408/20140408162655_original.png" alt="f:id:yoshi-ken:20140408162655p:plain" title="f:id:yoshi-ken:20140408162655p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>本機能を用いてelasticsearchへ登録したドキュメント</p>
<pre class="code lang-ruby" data-lang="ruby" data-unlink>$ curl -<span class="synType">XGET</span> http<span class="synConstant">:/</span>/localhost:<span class="synConstant">9200</span>/sample/member_skill/<span class="synConstant">1</span>?pretty
{
<span class="synSpecial">"</span><span class="synConstant">_index</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">sample</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">_type</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">member_skill</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">_id</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">1</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">_version</span><span class="synSpecial">"</span> : <span class="synConstant">1</span>,
<span class="synSpecial">"</span><span class="synConstant">found</span><span class="synSpecial">"</span> : <span class="synConstant">true</span>,
<span class="synSpecial">"</span><span class="synConstant">_source</span><span class="synSpecial">"</span> : {
<span class="synSpecial">"</span><span class="synConstant">member_id</span><span class="synSpecial">"</span> : <span class="synConstant">1</span>,
<span class="synSpecial">"</span><span class="synConstant">member_name</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">ユーザA</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">skills</span><span class="synSpecial">"</span> : [
{
<span class="synSpecial">"</span><span class="synConstant">skill_name</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">PHP</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">skill_url</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">http://php.net/</span><span class="synSpecial">"</span>
},
{
<span class="synSpecial">"</span><span class="synConstant">skill_name</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">Ruby</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">skill_url</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">https://www.ruby-lang.org/</span><span class="synSpecial">"</span>
}
]
}
}
</pre>
<h5>ネスト構造を生成する仕組み</h5>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>では1:N対応となるネスト構造は表現できません。<br />
そこで、クエリの中に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>を埋め込みそれを都度展開させる処理を行います。<br />
query設定の実行時の結果のfetch時に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>があれば、別途プログラムの中でSELECTクエリを発行して結果をマージする処理を行うというものです。</p>
<pre class="code lang-sql" data-lang="sql" data-unlink><span class="synComment">-- prepared_query設定に記述する一時テーブル作成クエリ</span>
<span class="synStatement">CREATE</span> TEMPORARY <span class="synSpecial">TABLE</span> tmp_member_skill
<span class="synStatement">SELECT</span>
members.id <span class="synSpecial">AS</span> member_id,
skills.name <span class="synSpecial">AS</span> skill_name,
skills.url <span class="synSpecial">AS</span> skill_url
<span class="synSpecial">FROM</span>
members
LEFT JOIN member_skill_relation <span class="synSpecial">ON</span> members.id = member_id
LEFT JOIN skills <span class="synSpecial">ON</span> skills.id = skill_id;
<span class="synComment">-- query設定に記述する、elasticsearchへ登録するドキュメントを生成するクエリ</span>
<span class="synComment">-- クエリの中に、ネスト構造として納めたいクエリを記述すると処理時に展開します</span>
<span class="synStatement">SELECT</span>
members.id <span class="synSpecial">AS</span> member_id,
members.name <span class="synSpecial">AS</span> member_name,
<span class="synConstant">"SELECT skill_name, skill_url FROM tmp_member_skill WHERE member_id = ${member_id}"</span> <span class="synSpecial">AS</span> skills
<span class="synSpecial">FROM</span>
members
;
</pre>
<p>仕組みとしては、まずquery設定のクエリを実行し、次の結果を得ます。</p>
<pre class="code lang-ruby" data-lang="ruby" data-unlink>{
<span class="synSpecial">"</span><span class="synConstant">member_id</span><span class="synSpecial">"</span> : <span class="synConstant">1</span>,
<span class="synSpecial">"</span><span class="synConstant">member_name</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">ユーザA</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">skills</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">SELECT skill_name, skill_url FROM tmp_member_skill WHERE member_id = ${member_id}</span><span class="synSpecial">"</span>,
}
</pre>
<p>この<code>skills</code>キーに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>付きのクエリがありますので、続けて<code>${カラム名}</code>の展開をします。<br />
クエリ実行結果にある<code>member_id</code>の値である<code>1</code>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>に代入し、<a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a>クエリを実行します。<br />
<code>SELECT skill_name, skill_url FROM tmp_member_skill WHERE member_id = 1</code></p>
<p>ここでは<code>tmp_member_skill</code>という事前にCREATE TEMPORARY TABLE構文で作成した一時テーブルを利用しています。使わずに都度JOINして結果を得るとパフォーマンスが劣化するため、事前に計算結果をメモリに蓄える手法を利用しています。</p>
<p>そして、実行結果をskillsの値として代入することで、次のネスト構造を得られました。<br />
最後にこのドキュメントをelasticsearchへ登録すれば完了です。</p>
<pre class="code lang-ruby" data-lang="ruby" data-unlink>{
<span class="synSpecial">"</span><span class="synConstant">member_id</span><span class="synSpecial">"</span> : <span class="synConstant">1</span>,
<span class="synSpecial">"</span><span class="synConstant">member_name</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">ユーザA</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">skills</span><span class="synSpecial">"</span> : [
{
<span class="synSpecial">"</span><span class="synConstant">skill_name</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">PHP</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">skill_url</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">http://php.net/</span><span class="synSpecial">"</span>
},
{
<span class="synSpecial">"</span><span class="synConstant">skill_name</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">Ruby</span><span class="synSpecial">"</span>,
<span class="synSpecial">"</span><span class="synConstant">skill_url</span><span class="synSpecial">"</span> : <span class="synSpecial">"</span><span class="synConstant">https://www.ruby-lang.org/</span><span class="synSpecial">"</span>
}
]
}
</pre>
<h2>elasticsearch-<a class="keyword" href="http://d.hatena.ne.jp/keyword/JDBC">JDBC</a>-river との違い</h2>
<p>実は<a class="keyword" href="http://d.hatena.ne.jp/keyword/JDBC">JDBC</a>ドライバを用いて、elasticsearchへ各種制約はありながらもデータ同期が出来るRiver<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は存在します。<br />
しかし、このようなネスト構造のサポートは行われておりません。</p>
<ul>
<li>Elasticsearch <a class="keyword" href="http://d.hatena.ne.jp/keyword/JDBC">JDBC</a> river<br />
<a href="https://github.com/jprante/elasticsearch-river-jdbc">https://github.com/jprante/elasticsearch-river-jdbc</a></li>
</ul>
<h2>まとめ</h2>
<p>この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を用いることで、既存の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>環境はそのままに、手軽にelasticsearchを用いた高機能な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>を試せる環境が作れます。<br />
実際に弊社内で運用しており、特にトラブルなく稼働しております。今後はドキュメントの拡充を進めていこうと考えております。</p>
<p>この記事をご覧頂いた皆様も是非、まずは開発環境でのトライアルから初めて頂けると幸いです。<br />
不明点等ございましたら、<a href="https://twitter.com/yoshi_ken">@yoshi_ken</a>までご連絡ください。</p>
yoshi-ken
elasticsearchを全文検索サーバとして活用するなら読んでおきたい、6つのブログ記事をピックアップ(追記あり)
hatenablog://entry/12921228815721191587
2014-04-04T17:05:03+09:00
2014-04-14T11:31:45+09:00 LuceneベースのNoSQL全文検索サーバ、elasticsearchはログ解析の収集先として取り上げられることが多いですが、優れたNoSQL全文検索サーバでもあります。 日本でも2013年末頃から続々とブログ記事や利用事例が増えている注目の技術でもあります。 今回は、その中で全文検索サーバとしての切り口で分かりやすく解説された6つの記事を紹介します。
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Lucene">Lucene</a>ベースのNoSQL<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>サーバ、elasticsearchはログ解析の収集先として取り上げられることが多いですが、優れたNoSQL<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>サーバでもあります。<br />
日本でも2013年末頃から続々とブログ記事や利用事例が増えている注目の技術でもあります。<br />
今回は、その中で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>サーバとしての切り口で分かりやすく解説された6つの記事を紹介します。</p>
<h2>(追記)Hello! Elasticsearch. — Medium</h2>
<p>ナレッジワークス株式会社のKunihiko Kidoさんによるとても分かりやすい記事です。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140414/20140414112108.png" alt="f:id:yoshi-ken:20140414112108p:plain" title="f:id:yoshi-ken:20140414112108p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><a href="https://medium.com/hello-elasticsearch">https://medium.com/hello-elasticsearch</a></p>
<p>2014年4月に入ってから怒濤の勢いでこれらのステキな記事が追加されています。</p>
<ul>
<li>Elasticsearch Features — 主にシステムを中心とした特徴まとめ</li>
<li>Elasticsearch Quick Start — インストールからインデックス、検索までのクイックスタート手順</li>
<li>Elasticsearch System Overview — インデックス設計に関連する主要概念</li>
<li>Elasticsearch Modules — システムを構成する主要モジュール</li>
<li>Elasticsearch Plugins — 機能を拡張する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の管理方法と主な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a></li>
<li>Elasticsearch Search & Index <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> Overview — サーチ&インデックス <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を使用する為の前提知識</li>
<li>Elasticsearch Routing — 検索パフォーマンスを向上させる為の仕組み</li>
<li>Elasticsearch Japanese Analysis — 日本語<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>と解析処理モジュール概要</li>
<li>Elasticsearch Japanese Analysis — 日本語<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>で使用する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>と、日本語解析フィルター</li>
<li>Elasticsearch Japanese Analysis — 日本語<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>の為のカスタムアナライザー</li>
<li>Elasticsearch Image Plugin DEMO — デモサイトに関するノート</li>
<li>Elasticsearch Image Plugin — インストールから検索までの手順</li>
<li>Elasticsearch Mapping — ドキュ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%F3%A5%C8%A5%B9">メントス</a>キーマと検索精度を最適化するための<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%C3%A5%D4%A5%F3%A5%B0">マッピング</a>定義</li>
</ul>
<h2>実践!Elasticsearch - Wantedly Engineer Blog</h2>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140402/20140402181209.png" alt="f:id:yoshi-ken:20140402181209p:plain" title="f:id:yoshi-ken:20140402181209p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><a href="http://engineer.wantedly.com/2014/02/25/elasticsearch-at-wantedly-1.html">http://engineer.wantedly.com/2014/02/25/elasticsearch-at-wantedly-1.html</a></p>
<p><a href="https://www.wantedly.com/">Wantedly</a>という求人サイトのバックエンド検索システムにelasticsearchを導入した際のノウハウが、やさしく紹介されています。<br />
日本語検索を行う際のMapping定義や、ドキュメントの親子関係を定義した検索の解説など実践的な内容となっております。</p>
<h2>Elasticsearch<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB">チュートリアル</a> - 不可視点</h2>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140402/20140402181348.png" alt="f:id:yoshi-ken:20140402181348p:plain" title="f:id:yoshi-ken:20140402181348p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><a href="http://code46.hatenablog.com/entry/2014/01/21/115620">http://code46.hatenablog.com/entry/2014/01/21/115620</a></p>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Livedoor">Livedoor</a>グルメの研究用公開デー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a>を用いて、Mappingの作成から次の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a>を行うまでの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB">チュートリアル</a>がまとまっております。</p>
<ul>
<li>「地名 料理ジャンル/店名」と言った形でレストランが探せる</li>
<li>メニュー名からレストランが探せる(例えば「ハンバーガー」が美味しいお店)</li>
<li>PV順・口コミが多い順・評価が高い順など検索結果をソートできる</li>
</ul>
<p>この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB">チュートリアル</a>を実践するための各種ファイルはこちらの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>に保管されております。</p>
<p><a href="https://github.com/yteraoka/elasticsearch-study">https://github.com/yteraoka/elasticsearch-study</a></p>
<h2>Solr vs elasticsearch 類似文書検索</h2>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140402/20140402181316.png" alt="f:id:yoshi-ken:20140402181316p:plain" title="f:id:yoshi-ken:20140402181316p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>Solrとelasticsearchそれぞれでの類似文章検索の設定方法が解説されております。Solrを扱ったことのある方であれば、より理解が深まると思います。<br />
日本語のトークナイズ設定や、ドキュメントの登録方法、MoreLikeThisを用いた類似文章検索について触れられています。</p>
<p><a href="http://lab.synergy-marketing.co.jp/?s=elasticsearch">http://lab.synergy-marketing.co.jp/?s=elasticsearch</a></p>
<h2>elasticsearch勉強会で発表してきました | Advanced Technology Lab</h2>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140402/20140402181329.png" alt="f:id:yoshi-ken:20140402181329p:plain" title="f:id:yoshi-ken:20140402181329p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><a href="http://atl.recruit-tech.co.jp/blog/1203/">http://atl.recruit-tech.co.jp/blog/1203/</a></p>
<p>Elasticsearch+DynamoDB+Node.jsで作る<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>向けのプッシュ通知システム「Pusna-RS」の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>が詳しく紹介されています。<br />
細かな条件指定を元に大量の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A1%BC%A5%C8%A5%D5%A5%A9%A5%F3">スマートフォン</a>端末へプッシュ通知する場合、ページングが深くなるにつれて<a class="keyword" href="http://d.hatena.ne.jp/keyword/RDBMS">RDBMS</a>は応答速度が遅くなるのは周知の事実です。<br />
そこで、取り出すときにソートをしなければ深いページングをしても性能が劣化しないという、elasticsearchのscroll_idを指定した<a href="http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-scroll.html">scrollリクエスト</a>を採用して解決した事例の紹介です。</p>
<iframe src="http://www.slideshare.net/slideshow/embed_code/30940789?rel=0&startSlide=22" width="597" height="486" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px 1px 0; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
<p> <div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/recruitcojp/elasticsearchnodejsdynamodb-7" title="Elasticsearch+nodejs+dynamodbで作る全社システム基盤" target="_blank">Elasticsearch+nodejs+dynamodbで作る全社システム基盤</a> </strong> from <strong><a href="http://www.slideshare.net/recruitcojp" target="_blank">Recruit Technologies</a></strong> </div></p>
<h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>で始めるElasticSearch | シリーズ | Developers.IO</h2>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140402/20140402181154.png" alt="f:id:yoshi-ken:20140402181154p:plain" title="f:id:yoshi-ken:20140402181154p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p><a href="http://dev.classmethod.jp/series/aws%E3%81%A7%E5%A7%8B%E3%82%81%E3%82%8Belasticsearch/">http://dev.classmethod.jp/series/aws%E3%81%A7%E5%A7%8B%E3%82%81%E3%82%8Belasticsearch/</a></p>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>でelasticsearchを運用する際には目を通しておきたい記事がまとまっております。</p>
<ul>
<li><p>Kuromojiで日本語<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%B4%CA%B8%B8%A1%BA%F7">全文検索</a> – <a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>で始めるElasticSearch(1)<br />
<a href="http://dev.classmethod.jp/cloud/aws/use-elasticsearch-1-use-kuromoji/">http://dev.classmethod.jp/cloud/aws/use-elasticsearch-1-use-kuromoji/</a></p></li>
<li><p>Cluster機能を使う – <a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>で始めるElasticSearch(2)<br />
<a href="http://dev.classmethod.jp/cloud/aws/use-elasticsearch-2-use-cluster/">http://dev.classmethod.jp/cloud/aws/use-elasticsearch-2-use-cluster/</a></p></li>
<li><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a> Cloud Plugin for ElasticSearchを使う – <a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>で始めるElasticSearch(3)<br />
<a href="http://dev.classmethod.jp/cloud/aws/use-elasticsearch-3-use-awscloudplugin/">http://dev.classmethod.jp/cloud/aws/use-elasticsearch-3-use-awscloudplugin/</a></p></li>
<li><p>データ構造について – <a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a>で始めるElasticSearch(4)<br />
<a href="http://dev.classmethod.jp/cloud/aws/use-elasticsearch-4-data-structure/">http://dev.classmethod.jp/cloud/aws/use-elasticsearch-4-data-structure/</a></p></li>
</ul>
<h2>さいごに</h2>
<p>WEB上でも各種情報がありますが、体系的な理解を深めるならば日本語で書かれたこちらの書籍がおすすめです。<br />
こちらの書籍のオリジナル言語版は elasticsearch 0.19/0.20 というとても古いバージョンを対象に記述されています。しかしこの日本語版では elasticsearch 0.90 を対象に書き直されている<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%BF%A4%E1%C0%B8%A4%AD">ため生き</a>た情報源としていますぐ使えますね!</p>
<p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00J4KDYZU/y_ken_studio-22/"><img src="http://ecx.images-amazon.com/images/I/510nupY-9zL._SL160_.jpg" class="hatena-asin-detail-image" alt="高速スケーラブル検索エンジン ElasticSearch Server (アスキー書籍)" title="高速スケーラブル検索エンジン ElasticSearch Server (アスキー書籍)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00J4KDYZU/y_ken_studio-22/">高速スケーラブル検索エンジン ElasticSearch Server (アスキー書籍)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> Rafal Kuc (lに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C8%A5%ED%A1%BC%A5%AF">ストローク</a>符号、cにアクサン・テギュ付く),Marek Rogozinski (nにアクサン・テギュ付く)</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/KADOKAWA">KADOKAWA</a> / <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%B9%A5%AD%A1%BC%A1%A6%A5%E1%A5%C7%A5%A3%A5%A2%A5%EF%A1%BC%A5%AF%A5%B9">アスキー・メディアワークス</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2014/03/25</li><li><span class="hatena-asin-detail-label">メディア:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Kindle">Kindle</a>版</li><li><a href="http://d.hatena.ne.jp/asin/B00J4KDYZU/y_ken_studio-22" target="_blank">この商品を含むブログ (2件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p>
<h5>更新履歴</h5>
<p>2014年4月14日 : <a href="https://medium.com/hello-elasticsearch">https://medium.com/hello-elasticsearch</a> を追加</p>
yoshi-ken
プレースホルダ設定に対応した fluent-plugin-geoip v0.1.1 をリリースしました
hatenablog://entry/12921228815721049859
2014-03-31T12:59:52+09:00
2014-03-31T15:19:41+09:00 GeoIPを用いてIPアドレスを元に位置情報をレコードに付与するFluentdプラグイン、fluent-plugin-geoip v0.1.1をリリースしました。 今回の目玉は、GeoIP判定対象の複数キー対応化と、プレースホルダ記法への対応するための設定ファイル仕様の変更です。 https://github.com/y-ken/fluent-plugin-geoip http://rubygems.org/gems/fluent-plugin-geoip 前回記事はv0.0.4の紹介でしたので、それ以降にリリースしたv0.0.5とv0.0.6とv0.1.0、そしてv0.1.1のリリースノート…
<p>GeoIPを用いて<a class="keyword" href="http://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a>を元に位置情報をレコードに付与するFluentd<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>、fluent-plugin-geoip v0.1.1をリリースしました。<br />
今回の目玉は、GeoIP判定対象の複数キー対応化と、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>記法への対応するための設定ファイル仕様の変更です。</p>
<ul>
<li><a href="https://github.com/y-ken/fluent-plugin-geoip">https://github.com/y-ken/fluent-plugin-geoip</a> <iframe src="http://ghbtns.com/github-btn.html?user=y-ken&repo=fluent-plugin-geoip&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe></li>
<li><a href="http://rubygems.org/gems/fluent-plugin-geoip">http://rubygems.org/gems/fluent-plugin-geoip</a></li>
</ul>
<p><a href="http://y-ken.hatenablog.com/entry/fluent-plugin-geoip-v0.0.4">前回記事</a>はv0.0.4の紹介でしたので、それ以降にリリースしたv0.0.5とv0.0.6とv0.1.0、そしてv0.1.1のリリースノートをまとめたいと思います。</p>
<h2>アップデート方法</h2>
<p>次の手順でアップデート後、fluentd (td-agent)を再起動してください。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># for fluentd</span>
$ gem <span class="synStatement">install</span> fluent-plugin-geoip <span class="synSpecial">--no-ri</span> <span class="synSpecial">--no-rdoc</span>
<span class="synComment"># for td-agent</span>
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem <span class="synStatement">install</span> fluent-plugin-geoip <span class="synSpecial">--no-ri</span> <span class="synSpecial">--no-rdoc</span>
</pre>
<h2>変更内容概要</h2>
<p>v0.0.4とv0.1.1の<a href="https://github.com/y-ken/fluent-plugin-geoip/compare/v0.0.4...v0.1.1">修正差分</a>より紹介します。</p>
<ul>
<li><p>v0.1.1 のリリース内容</p>
<ul>
<li>[改修]<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>で代入する文字列に<a class="keyword" href="http://d.hatena.ne.jp/keyword/JSON">JSON</a>エスケープ処理を追加</li>
<li>[改修]追加データがハッシュ/配列の時、1つでも<a class="keyword" href="http://d.hatena.ne.jp/keyword/nil">nil</a>があるとその追加キーの値が<a class="keyword" href="http://d.hatena.ne.jp/keyword/nil">nil</a>となる不自然な挙動を解消</li>
<li>[改修]Fluentd起動時に<code><record>...</record></code>ディレクティブに記述された<a class="keyword" href="http://d.hatena.ne.jp/keyword/JSON">JSON</a>フォーマットの構文チェックを追加</li>
<li>[改修]テストを拡充</li>
</ul>
</li>
<li><p>v0.1.0 のリリース内容</p>
<ul>
<li>[新機能]GeoIP判定結果を保持した<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>を用いた<code><record>...</record></code>ディレクティブへの設定ファイル対応 (Thanks! @hakobera さん)<br />
<a href="https://github.com/y-ken/fluent-plugin-geoip/pull/7">https://github.com/y-ken/fluent-plugin-geoip/pull/7</a>
<a href="https://github.com/y-ken/fluent-plugin-geoip/pull/11">https://github.com/y-ken/fluent-plugin-geoip/pull/11</a>
<ul>
<li>この実装に伴い、従来の<code>enable_key_*</code>という記法は今後廃止し、<code><record>...</record></code>ディレクティブに一本化します</li>
</ul>
</li>
<li>[改修]GeoIP判定対象フィールドが無いケースでは、レコードへ値が<a class="keyword" href="http://d.hatena.ne.jp/keyword/nil">nil</a>であるキーを必ず追加するよう仕様を変更</li>
<li>[新機能]タグの部分削除/追加だけでなく、タグの明示的な指定や、tag_parts<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>も扱える<code>tag</code>設定機能を追加
<ul>
<li><code>tag</code>オプションで使える<code>tag_parts</code><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>に関する詳細は次のページをご覧ください<br />
<a href="http://y-ken.hatenablog.com/entry/fluentd-how-to-use-tag_parts-placeholder">http://y-ken.hatenablog.com/entry/fluentd-how-to-use-tag_parts-placeholder</a></li>
<li>この実装に伴い、<a href="https://github.com/y-ken/fluent-mixin-rewrite-tag-name">fluent-mixin-rewrite-tag-name</a> への依存を追加しております</li>
</ul>
</li>
<li>[新機能]<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%AC%C4%EA">規定</a>のバッファインターバル<code>flush_interval</code>設定を60秒から0秒に変更</li>
<li>[新機能]ログ出力の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%EF%E7%C3%CD">閾値</a>を指定できる<a href="http://blog.livedoor.jp/sonots/archives/36150373.html">log_level</a>設定への対応 (Fluentd v0.10.43以降で動作)</li>
</ul>
</li>
<li><p>v0.0.6 のリリース内容</p>
<ul>
<li>[新機能]GeoIP判定対象となるレコードの複数キー対応 (Thanks! @muddydixon さん)<br />
<a href="https://github.com/y-ken/fluent-plugin-geoip/pull/6">https://github.com/y-ken/fluent-plugin-geoip/pull/6</a></li>
<li>[改修]<a class="keyword" href="http://d.hatena.ne.jp/keyword/Travis">Travis</a>-CIでの自動テストを<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>-2.1.0でも開始</li>
</ul>
</li>
<li><p>v0.0.5 のリリース内容</p>
<ul>
<li>[新機能]ネスト構造のキーを対象としたGeoIP判定に対応 (Thanks! @muddydixon さん)<br />
<a href="https://github.com/y-ken/fluent-plugin-geoip/pull/5">https://github.com/y-ken/fluent-plugin-geoip/pull/5</a></li>
</ul>
</li>
</ul>
<h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>について</h2>
<p>今回導入した<code><record>...</record></code>ディレクティブでは、より柔軟なレコード追加が出来るようになります。<br />
実際の設定ファイルのサンプルは次の通りです。</p>
<pre class="code lang-xml" data-lang="xml" data-unlink># 従来の設定ファイル記述例
<span class="synIdentifier"><match </span><span class="synType">input</span><span class="synIdentifier">.access></span>
type geoip
geoip_lookup_key host
enable_key_latitude geoip_lat
enable_key_longitude geoip_lon
enable_key_lonlat geoip_lonlat
remove_tag_prefix input.
add_tag_prefix geoip.
<span class="synIdentifier"></match></span>
# 今回導入した設定ファイル記述例
<span class="synIdentifier"><match </span><span class="synType">input</span><span class="synIdentifier">.access></span>
type geoip
# GeoIP判定を行うキーを指定
## 2つ以上のキーを対象とする場合には、カンマ区切りで並べます
geoip_lookup_key host
# レコードに追加するキーと、その値をそれぞれ指定
## 各キーの中にJSON形式で記載すれば、ネスト構造のデータをレコードに追加可能
<span class="synIdentifier"><record></span>
geoip_lat ${latitude['host']}
geoip_lon ${longitude['host']}
# Array型を追加する場合
## elasticsearch+Kibana3構成でbettermapを利用する際に必要となる、
## GeoJSONという配列型 [longitude,latitude] を追加する場合の例です
coordinate [ ${longitude['host']}, ${latitude['host']} ]
<span class="synIdentifier"></record></span>
# タグの書き換えルールを指定
## tagオプション内では${tag}のほか${tag_parts[n]}が利用可能
## この例ではinput.accessというタグが、geoip.accessとなります
tag geoip.${tag_parts[1]}
<span class="synIdentifier"></match></span>
</pre>
<p>tag_partsを用いたタグ書き換えの詳細については次の記事が参考になります。</p>
<ul>
<li>Fluentdのタグ書き換えが捗る「tag_parts」<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>を使ってみよう - Y-Ken Studio<br />
<a href="http://y-ken.hatenablog.com/entry/fluentd-how-to-use-tag_parts-placeholder">http://y-ken.hatenablog.com/entry/fluentd-how-to-use-tag_parts-placeholder</a></li>
</ul>
<p>Kibana3のbettermapについては、次のページが参考になります。</p>
<ul>
<li><a href="http://www.elasticsearch.org/guide/en/kibana/current/_bettermap.html">http://www.elasticsearch.org/guide/en/kibana/current/_bettermap.html</a></li>
</ul>
<p>そして、次の例はいずれもelasticsearchの<a href="http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-geo-point-type.html">geo point type</a>にて対応している位置情報のデータ構造です。</p>
<pre class="code lang-xml" data-lang="xml" data-unlink><span class="synIdentifier"><match </span><span class="synType">input</span><span class="synIdentifier">.access></span>
type geoip
geoip_lookup_key host
<span class="synIdentifier"><record></span>
# lat lon as properties
location_properties { "lat":${latitude['host']}, "lon":${longitude['host']}}
# lat lon as string
location_string ${latitude['host']},${longitude['host']}
# lat lon as array
location_array [${longitude['host']},${latitude['host']}]
<span class="synIdentifier"></record></span>
tag geoip.${tag_parts[1]}
<span class="synIdentifier"></match></span>
</pre>
<h4>提供する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a></h4>
<p><code>lookup_field</code>には<code>geoip_lookup_key</code>で指定したフィールドを指定します。<br />
例えば<code>host</code>に対してのGeoIP判定結果を参照するには、<code>${city['host']}</code>と指定します。</p>
<ul>
<li>${city[lookup_field]}</li>
<li>${latitude[lookup_field]}</li>
<li>${longitude[lookup_field]}</li>
<li>${country_code3[lookup_field]}</li>
<li>${country_code[lookup_field]}</li>
<li>${country_name[lookup_field]}</li>
<li>${dma_code[lookup_field]}</li>
<li>${area_code[lookup_field]}</li>
<li>${region[lookup_field]}</li>
</ul>
<h2>あとがき</h2>
<p>v0.1.0より設定記法の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%E5%CA%FD%B8%DF%B4%B9">後方互換</a>を維持しつつ、GeoIP判定結果を配列型やネスト構造データに対応することで、様々な要件に対応できるようになりました。<br />
この実装は、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>展開後にevalを呼び出せば簡単に実現できますが、それは'eval is <a class="keyword" href="http://d.hatena.ne.jp/keyword/evil">evil</a>'と言われる実装です。そのためこの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>では、<a class="keyword" href="http://d.hatena.ne.jp/keyword/JSON">JSON</a>(<a href="https://github.com/brianmario/yajl-ruby">Yajl::Parser</a>)を利用しております。</p>
<p>また、<code><record>...</record></code>ディレクティブ対応化の実装には<a href="https://github.com/sonots/fluent-plugin-record-reformer">fluent-plugin-record-reformer</a>を参考にしました。@sonotsさん、ありがとうございます。<br />
現段階では互換レイヤーを挟む事で動作しますが、今後<code>enable_key_*</code>を使う設定は廃止予定のため、お手数ですが<code><record>...</record></code>ディレクティブへの乗り換えをお願いします。</p>
yoshi-ken
Fluentdでelasticsearchの一般ログ・スロークエリログを収集する設定
hatenablog://entry/12921228815720250550
2014-03-19T16:43:16+09:00
2014-03-19T16:43:16+09:00 FluentdのtailプラグインでElasticsearchのログを収集する方法を紹介します。
<p>Fluentdのtail<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>でElasticsearchのログを収集する方法を紹介します。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140319/20140319154142.png" alt="f:id:yoshi-ken:20140319154142p:plain" title="f:id:yoshi-ken:20140319154142p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<h1>収集対象ログ</h1>
<p><code>/etc/elasticsearch/logging.yml</code>にて設定された動作でログを次のファイルに出力します。</p>
<ul>
<li>/var/log/elasticsearch/elasticsearch.log</li>
<li>/var/log/elasticsearch/elasticsearch_index_search_slowlog.log</li>
<li>/var/log/elasticsearch/elasticsearch_index_indexing_slowlog.log</li>
</ul>
<p><a href="http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/index-modules-slowlog.html">slowlog</a>に関しては<code>/etc/elasticsearch/elasticsearch.yml</code>にて設定した<a class="keyword" href="http://d.hatena.ne.jp/keyword/%EF%E7%C3%CD">閾値</a>時間を超えて処理したクエリを記録できますが、デフォルトでは設定が行われていません。後々のパフォーマンス観察を容易にするためにも設定しておくと便利です。</p>
<h2>設定例</h2>
<p>Fluentdでログを収集する設定例は次の通りです。<br>
この例では<code>elasticsearch.*</code>に該当するタグでログをまとめて、fluentdのstdoutログに出力します。</p>
<pre class="code lang-xml" data-lang="xml" data-unlink><span class="synIdentifier"><source></span>
type tail
tag elasticsearch.general_log
format /^\[(?<span class="synIdentifier"><time></span>[^ ]* [^ ]*)\]\[(?<span class="synIdentifier"><log_level></span>[^ ]*) *?\]\[(?<span class="synIdentifier"><log_type></span>[^ ]*) *\] \[(?<span class="synIdentifier"><node_name></span>[^ ]*) *\] (?<span class="synIdentifier"><message></span>.*)$/
path /var/log/elasticsearch/elasticsearch.log
pos_file /var/log/td-agent/elasticsearch.log.pos
<span class="synIdentifier"></source></span>
<span class="synIdentifier"><source></span>
type tail
tag elasticsearch.search_slowlog
format /^\[(?<span class="synIdentifier"><time></span>[^ ]* [^ ]*)\]\[(?<span class="synIdentifier"><log_level></span>[^ ]*) *?\]\[(?<span class="synIdentifier"><log_type></span>[^ ]*) *\] \[(?<span class="synIdentifier"><node_name></span>[^ ]*) *\] (?<span class="synIdentifier"><message></span>.*)$/
path /var/log/elasticsearch/elasticsearch_index_search_slowlog.log
pos_file /var/log/td-agent/elasticsearch_index_search_slowlog.log.pos
<span class="synIdentifier"></source></span>
<span class="synIdentifier"><source></span>
type tail
tag elasticsearch.indexing_slowlog
format /^\[(?<span class="synIdentifier"><time></span>[^ ]* [^ ]*)\]\[(?<span class="synIdentifier"><log_level></span>[^ ]*) *?\]\[(?<span class="synIdentifier"><log_type></span>[^ ]*) *\] \[(?<span class="synIdentifier"><node_name></span>[^ ]*) *\] (?<span class="synIdentifier"><message></span>.*)$/
path /var/log/elasticsearch/elasticsearch_index_indexing_slowlog.log
pos_file /var/log/td-agent/elasticsearch_index_indexing_slowlog.log.pos
<span class="synIdentifier"></source></span>
<span class="synIdentifier"><match </span><span class="synType">elasticsearch</span><span class="synIdentifier">.*></span>
type stdout
<span class="synIdentifier"></match></span>
</pre>
<h2>ログデータサンプル</h2>
<p>実際にどのように分解されるかは、<a href="http://fluentular.herokuapp.com/parse?regexp=%5E%5C%5B%28%3F%3Ctime%3E%5B%5E+%5D*+%5B%5E+%5D*%29%5C%5D%5C%5B%28%3F%3Clog_level%3E%5B%5E+%5D*%29+*%3F%5C%5D%5C%5B%28%3F%3Clog_type%3E%5B%5E+%5D*%29+*%5C%5D+%5C%5B%28%3F%3Cnode_name%3E%5B%5E+%5D*%29+*%5C%5D+%28%3F%3Cmessage%3E.*%29&input=%5B2014-03-18+18%3A27%3A34%2C897%5D%5BINFO+%5D%5Bhttp+++++++++++++++++++++%5D+%5Bes01%5D+bound_address+%7Binet%5B%2F0%3A0%3A0%3A0%3A0%3A0%3A0%3A0%3A9200%5D%7D%2C+publish_address+%7Binet%5B%2F10.0.0.185%3A9200%5D%7D&time_format=">Fluentular</a>で確認すると便利です。</p>
<ul>
<li>elasticsearch.log</li>
</ul>
<pre class="code lang-" data-lang="" data-unlink>[2014-03-18 18:27:34,897][INFO ][http ] [es01] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/10.0.0.185:9200]}
[2014-03-18 18:27:35,647][INFO ][gateway ] [es01] recovered [3] indices into cluster_state
[2014-03-18 18:27:35,648][INFO ][node ] [es01] started
[2014-03-18 18:27:37,426][INFO ][cluster.service ] [es01] added {[es02][fC4QjocCREagqkxz3nQ8rQ][v157-7-203-186.z1d4.static.cnode.jp][inet[/10.0.0.186:9300]]{master=false},}, reason: zen-disco-receive(join from node[[es02][fC4QjocCREagqkxz3nQ8rQ][v157-7-203-186.z1d4.static.cnode.jp][inet[/10.0.0.186:9300]]{master=false}])</pre>
<ul>
<li>elasticsearch_index_indexing_slowlog.log</li>
</ul>
<pre class="code lang-" data-lang="" data-unlink>[2014-03-18 18:26:12,630][TRACE][index.indexing.slowlog.index] [es01] [b][0] took[70.8ms], took_millis[70], type[es02], id[1], routing[], source[{"user":"kimchy","post_date":"2009-11-15T14:12:12","message":"trying out Elasticsearch"}]</pre>
<ul>
<li>elasticsearch_index_search_slowlog.log<br>
<a href="http://www.chepoo.com/elasticsearch-index-search-slowlog-query-explanation.html">elasticsearch index.search.slowlog.query解释-IT技术精华网</a> より引用</li>
</ul>
<pre class="code lang-" data-lang="" data-unlink>[2013-11-27 13:02:51,436][TRACE][index.search.slowlog.query] [h35] [cms][2] took[1.1s], took_millis[1136], types[news], stats[], search_type[QUERY_THEN_FETCH], total_shards[10], source[{"from":250,"size":10,"query":{"custom_score":{"query":{"filtered":{"query":{"query_string":{"query":"尼日利亚","fields":["title","content"],"analyzer":"ik"}},"filter":{"bool":{"must":{"range":{"updatetime":{"from":1353992570,"to":1385528570,"include_lower":true,"include_upper":true}}}}}}},"script":"long x=Long.parseLong(doc['updatetime'].value);x=x/86400l;long nows=yy/86400l;int nowDay=(int)nows;int day=(int)x;if (day < nowDay) {int temp=nowDay-day;int delta=(int)temp/5+1;if(delta<32){_score=_score+6*pow(0.9,delta);}else{_score=_score+3*pow(0.9,31);}} else if (day > nowDay) {_score=_score+3*pow(0.9,31);} else{_score=_score+3;}","params":{"yy":1385528570}}},"fields":["id","channelid","catid","model","title","content","thumb","url","updatetime"],"sort":[{"_score":{"order":"desc"}},{"updatetime":{"order":"desc"}}],"highlight":{"pre_tags":["<em>"],"post_tags":["</em>"],"encoder":"UTF-8","fields":{"title":{},"content":{"fragment_size":72,"number_of_fragments":3}}}}], extra_source[]</pre>
<h2>まとめ</h2>
<p>elasticsearchは<a class="keyword" href="http://d.hatena.ne.jp/keyword/log4j">log4j</a>を利用しており、logrotate.dに設定を入れること無くログのローテーションが出来ます。つまり日付毎にファイルが作られるため、消し込み処理は必要に応じて検討しましょう。</p>
<p>そして、ログファイルからデータを収集したい時には<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>を都度書くと思います。その際にはブラウザで設定ファイルが作れる<a href="http://fluentular.herokuapp.com/">Fluentular</a>がとても便利ですので是非、お使いください。</p>
yoshi-ken
不正バイト文字列対策済の fluent-plugin-rewrite-tag-filter v1.4.1 をリリースしました #fluentd
hatenablog://entry/12921228815719718570
2014-03-10T18:50:54+09:00
2014-10-30T17:49:29+09:00 ログ収集ツールFluentdに、Apacheのmod_rewriteのようにtagを自在に書き換える機能を追加する、fluent-plugin-rewrite-tag-filterのv1.4.1をリリースしました。 https://github.com/y-ken/fluent-plugin-rewrite-tag-filter http://rubygems.org/gems/fluent-plugin-rewrite-tag-filter 前回記事はv1.3.1の紹介でしたので、それ以降にリリースしたv1.4.0とv1.4.1のリリースノートをまとめたいと思います。
<p>ログ収集ツールFluentdに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apache">Apache</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/mod_rewrite">mod_rewrite</a>のようにtagを自在に書き換える機能を追加する、fluent-plugin-rewrite-tag-filterのv1.4.1をリリースしました。</p>
<ul>
<li><a href="https://github.com/y-ken/fluent-plugin-rewrite-tag-filter">https://github.com/y-ken/fluent-plugin-rewrite-tag-filter</a> <iframe src="http://ghbtns.com/github-btn.html?user=y-ken&repo=fluent-plugin-rewrite-tag-filter&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe></li>
<li><a href="http://rubygems.org/gems/fluent-plugin-rewrite-tag-filter">http://rubygems.org/gems/fluent-plugin-rewrite-tag-filter</a></li>
</ul>
<p><a href="http://y-ken.hatenablog.com/entry/fluent-plugin-rewrite-tag-filter-v1.3.1">前回記事</a>はv1.3.1の紹介でしたので、それ以降にリリースしたv1.4.0とv1.4.1のリリースノートをまとめたいと思います。</p>
<h2>お知らせ</h2>
<p>今回は4点、嬉しいお知らせがあります。</p>
<h4>Fluentd公式<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>化</h4>
<blockquote class="twitter-tweet" lang="ja"><p>fluent-plugin-rewrite-tag-filterですが,ユーザも多く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B9%A5%B1%A1%BC%A5%B9">ユースケース</a>がたくさんあるので,公式<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>以下でメンテされることになりました.メンテナは変わってませんのでご心配なく > <a href="https://t.co/TqaLlt5mdK">https://t.co/TqaLlt5mdK</a> <a href="https://twitter.com/search?q=%23fluentd&src=hash">#fluentd</a></p>— Mr. Fiber (@repeatedly) <a href="https://twitter.com/repeatedly/statuses/403473990036901888">2013, 11月 21</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>fluentdプロジェクトに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>を移動し、引き続きメンテナンスして行きます。</p>
<ul>
<li>Recent Fluentd updates - <a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> グループ<br>
<a href="https://groups.google.com/d/topic/fluentd/CiWv-Bcj0AU/discussion">https://groups.google.com/d/topic/fluentd/CiWv-Bcj0AU/discussion</a></li>
</ul>
<h4>Fluentd公式ドキュメントへの掲載</h4>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の利用ガイドを、公式ドキュメントへ寄稿しました。<br>
<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%AF%A5%BB%A5%B9%A5%ED%A5%B0">アクセスログ</a>を集計して通知するという<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B9%A5%B1%A1%BC%A5%B9">ユースケース</a>も紹介しております。</p>
<ul>
<li>rewrite_tag_filter Output Plugin | Fluentd<br>
<a href="http://docs.fluentd.org/ja/articles/out_rewrite_tag_filter">http://docs.fluentd.org/ja/articles/out_rewrite_tag_filter</a></li>
</ul>
<h4>td-agentへのバンドル開始</h4>
<p>2013年12月5日リリースのtd-agent v1.1.18より、rewrite-tag-filterが内包されました。<br>
これには、fluent-plugin-rewrite-tag-filter v1.3.1がバンドルされております。</p>
<ul>
<li>td-agent 1.1.18 - <a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> グループ<br>
<a href="https://groups.google.com/d/topic/fluentd/M8IDg7y3HU8/discussion">https://groups.google.com/d/topic/fluentd/M8IDg7y3HU8/discussion</a></li>
</ul>
<h4>30,000ダウンロード達成 @ <a class="keyword" href="http://d.hatena.ne.jp/keyword/rubygems">rubygems</a>.org</h4>
<p>お陰様で3万ダウンロードを達成しました。今後ともよろしくお願いします。<br></p>
<ul>
<li>fluent-plugin-rewrite-tag-filter | <a class="keyword" href="http://d.hatena.ne.jp/keyword/RubyGems">RubyGems</a>.org | your community gem host<br>
<a href="http://rubygems.org/gems/fluent-plugin-rewrite-tag-filter">http://rubygems.org/gems/fluent-plugin-rewrite-tag-filter</a></li>
</ul>
<h2>アップデート方法</h2>
<p>次の手順でアップデート後、fluentd (td-agent)を再起動してください。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># for fluentd</span>
$ gem <span class="synStatement">install</span> fluent-plugin-rewrite-tag-filter <span class="synSpecial">--no-ri</span> <span class="synSpecial">--no-rdoc</span>
<span class="synComment"># for td-agent</span>
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem <span class="synStatement">install</span> fluent-plugin-rewrite-tag-filter <span class="synSpecial">--no-ri</span> <span class="synSpecial">--no-rdoc</span>
</pre>
<h2>リリースノート</h2>
<p>それでは続きましてリリースノートを、<a href="https://github.com/y-ken/fluent-plugin-rewrite-tag-filter/compare/v1.3.1...v1.4.1">修正履歴</a>より紹介します。</p>
<ul>
<li><p>v1.4.0 のリリース内容</p>
<ul>
<li>[新機能] tag_parts<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>対応 Thanks futoase!!<br>
<a href="https://github.com/fluent/fluent-plugin-rewrite-tag-filter/pull/8">https://github.com/fluent/fluent-plugin-rewrite-tag-filter/pull/8</a></li>
<li>[改修]存在しない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>が指定された際のWARNログ出力を追加<br>
<a href="https://github.com/fluent/fluent-plugin-rewrite-tag-filter/commit/5685a35">https://github.com/fluent/fluent-plugin-rewrite-tag-filter/commit/5685a35</a></li>
<li>[改修]<a class="keyword" href="http://d.hatena.ne.jp/keyword/Travis">Travis</a>-CIへの対応<br>
<a href="https://github.com/fluent/fluent-plugin-rewrite-tag-filter/commit/df46153">https://github.com/fluent/fluent-plugin-rewrite-tag-filter/commit/df46153</a></li>
</ul>
</li>
<li><p>v1.4.1 のリリース内容</p>
<ul>
<li>[不具合] 不正なバイト文字列を評価した場合のinvalid byte sequence in <a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-8">UTF-8</a>エラーを修正 Reported by <a href="https://twitter.com/bluewhale07/status/435673677309292544">bluewhale07</a><br>
<a href="https://github.com/fluent/fluent-plugin-rewrite-tag-filter/pull/12">https://github.com/fluent/fluent-plugin-rewrite-tag-filter/pull/12</a></li>
</ul>
</li>
</ul>
<h4>新機能「tag_parts」<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a></h4>
<p>v1.4.0より機能追加となったtag_partsは、ドットで区切ったタグの一部を使ってタグを再構築する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>です。</p>
<p>詳細な利用方法や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B9%A5%B1%A1%BC%A5%B9">ユースケース</a>については次のブログ記事が参考になります。<br>
<a href="http://y-ken.hatenablog.com/entry/fluentd-how-to-use-tag_parts-placeholder">http://y-ken.hatenablog.com/entry/fluentd-how-to-use-tag_parts-placeholder</a></p>
<h4>依存関係の追加</h4>
<p>不正なバイト文字列を評価した場合に例外エラーが発生し、ログの欠損が起きる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%F6%BE%DD">事象</a>を確認しました。この例外エラーを修正する際に<code>string-scrub</code>というgemの依存が増えております。<br>
string-scrubについてはこちらのブログが詳しいです。<br></p>
<ul>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.1.0 に追加される不正なバイト列を除去する String#scrub の紹介 - sonots:blog<br>
<a href="http://blog.livedoor.jp/sonots/archives/34702351.html">http://blog.livedoor.jp/sonots/archives/34702351.html</a></li>
</ul>
<h2>あとがき</h2>
<p>invalid byte sequence in <a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-8">UTF-8</a>エラーはFluentdに渡された構造化ログの中身を見て何らかの処理を行う<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>全てに影響しうるため、修正が必要な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>が他にもあると見ています。<br>
これはログ欠損が起きる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%F6%BE%DD">事象</a>に繋がるため、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>開発者の皆様、是非とも状況の確認と対応をお願いします。</p>
yoshi-ken
タグ書き換えが捗るFluentd用Mixinプラグイン「Fluent::Mixin::RewriteTagName」を公開
hatenablog://entry/12921228815719712380
2014-03-10T16:29:54+09:00
2014-03-10T16:30:53+09:00 fluent-mixin-rewrite-tag-nameというFluentd向けMixinプラグインを公開しました。 このMixinプラグインは、<source>や<match **>の中で使えるtagオプションを追加します。 タグ書き換え周りのプラグイン実装の省力化ができますね! https://github.com/y-ken/fluent-mixin-rewrite-tag-name http://rubygems.org/gems/fluent-mixin-rewrite-tag-name これは、次のようなプラグインで使えるタグ書き換えに用いられている機能を、その他のプラグインに転…
<p>fluent-mixin-rewrite-tag-nameというFluentd向けMixin<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を公開しました。<br>
このMixin<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は、<code><source></code>や<code><match **></code>の中で使える<code>tag</code>オプションを追加します。<br>
タグ書き換え周りの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>実装の省力化ができますね!</p>
<ul>
<li><a href="https://github.com/y-ken/fluent-mixin-rewrite-tag-name">https://github.com/y-ken/fluent-mixin-rewrite-tag-name</a></li>
<li><a href="http://rubygems.org/gems/fluent-mixin-rewrite-tag-name">http://rubygems.org/gems/fluent-mixin-rewrite-tag-name</a></li>
</ul>
<p>これは、次のような<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>で使えるタグ書き換えに用いられている機能を、その他の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>に転用できるよう切り出しました。</p>
<ul>
<li>fluent-plugin-forest</li>
<li>fluent-plugin-record-reformer</li>
<li>fluent-plugin-rewrite-tag-filter</li>
</ul>
<h2>提供<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a></h2>
<p>Fluent::Mixin::RewriteTagNameを導入することで、次の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>が使えるようになります。</p>
<ul>
<li><p>タグ (Output<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>のみ利用可能)<br>
tag_parts<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>については次の項で紹介します。</p>
<ul>
<li><code>${tag}</code></li>
<li><code>__TAG__</code></li>
<li><code>{$tag_parts[n]}</code></li>
<li><code>__TAG_PARTS[n]__</code></li>
</ul>
</li>
<li><p>ホスト名 (Input/Output<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>両対応)</p>
<ul>
<li><code>${hostname}</code></li>
<li><code>__HOSTNAME__</code></li>
</ul>
</li>
</ul>
<h3>tag_parts<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>機能</h3>
<p>これは、ドットで区切ったタグの一部を使ってタグを再構築する機能です。
次の例のように、インデックス指定だけでなく<code>${tag_parts[0..2]}</code>といった範囲表現にも対応しています。
<a href="https://github.com/y-ken/fluent-mixin-rewrite-tag-name/blob/master/test/mixin/test_rewrite_tag_name.rb#L97">test_emit_tag_parts</a>より抜粋したものを以下に転載します。</p>
<pre class="code lang-ruby" data-lang="ruby" data-unlink>tag = <span class="synSpecial">'</span><span class="synConstant">0.1.2.3.4</span><span class="synSpecial">'</span>
rules = [
{<span class="synConstant">:conf</span>=><span class="synSpecial">'</span><span class="synConstant">tag rewrited.${tag_parts[0]}</span><span class="synSpecial">'</span>, <span class="synConstant">:expect_tag</span> => <span class="synSpecial">'</span><span class="synConstant">rewrited.0</span><span class="synSpecial">'</span>},
{<span class="synConstant">:conf</span>=><span class="synSpecial">'</span><span class="synConstant">tag rewrited.${tag_parts[1]}</span><span class="synSpecial">'</span>, <span class="synConstant">:expect_tag</span> => <span class="synSpecial">'</span><span class="synConstant">rewrited.1</span><span class="synSpecial">'</span>},
{<span class="synConstant">:conf</span>=><span class="synSpecial">'</span><span class="synConstant">tag rewrited.${tag_parts[-1]}</span><span class="synSpecial">'</span>, <span class="synConstant">:expect_tag</span> => <span class="synSpecial">'</span><span class="synConstant">rewrited.4</span><span class="synSpecial">'</span>},
{<span class="synConstant">:conf</span>=><span class="synSpecial">'</span><span class="synConstant">tag rewrited.${tag_parts[-2]}</span><span class="synSpecial">'</span>, <span class="synConstant">:expect_tag</span> => <span class="synSpecial">'</span><span class="synConstant">rewrited.3</span><span class="synSpecial">'</span>},
{<span class="synConstant">:conf</span>=><span class="synSpecial">'</span><span class="synConstant">tag rewrited.${tag_parts[1..1000]}</span><span class="synSpecial">'</span>, <span class="synConstant">:expect_tag</span> => <span class="synSpecial">'</span><span class="synConstant">rewrited.1.2.3.4</span><span class="synSpecial">'</span>},
{<span class="synConstant">:conf</span>=><span class="synSpecial">'</span><span class="synConstant">tag rewrited.${tag_parts[0..2]}</span><span class="synSpecial">'</span>, <span class="synConstant">:expect_tag</span> => <span class="synSpecial">'</span><span class="synConstant">rewrited.0.1.2</span><span class="synSpecial">'</span>},
{<span class="synConstant">:conf</span>=><span class="synSpecial">'</span><span class="synConstant">tag rewrited.${tag_parts[0..-3]}</span><span class="synSpecial">'</span>, <span class="synConstant">:expect_tag</span> => <span class="synSpecial">'</span><span class="synConstant">rewrited.0.1.2</span><span class="synSpecial">'</span>},
{<span class="synConstant">:conf</span>=><span class="synSpecial">'</span><span class="synConstant">tag rewrited.${tag_parts[1..-2]}</span><span class="synSpecial">'</span>, <span class="synConstant">:expect_tag</span> => <span class="synSpecial">'</span><span class="synConstant">rewrited.1.2.3</span><span class="synSpecial">'</span>},
{<span class="synConstant">:conf</span>=><span class="synSpecial">'</span><span class="synConstant">tag rewrited.${tag_parts[-2..-1]}</span><span class="synSpecial">'</span>, <span class="synConstant">:expect_tag</span> => <span class="synSpecial">'</span><span class="synConstant">rewrited.3.4</span><span class="synSpecial">'</span>},
]
</pre>
<p>詳細な利用方法や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B9%A5%B1%A1%BC%A5%B9">ユースケース</a>については次のブログ記事が参考になります。<br></p>
<ul>
<li><a href="http://y-ken.hatenablog.com/entry/fluentd-how-to-use-tag_parts-placeholder">Fluentdのタグ書き換えが捗る「tag_parts」プレースホルダを使ってみよう - Y-Ken Studio</a><br>
<a href="http://y-ken.hatenablog.com/entry/fluentd-how-to-use-tag_parts-placeholder">http://y-ken.hatenablog.com/entry/fluentd-how-to-use-tag_parts-placeholder</a></li>
</ul>
<h2>利用例</h2>
<p>出力タグにホスト名を埋め込みたいという<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B9%A5%B1%A1%BC%A5%B9">ユースケース</a>での設定例は次の通りです。<br>
このMixin<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を導入することで、ちょっとした書き換えのために複数の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を経由させなくても良くなるのは良いことですね。</p>
<pre class="code lang-xml" data-lang="xml" data-unlink># Inputプラグインでの例
# ホスト名がweb01.example.comなら、tagは'message.web01.example.com'となります
<span class="synIdentifier"><source></span>
type your_cool_plugin
tag message.${hostname}
<span class="synIdentifier"></source></span>
# Outputプラグインでの例
# この場合には、tagは'td.foo_bar.web01.example.com'となります
<span class="synIdentifier"><match </span><span class="synType">app</span><span class="synIdentifier">.foo_bar></span>
type your_cool_plugin
tag td.${tag}.${hostname}
remove_tag_prefix app.
<span class="synIdentifier"></match></span>
</pre>
<p>しかしながらドットが含まれると都合が悪く、短縮ホスト名を使いたいケースがあると思います。<br>
その場合には、ホスト名取得コマンドを<code>hostname_command</code>オプションを用いて次のように指定します。</p>
<pre class="code lang-xml" data-lang="xml" data-unlink># Inputプラグインでの例
# ホスト名がweb01.example.comなら、tagは'message.web01'となります
<span class="synIdentifier"><source></span>
type your_cool_plugin
tag message.${hostname}
hostname_command hostname -s
<span class="synIdentifier"></source></span>
# Outputプラグインでの例
# この場合には、tagは'td.foo_bar.web01'となります
<span class="synIdentifier"><match </span><span class="synType">app</span><span class="synIdentifier">.foo_bar></span>
type your_cool_plugin
tag td.${tag}.${hostname}
remove_tag_prefix app.
hostname_command hostname -s
<span class="synIdentifier"></match></span>
</pre>
<h2>導入事例</h2>
<ul>
<li><p>Input<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a><br>
<a href="https://github.com/shun0102/fluent-plugin-dstat">https://github.com/shun0102/fluent-plugin-dstat</a></p></li>
<li><p>Output<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a><br>
<a href="https://github.com/y-ken/fluent-plugin-anonymizer">https://github.com/y-ken/fluent-plugin-anonymizer</a></p></li>
</ul>
<h2>導入方法</h2>
<p>このRewriteTagNameMixinを使うには、大まかには次の流れで行います。
これより、タグ書き換えに便利な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>機能の導入方法を、<code>fluent-plugin-foobar</code>という架空の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を例に解説します。</p>
<ol>
<li><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>ファイルの最上部にて、このmixin<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>をrequireする<br>
<code>require 'fluent/mixin/rewrite_tag_name'</code></p></li>
<li><p>Output<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の場合には、'remove_tag_prefix'オプションを使うためのMixin<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>もロードする<br>
<code>include Fluent::HandleTagNameMixin</code></p></li>
<li><p>HandleTagNameMixinをロードした後に、このRewriteTagNameをロードする<br>
<code>include Fluent::Mixin::RewriteTagName</code></p></li>
<li><p><code>Fluent::Engine.emit</code>する前に、次のコードを呼び出す<br>
<code>emit_tag = tag.dup</code>及び<code>filter_record(emit_tag, time, record)</code></p></li>
</ol>
<h4>事前準備</h4>
<p>次のようにgemspecを編集し、このMixin<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>をインストールします。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># 機能を追加したいプラグインのディレクトリへ移動する</span>
$ <span class="synStatement">cd</span> fluent-plugin-foobar
<span class="synComment"># gemspecファイルを編集する</span>
$ vim fluent-plugin-foobar.gemspec
<span class="synComment"># 依存ライブラリをインストールする</span>
<span class="synComment"># 単に`bundle install`としても構いません</span>
$ bundle <span class="synStatement">install</span> <span class="synSpecial">--path</span> vendor/bundle
</pre>
<p>gemspecファイル編集時には、次のように依存関係を追加します。<br>
実装例として<a href="https://github.com/y-ken/fluent-plugin-anonymizer/blob/master/fluent-plugin-anonymizer.gemspec#L22">fluent-plugin-anonymizer.gemspec</a>が参考になります。</p>
<pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synType">Gem</span>::<span class="synType">Specification</span>.new <span class="synStatement">do</span> |<span class="synIdentifier">spec</span>|
<span class="synComment"># ...中略...</span>
spec.add_runtime_dependency <span class="synSpecial">"</span><span class="synConstant">fluent-mixin-rewrite-tag-name</span><span class="synSpecial">"</span>
<span class="synStatement">end</span>
</pre>
<h4>Input<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>への実装例</h4>
<pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synPreProc">require</span> <span class="synSpecial">'</span><span class="synConstant">fluent/mixin/rewrite_tag_name</span><span class="synSpecial">'</span>
<span class="synPreProc">module</span> <span class="synType">Fluent</span>
<span class="synPreProc">class</span> <span class="synType">FooBarInput</span> < <span class="synType">Fluent</span>::<span class="synType">Input</span>
<span class="synType">Plugin</span>.register_input(<span class="synSpecial">'</span><span class="synConstant">foo_bar</span><span class="synSpecial">'</span>, <span class="synConstant">self</span>)
<span class="synComment"># ...中略...</span>
<span class="synPreProc">include</span> <span class="synType">Fluent</span>::<span class="synType">HandleTagNameMixin</span>
<span class="synPreProc">include</span> <span class="synType">Fluent</span>::<span class="synType">Mixin</span>::<span class="synType">RewriteTagName</span>
config_param <span class="synConstant">:hostname_command</span>, <span class="synConstant">:string</span>, <span class="synConstant">:default</span> => <span class="synSpecial">'</span><span class="synConstant">hostname</span><span class="synSpecial">'</span>
<span class="synComment"># ...中略...</span>
<span class="synPreProc">def</span> <span class="synIdentifier">configure</span>(conf)
<span class="synStatement">super</span>
<span class="synComment"># ...中略...</span>
<span class="synComment"># add a error handling </span>
<span class="synStatement">if</span> ( !<span class="synIdentifier">@tag</span> && !<span class="synIdentifier">@remove_tag_prefix</span> && !<span class="synIdentifier">@remove_tag_suffix</span> && !<span class="synIdentifier">@add_tag_prefix</span> && !<span class="synIdentifier">@add_tag_suffix</span> )
<span class="synStatement">raise</span> <span class="synType">Fluent</span>::<span class="synType">ConfigError</span>, <span class="synSpecial">"</span><span class="synConstant">foo_bar: missing remove_tag_prefix, remove_tag_suffix, add_tag_prefix or add_tag_suffix.</span><span class="synSpecial">"</span>
<span class="synStatement">end</span>
<span class="synPreProc">end</span>
<span class="synComment"># ...中略...</span>
<span class="synPreProc">def</span> <span class="synIdentifier">emit_message</span>(tag, message)
emit_tag = tag.dup
filter_record(emit_tag, time, message)
<span class="synType">Engine</span>.emit(emit_tag, <span class="synType">Engine</span>.now, message)
<span class="synPreProc">end</span>
<span class="synComment"># ...中略...</span>
<span class="synPreProc">end</span>
<span class="synPreProc">end</span>
</pre>
<h4>Output<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>への実装例</h4>
<pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synPreProc">require</span> <span class="synSpecial">'</span><span class="synConstant">fluent/mixin/rewrite_tag_name</span><span class="synSpecial">'</span>
<span class="synPreProc">class</span> <span class="synType">Fluent</span>
<span class="synPreProc">class</span> <span class="synType">FooBarOutput</span> < <span class="synType">Fluent</span>::<span class="synType">Output</span>
<span class="synType">Fluent</span>::<span class="synType">Plugin</span>.register_output(<span class="synSpecial">'</span><span class="synConstant">foo_bar</span><span class="synSpecial">'</span>, <span class="synConstant">self</span>)
<span class="synPreProc">include</span> <span class="synType">Fluent</span>::<span class="synType">Mixin</span>::<span class="synType">RewriteTagName</span>
config_param <span class="synConstant">:hostname_command</span>, <span class="synConstant">:string</span>, <span class="synConstant">:default</span> => <span class="synSpecial">'</span><span class="synConstant">hostname</span><span class="synSpecial">'</span>
<span class="synComment"># ...中略...</span>
<span class="synPreProc">def</span> <span class="synIdentifier">configure</span>(conf)
<span class="synStatement">super</span>
<span class="synComment"># ...中略...</span>
<span class="synComment"># add a error handling </span>
<span class="synStatement">if</span> ( !<span class="synIdentifier">@tag</span> && !<span class="synIdentifier">@remove_tag_prefix</span> && !<span class="synIdentifier">@remove_tag_suffix</span> && !<span class="synIdentifier">@add_tag_prefix</span> && !<span class="synIdentifier">@add_tag_suffix</span> )
<span class="synStatement">raise</span> <span class="synType">Fluent</span>::<span class="synType">ConfigError</span>, <span class="synSpecial">"</span><span class="synConstant">foo_bar: missing remove_tag_prefix, remove_tag_suffix, add_tag_prefix or add_tag_suffix.</span><span class="synSpecial">"</span>
<span class="synStatement">end</span>
<span class="synPreProc">end</span>
<span class="synComment"># ...中略...</span>
<span class="synPreProc">def</span> <span class="synIdentifier">emit</span>(tag, es, chain)
es.each <span class="synStatement">do</span> |<span class="synIdentifier">time</span>, <span class="synIdentifier">record</span>|
emit_tag = tag.dup
filter_record(emit_tag, time, record)
<span class="synType">Fluent</span>::<span class="synType">Engine</span>.emit(emit_tag, time, record)
<span class="synStatement">end</span>
chain.next
<span class="synPreProc">end</span>
<span class="synComment"># ...中略...</span>
<span class="synPreProc">end</span>
<span class="synPreProc">end</span>
</pre>
<h2>まとめ</h2>
<p>tag_parts等の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%B9%A5%DB%A5%EB%A5%C0">プレースホルダ</a>機能を、とても簡単に導入出来るので、是非お試しください。<br>
どの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>でも共通して行う実装には、積極的にMixin<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を利用して挙動の統一を図っていきたいですね。</p>
<p>また、ニーズ次第ではこれをRewriteTagNameMixinとして、Fluentd本体の<a href="https://github.com/fluent/fluentd/blob/master/lib/fluent/mixin.rb">fluentd/lib/fluent/mixin.rb</a>へマージするのも良いのでは無いかと考えています。</p>
yoshi-ken
LXCベースのDockerゲストマシンとホストマシンのディスクI/O性能を比較検証(Bonnie++編)
hatenablog://entry/12921228815718728677
2014-02-20T18:10:28+09:00
2014-02-22T20:27:48+09:00 dotCloudが開発しているLinuxコンテナ型仮想ソフト「Docker」が巷で話題ですね! これはLXCにストレージドライバとしてunionfsから派生したaufs(CentOSではLVMのThin Provisioning)を組み合わせた所がキモで、つまりファイルシステムの差分管理が出来る特徴があります。 なんだか仕組みを想像する限りディスクI/Oが遅そうな印象ですが、どの程度のものかベンチマークを取りました。
<p><a href="https://www.dotcloud.com/">dotCloud</a>が開発している<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>コンテナ型仮想ソフト「Docker」が巷で話題ですね!<br>
これはLXCにストレージドライバとしてunionfsから派生したaufs(<a class="keyword" href="http://d.hatena.ne.jp/keyword/CentOS">CentOS</a>ではLVMのThin Provisioning)を組み合わせた所がキモで、つまり<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%A1%A5%A4%A5%EB%A5%B7%A5%B9%A5%C6%A5%E0">ファイルシステム</a>の差分管理が出来る特徴があります。<br>
なんだか仕組みを想像する限りディスク<a class="keyword" href="http://d.hatena.ne.jp/keyword/I/O">I/O</a>が遅そうな印象ですが、どの程度のものか<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>を取りました。</p>
<h2>ストレージドライバ</h2>
<p>Dockerは元々aufsで作られていたのですが、それは<a href="http://blog.hansode.org/archives/docker.html">AUFS対応のカーネルを入れる</a>前提です。<br>
これは<a class="keyword" href="http://d.hatena.ne.jp/keyword/RedHat">RedHat</a>系<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%B7%A5%E7%A5%F3">ディストリビューション</a>への対応を行う上での大きなハードルでした。<br>
そこで同様にCoW(CopyOnWrite)を実現出来る<a href="http://i.sios.com/products/oss/redhat/tech_news/2012/12/20127lvm-thin-provisioning-lv.html">LVMのThin Provisioning</a>が採用されています。</p>
<p>ドライバがaufsなのかLVMを扱うためのdevicemapperかは<code>docker info</code>コマンドで次のように確認できます。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ sudo docker info
Containers: <span class="synConstant">232</span>
Images: <span class="synConstant">297</span>
Driver: devicemapper
Pool Name: docker<span class="synConstant">-253</span>:<span class="synConstant">0-1700795</span>-pool
Data file: /var/lib/docker/devicemapper/devicemapper/data
Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
Data Space Used: <span class="synConstant">31616</span>.<span class="synConstant">2</span> Mb
Data Space Total: <span class="synConstant">102400</span>.<span class="synConstant">0</span> Mb
Metadata Space Used: <span class="synConstant">40</span>.<span class="synConstant">6</span> Mb
Metadata Space Total: <span class="synConstant">2048</span>.<span class="synConstant">0</span> Mb
</pre>
<p>devicemapperに至る経緯などに関しては次のページが参考になります。</p>
<ul>
<li>Docker ストレージドライバによる <a class="keyword" href="http://d.hatena.ne.jp/keyword/RHEL">RHEL</a>/<a class="keyword" href="http://d.hatena.ne.jp/keyword/CentOS">CentOS</a> 対応について - Shin x blog<br>
<a href="http://www.1x1.jp/blog/2013/12/storage-driver-on-docker07.html">http://www.1x1.jp/blog/2013/12/storage-driver-on-docker07.html</a></li>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Red%20Hat">Red Hat</a> and Docker Collaborate | Docker Blog<br>
<a href="http://blog.docker.io/2013/09/red-hat-and-docker-collaborate/">http://blog.docker.io/2013/09/red-hat-and-docker-collaborate/</a></li>
</ul>
<h2>計測方法</h2>
<p>bonnie++を用いて計測を4回行い、その結果の平均値を利用しています。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ wget https://github.com/y-ken/bonnie/raw/master/bonnie++
$ <span class="synStatement">chmod</span> <span class="synConstant">755</span> bonnie++
$ ./bonnie++ <span class="synSpecial">-u</span> nobody <span class="synSpecial">-d</span> /tmp/
</pre>
<p>なお、<a href="http://www.drk7.jp/MT/archives/001448.html">bonnie++ で I/O 性能を測定 (Linux/Unix での IO ベンチマークソフト) - drk7jp</a>を参考に、<code>MinTime (0.01)</code>に変更してビルドしたものを利用しました。</p>
<h2>計測対象</h2>
<p>OpenStack Novaを用いた<a class="keyword" href="http://d.hatena.ne.jp/keyword/KVM">KVM</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>であるConoHa (CPU2コア メモリ1GB HDD100GB)上のCentOS6.5環境にDockerコンテナを起ち上げて計測しました。docker関連の<a class="keyword" href="http://d.hatena.ne.jp/keyword/RPM">RPM</a>バージョンは次の通りです。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ <span class="synStatement">rpm</span> <span class="synSpecial">-qa</span> | <span class="synStatement">egrep</span> <span class="synStatement">"</span><span class="synConstant">^(lxc|docker|kernel|bridge)</span><span class="synStatement">"</span> | <span class="synStatement">sort</span>
bridge-utils<span class="synConstant">-1</span>.<span class="synConstant">2-10</span>.el6.x86_64
docker-io<span class="synConstant">-0</span>.<span class="synConstant">7</span>.<span class="synConstant">6-2</span>.el6.x86_64
kernel<span class="synConstant">-2</span>.<span class="synConstant">6</span>.<span class="synConstant">32-431</span>.<span class="synConstant">5</span>.<span class="synConstant">1</span>.el6.x86_64
kernel-devel<span class="synConstant">-2</span>.<span class="synConstant">6</span>.<span class="synConstant">32-431</span>.<span class="synConstant">5</span>.<span class="synConstant">1</span>.el6.x86_64
kernel-firmware<span class="synConstant">-2</span>.<span class="synConstant">6</span>.<span class="synConstant">32-431</span>.<span class="synConstant">5</span>.<span class="synConstant">1</span>.el6.noarch
kernel-headers<span class="synConstant">-2</span>.<span class="synConstant">6</span>.<span class="synConstant">32-431</span>.<span class="synConstant">5</span>.<span class="synConstant">1</span>.el6.x86_64
lxc<span class="synConstant">-0</span>.<span class="synConstant">9</span>.<span class="synConstant">0-2</span>.el6.x86_64
lxc-libs<span class="synConstant">-0</span>.<span class="synConstant">9</span>.<span class="synConstant">0-2</span>.el6.x86_64
</pre>
<p>そしてDockerコンテナで作る環境は実にシンプルで、Dockerfileの中身は<code>FROM centos</code>だけです。この環境にて、3種類の計測を行いました。</p>
<ul>
<li><p>Guest local<br>
Guestのローカルディレクトリに対する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>結果</p></li>
<li><p>Guest shared<br>
ホスト側のディレクトリをGuestのローカル<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%A1%A5%A4%A5%EB%A5%B7%A5%B9%A5%C6%A5%E0">ファイルシステム</a>に重ねた(マウントでは無い)ディレクトリの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>結果<br>
参考記事:<a href="http://cpw.hatenadiary.jp/entry/2013/08/17/024028">Dockerでコンテナからホストのディレクトリをマウントする - cpw's diary</a></p></li>
<li><p>Host<br>
ホスト側のローカルディレクトリに対する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>結果</p></li>
</ul>
<h1>計測結果</h1>
<p>差分管理する箇所への<a class="keyword" href="http://d.hatena.ne.jp/keyword/I/O">I/O</a>の性能劣化は見られますが、<a href="http://docs.docker.io/en/latest/use/working_with_volumes/">Share Directories via Volumes</a>を用いた場合の性能は健闘しています。</p>
<h5>ホスト側性能を100とした場合の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%EA%C2%D0%C0%AD">相対性</a>能を比較</h5>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140221/20140221120442_original.png" alt="f:id:yoshi-ken:20140221120442p:plain" title="f:id:yoshi-ken:20140221120442p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C2%D0%BF%F4">対数</a>グラフでの比較</h5>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140221/20140221120447_original.png" alt="f:id:yoshi-ken:20140221120447p:plain" title="f:id:yoshi-ken:20140221120447p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>計測データは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Github">Github</a>のGistに載せたので、そちらをご覧ください。<br>
<a href="https://gist.github.com/y-ken/9108610">https://gist.github.com/y-ken/9108610</a></p>
<h1>まとめ</h1>
<p>本日は「Docker」が使う<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%A1%A5%A4%A5%EB%A5%B7%A5%B9%A5%C6%A5%E0">ファイルシステム</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>を行いました。<br>
ディスク<a class="keyword" href="http://d.hatena.ne.jp/keyword/I/O">I/O</a>性能は相対的に落ちるがデメリットと言うほどでも無く、体感的にも十分実用性の高い速度が出ています。<br>
むしろポータビリティ性の高い再現可能な環境がとても容易に手に入るというメリットの方が大きいと感じました。<br>
immutable infrastructureの一つの形であるDocker、かなり良さそうです!</p>
yoshi-ken
elasticsearch-1.0.0正式版がリリースされたので、0.9.xからのアップグレード手順をまとめました(追記あり)
hatenablog://entry/12921228815718319955
2014-02-13T17:35:24+09:00
2014-04-17T13:20:15+09:00 Elasticsearch 1.0.0 released ということで、早速アップデートしてみました!
<p><a href="http://www.elasticsearch.org/blog/1-0-0-released/">Elasticsearch 1.0.0 released</a> ということで、早速アップデートしてみました!</p>
<p><blockquote class="twitter-tweet" lang="HASH(0x83b4408)"><p>elasticsearchを0.90.3から1.0.0へ<a class="keyword" href="http://d.hatena.ne.jp/keyword/rpm">rpm</a>で更新しました。 /etc/elasticsearch/elasticsearch.ymlの差分もあるので、オリジナルに加えていた変更点の反映・<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の更新も済ませたらesを再起動。数分応答返さず焦ったが無事完了!</p>— Y.Kentaro (@yoshi_ken) <a href="https://twitter.com/yoshi_ken/statuses/433819552309211136">February 13, 2014</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>本日は、このアップグレードを行った記録を紹介します。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># アップデート前</span>
$ <span class="synStatement">rpm</span> <span class="synSpecial">-q</span> elasticsearch
elasticsearch<span class="synConstant">-0</span>.<span class="synConstant">90</span>.<span class="synConstant">3-1</span>.noarch
<span class="synComment"># アップデート後</span>
$ <span class="synStatement">rpm</span> <span class="synSpecial">-q</span> elasticsearch
elasticsearch<span class="synConstant">-1</span>.<span class="synConstant">0</span>.<span class="synConstant">0-1</span>.noarch
</pre>
<h3>追記</h3>
<p>公式のアップデート手順も公開されておりますので、合わせてご確認ください。<br />
v0.9までのものと、v1.0以降の手順それぞれが公開されています。<br />
<a href="http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/setup-upgrade.html#rolling-upgrades">http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/setup-upgrade.html#rolling-upgrades</a></p>
<h3>アップデート手順</h3>
<p>アップグレードは次の流れで行います。</p>
<ul>
<li>インストール済み<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を確認</li>
<li>elasticsearchの停止</li>
<li>elasticsearchのアップグレード</li>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>のアップグレード</li>
<li>elasticsearchの起動</li>
<li>elasticsearchの動作確認</li>
<li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の動作確認</li>
</ul>
<h4>インストール済み<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を確認</h4>
<p>後ほど再インストールするため、次のように<a class="keyword" href="http://d.hatena.ne.jp/keyword/curl">curl</a>コマンドを用いて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の一覧を確認します。<br />
このリストに<code>site:true</code>と記載されているsite<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>に関しては、稼働中の更新を行えますが、<code>site:false</code>であるkuromojiは再起動が必要です。<br>
そのため今回は停止中に更新を行う手順としますが、もしsite<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>のみである場合には、elasticsearchのバージョンアップして起動した後に再インストールする対応でも問題ありません。</p>
<pre class="code lang-javascript" data-lang="javascript" data-unlink>$ curl -XGET <span class="synConstant">'http://localhost:9200/_nodes/_all?plugin=true&pretty'</span>
<span class="synIdentifier">{</span>
<span class="synConstant">"ok"</span> : <span class="synConstant">true</span>,
<span class="synConstant">"cluster_name"</span> : <span class="synConstant">"********"</span>,
<span class="synConstant">"nodes"</span> : <span class="synIdentifier">{</span>
<span class="synConstant">"*********-***********"</span> : <span class="synIdentifier">{</span>
<span class="synConstant">"name"</span> : <span class="synConstant">"**********"</span>,
<span class="synConstant">"transport_address"</span> : <span class="synConstant">"inet[/*********:9300]"</span>,
<span class="synConstant">"version"</span> : <span class="synConstant">"0.90.3"</span>,
<span class="synConstant">"http_address"</span> : <span class="synConstant">"inet[/*********:9200]"</span>,
<span class="synConstant">"plugins"</span> : <span class="synIdentifier">[</span> <span class="synIdentifier">{</span>
<span class="synConstant">"name"</span> : <span class="synConstant">"analysis-kuromoji"</span>,
<span class="synConstant">"description"</span> : <span class="synConstant">"Kuromoji analysis support"</span>,
<span class="synConstant">"jvm"</span> : <span class="synConstant">true</span>,
<span class="synConstant">"site"</span> : <span class="synConstant">false</span>
<span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>
<span class="synConstant">"name"</span> : <span class="synConstant">"HQ"</span>,
<span class="synConstant">"description"</span> : <span class="synConstant">"No description found for HQ."</span>,
<span class="synConstant">"url"</span> : <span class="synConstant">"/_plugin/HQ/"</span>,
<span class="synConstant">"jvm"</span> : <span class="synConstant">false</span>,
<span class="synConstant">"site"</span> : <span class="synConstant">true</span>
<span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>
<span class="synConstant">"name"</span> : <span class="synConstant">"bigdesk"</span>,
<span class="synConstant">"description"</span> : <span class="synConstant">"No description found for bigdesk."</span>,
<span class="synConstant">"url"</span> : <span class="synConstant">"/_plugin/bigdesk/"</span>,
<span class="synConstant">"jvm"</span> : <span class="synConstant">false</span>,
<span class="synConstant">"site"</span> : <span class="synConstant">true</span>
<span class="synIdentifier">}</span>, <span class="synIdentifier">{</span>
<span class="synConstant">"name"</span> : <span class="synConstant">"head"</span>,
<span class="synConstant">"description"</span> : <span class="synConstant">"No description found for head."</span>,
<span class="synConstant">"url"</span> : <span class="synConstant">"/_plugin/head/"</span>,
<span class="synConstant">"jvm"</span> : <span class="synConstant">false</span>,
<span class="synConstant">"site"</span> : <span class="synConstant">true</span>
<span class="synIdentifier">}</span> <span class="synIdentifier">]</span>
<span class="synIdentifier">}</span>
<span class="synIdentifier">}</span>
<span class="synIdentifier">}</span>
</pre>
<h4>elasticsearchの停止</h4>
<p><a href="http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/setup-upgrade.html#rolling-upgrades">公式ガイド</a>を参考に、サービスを止めます。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ curl <span class="synSpecial">-XPUT</span> <span class="synStatement">'</span><span class="synConstant">http://localhost:9200/_all/_settings</span><span class="synStatement">'</span> <span class="synSpecial">-d</span> <span class="synStatement">'</span><span class="synConstant">{</span>
<span class="synConstant"> "index": {</span>
<span class="synConstant"> "translog.disable_flush": "true"</span>
<span class="synConstant"> }</span>
<span class="synConstant">}</span><span class="synStatement">'</span>
</pre>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ curl <span class="synSpecial">-XPUT</span> <span class="synStatement">'</span><span class="synConstant">http://localhost:9200/_cluster/settings</span><span class="synStatement">'</span> <span class="synSpecial">-d</span> <span class="synStatement">'</span><span class="synConstant">{</span>
<span class="synConstant"> "transient" : {</span>
<span class="synConstant"> "cluster.routing.allocation.disable_allocation": "true"</span>
<span class="synConstant"> }</span>
<span class="synConstant">}</span><span class="synStatement">'</span>
</pre>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># service elasticsearch stopでも可</span>
$ sudo /etc/init.d/elasticsearch <span class="synStatement">stop</span>
Stopping elasticsearch: <span class="synStatement">[</span> OK <span class="synStatement">]</span>
</pre>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ curl <span class="synSpecial">-XPUT</span> <span class="synStatement">'</span><span class="synConstant">http://localhost:9200/_all/_settings</span><span class="synStatement">'</span> <span class="synSpecial">-d</span> <span class="synStatement">'</span><span class="synConstant">{</span>
<span class="synConstant"> "index": {</span>
<span class="synConstant"> "translog.disable_flush": "false"</span>
<span class="synConstant"> }</span>
<span class="synConstant">}</span><span class="synStatement">'</span>
$ curl <span class="synSpecial">-XPUT</span> <span class="synStatement">'</span><span class="synConstant">http://localhost:9200/_cluster/settings</span><span class="synStatement">'</span> <span class="synSpecial">-d</span> <span class="synStatement">'</span><span class="synConstant">{</span>
<span class="synConstant"> "transient" : {</span>
<span class="synConstant"> "cluster.routing.allocation.disable_allocation": "false"</span>
<span class="synConstant"> }</span>
<span class="synConstant">}</span><span class="synStatement">'</span>
</pre>
<p>なお、1台だけのシングル構成であっても、停止前に次の記事にある通りに自動再配置をOFFにしてからアップデートすることをお勧めします。データ量が多いと1台だけでもcluster healthがred状態になり、通常稼働するまでの時間を要すためです。</p>
<ul>
<li>ElasticSearchでノードを落とす際にshardの自動再配置を止める作法 - iをgに変えるとorangeになることに気づいたoranieの日記<br>
<a href="http://d.hatena.ne.jp/oranie/20130927/1380259209">http://d.hatena.ne.jp/oranie/20130927/1380259209</a></li>
</ul>
<h4>elasticsearchのアップグレード</h4>
<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/rpm">rpm</a>コマンド等でアップグレードします。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ <span class="synStatement">cd</span> /usr/<span class="synStatement">local</span>/src
$ sudo wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch<span class="synConstant">-1</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.noarch.<span class="synStatement">rpm</span>
$ sudo <span class="synStatement">rpm</span> <span class="synSpecial">-Uvh</span> elasticsearch<span class="synConstant">-1</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.noarch.<span class="synStatement">rpm</span>
</pre>
<p>なお、<a class="keyword" href="http://d.hatena.ne.jp/keyword/yum">yum</a>コマンドの方が都合の良い、etckeeperなどを利用している場合には、<a class="keyword" href="http://d.hatena.ne.jp/keyword/rpm">rpm</a>ではなく次のコマンドでアップグレードしましょう。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ <span class="synStatement">cd</span> /usr/<span class="synStatement">local</span>/src
$ sudo wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch<span class="synConstant">-1</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.noarch.<span class="synStatement">rpm</span>
$ sudo yum upgrade elasticsearch<span class="synConstant">-1</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.noarch.<span class="synStatement">rpm</span>
</pre>
<h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>のアップグレード</h4>
<p>それでは各<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>をアップグレードしていきます。<br>
どうやら、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>のupgradeコマンドは無いようですね。<a href="http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/modules-plugins.html">公式ページに記載の通り</a>、removeした後にinstallする手順で進めます。</p>
<p>まずはkuromojiから。<br>
これはインストール時にバージョンを毎回指定していますが、アンインストール時の指定は不要です。<br>
<a href="https://github.com/elasticsearch/elasticsearch-analysis-kuromoji">elasticsearch/elasticsearch-analysis-kuromoji - GitHub</a>のREADMEでは2.0.0.RC1が最新のようなのでそれを使います。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># kuromoji</span>
$ sudo bin/plugin <span class="synSpecial">-remove</span> elasticsearch/elasticsearch-analysis-kuromoji
-<span class="synStatement">></span> Removing elasticsearch/elasticsearch-analysis-kuromoji
Removed elasticsearch/elasticsearch-analysis-kuromoji
$ sudo bin/plugin <span class="synSpecial">-install</span> elasticsearch/elasticsearch-analysis-kuromoji/<span class="synConstant">2</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.RC1
-<span class="synStatement">></span> Installing elasticsearch/elasticsearch-analysis-kuromoji/<span class="synConstant">2</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.RC1...
Trying http://download.elasticsearch.org/elasticsearch/elasticsearch-analysis-kuromoji/elasticsearch-analysis-kuromoji<span class="synConstant">-2</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.RC1.zip...
Downloading ...................................................................................................................................DONE
Installed elasticsearch/elasticsearch-analysis-kuromoji/<span class="synConstant">2</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.RC1 into /usr/share/elasticsearch/plugins/analysis-kuromoji
</pre>
<p>次に、bigdesk, HQ, head<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を順番にアップグレードしていきます。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># bigdesk</span>
$ sudo bin/plugin <span class="synSpecial">-remove</span> lukas-vlcek/bigdesk
-<span class="synStatement">></span> Removing lukas-vlcek/bigdesk
Removed lukas-vlcek/bigdesk
$ sudo bin/plugin <span class="synSpecial">-install</span> lukas-vlcek/bigdesk
-<span class="synStatement">></span> Installing lukas-vlcek/bigdesk...
Trying https://github.com/lukas-vlcek/bigdesk/archive/master.zip...
Downloading ......................DONE
Installed lukas-vlcek/bigdesk into /usr/share/elasticsearch/plugins/bigdesk
Identified as a _site plugin, moving to _site structure ...
</pre>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># HQ</span>
$ sudo ./bin/plugin <span class="synSpecial">-remove</span> royrusso/elasticsearch-HQ
-<span class="synStatement">></span> Removing royrusso/elasticsearch-HQ
Removed royrusso/elasticsearch-HQ
$ sudo ./bin/plugin <span class="synSpecial">-install</span> royrusso/elasticsearch-HQ
-<span class="synStatement">></span> Installing royrusso/elasticsearch-HQ...
Trying https://github.com/royrusso/elasticsearch-HQ/archive/master.zip...
Downloading ...................................................................................................................................DONE
Installed royrusso/elasticsearch-HQ into /usr/share/elasticsearch/plugins/HQ
Identified as a _site plugin, moving to _site structure ...
</pre>
<pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># head</span>
$ sudo bin/plugin <span class="synSpecial">--remove</span> mobz/elasticsearch-head
-<span class="synStatement">></span> Removing mobz/elasticsearch-head
Removed mobz/elasticsearch-head
$ sudo bin/plugin <span class="synSpecial">--install</span> mobz/elasticsearch-head
-<span class="synStatement">></span> Installing mobz/elasticsearch-head...
Trying https://github.com/mobz/elasticsearch-head/archive/master.zip...
Downloading .......................................................DONE
Installed mobz/elasticsearch-head into /usr/share/elasticsearch/plugins/head
Identified as a _site plugin, moving to _site structure ...
</pre>
<h4>elasticsearchの起動</h4>
<p>サービスを起ち上げます。もちろん<code>service elasticsearch start</code>コマンドでも構いません。</p>
<pre class="code lang-sh" data-lang="sh" data-unlink>$ sudo /etc/init.d/elasticsearch <span class="synStatement">start</span>
Starting elasticsearch: <span class="synStatement">[</span> OK <span class="synStatement">]</span>
</pre>
<h4>elasticsearchの動作確認</h4>
<p>indexやshardの数にもよりますが、サービスを起ち上げてから数秒〜1分程度はリクエストを受け付けなくなります。<br>
焦らずtopコマンド等でモニタリングし、CPU・iowaitが落ち着くのを待ちましょう。</p>
<pre class="code lang-" data-lang="" data-unlink># 起動直後はしばらく繋がりません
$ curl -XGET 'http://localhost:9200/'
curl: (7) couldn't connect to host
# しばらくすると、繋がるようになります
$ curl -XGET 'http://localhost:9200/'
{
"status" : 200,
"name" : "Shadrac",
"version" : {
"number" : "1.0.0",
"build_hash" : "a46900e9c72c0a623d71b54016357d5f94c8ea32",
"build_timestamp" : "2014-02-12T16:18:34Z",
"build_snapshot" : false,
"lucene_version" : "4.6"
},
"tagline" : "You Know, for Search"
}</pre>
<h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の動作確認</h4>
<p>HQ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を開いてみましょう。<br>
これまで通りインデックスも認識されていますので完璧です。</p>
<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/y/yoshi-ken/20140213/20140213171802.png" alt="f:id:yoshi-ken:20140213171802p:plain" title="f:id:yoshi-ken:20140213171802p:plain" class="hatena-fotolife" itemprop="image"></span></p>
<p>以上です。お疲れ様でした!</p>
<h3>設定ファイルの差分</h3>
<p>設定ファイルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/GC">GC</a>まわりには、設定名の変更もあるようですね。</p>
<pre class="code lang-diff" data-lang="diff" data-unlink> ################################## GC Logging ################################
<span class="synSpecial">-#monitor.jvm.gc.ParNew.warn: 1000ms</span>
<span class="synSpecial">-#monitor.jvm.gc.ParNew.info: 700ms</span>
<span class="synSpecial">-#monitor.jvm.gc.ParNew.debug: 400ms</span>
<span class="synSpecial">-</span>
<span class="synSpecial">-#monitor.jvm.gc.ConcurrentMarkSweep.warn: 10s</span>
<span class="synSpecial">-#monitor.jvm.gc.ConcurrentMarkSweep.info: 5s</span>
<span class="synSpecial">-#monitor.jvm.gc.ConcurrentMarkSweep.debug: 2s</span>
<span class="synIdentifier">+#monitor.jvm.gc.young.warn: 1000ms</span>
<span class="synIdentifier">+#monitor.jvm.gc.young.info: 700ms</span>
<span class="synIdentifier">+#monitor.jvm.gc.young.debug: 400ms</span>
<span class="synIdentifier">+</span>
<span class="synIdentifier">+#monitor.jvm.gc.old.warn: 10s</span>
<span class="synIdentifier">+#monitor.jvm.gc.old.info: 5s</span>
<span class="synIdentifier">+#monitor.jvm.gc.old.debug: 2s</span>
</pre>
<p>詳細については次のgistページをご覧ください。<br>
<a href="https://gist.github.com/8970984">The differences of elasticsearch v0.99.3 and v1.0.0 configuration.</a></p>
<h3>まとめ</h3>
<p>0.9から1.0へはとても簡単にアップグレードできます。もし全台を計画停止の上でメンテナンスする場合には、oranieさんの<a href="http://d.hatena.ne.jp/oranie/20130927/1380259209">ElasticSearchでノードを落とす際にshardの自動再配置を止める作法</a>も参考にすると良いと思います!</p>
<p>それでは楽しいElasticsearchライフを!!!</p>
<p>追記:</p>
yoshi-ken
第3回elasticsearch勉強会でトークしました #elasticsearchjp
hatenablog://entry/12921228815718145915
2014-02-10T12:19:28+09:00
2014-02-20T18:11:13+09:00 2014年2月7日にリクルートテクノロジーズで開催された「第3回 ElasticSearch勉強会」でトークしてきました!前回の皆様の発表はKibanaに関する情報がメインでしたが、今回は検索技術中心のガチな内容でとても楽しかったです。 懇親会では今回発表したYamabikoのコア部分である fluent-plugin-mysql-replicator を実際に利用している方もいらっしゃるなど、感謝感激雨あられでした!ありがとうございます! その他にも2社合同で合同勉強会を開催しようといったお話を頂けるなど、実りのある時間を過ごせました。
<p>2014年2月7日に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%AF%A5%EB%A1%BC%A5%C8">リクルート</a>テクノロジーズで開催された「第3回 ElasticSearch勉強会」でトークしてきました!前回の皆様の発表はKibanaに関する情報がメインでしたが、今回は検索技術中心のガチな内容でとても楽しかったです。</p>
<p>懇親会では今回発表したYamabikoのコア部分である <a href="http://y-ken.hatenablog.com/entry/fluent-plugin-mysql-replicator-has-released">fluent-plugin-mysql-replicator</a> を実際に利用している方もいらっしゃるなど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%B6%BC%D5%B4%B6%B7%E3%B1%AB%A4%A2%A4%E9%A4%EC">感謝感激雨あられ</a>でした!ありがとうございます!<br/>
その他にも2社合同で合同勉強会を開催しようといったお話を頂けるなど、実りのある時間を過ごせました。</p>
<h2>発表テーマ</h2>
<p>今回は「<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>ユーザ視点での小さく始めるElasticsearch」という発表です。</p>
<p>ログビジュアライズアプリであるKibanaを通じてElasticsearchに触れる方も少なからずおり、世間ではKibanaとセットで使う物であるような雰囲気をにおわせていますが、実はElasticsearchは単体で使える優れた検索<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DF%A5%C9%A5%EB%A5%A6%A5%A7%A5%A2">ミドルウェア</a>でもあるのです。</p>
<p>Elasticsearchを検索<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DF%A5%C9%A5%EB%A5%A6%A5%A7%A5%A2">ミドルウェア</a>として使う際のTipsを<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>ユーザ視点でお話ししようと、今回登壇させて頂けることになりました。
発表中に紹介した、異種<a class="keyword" href="http://d.hatena.ne.jp/keyword/RDB">RDB</a>との連携を行うプロダクト<a href="http://www.slideshare.net/y-ken/yamabiko-replicate-mysql-table-to-elasticsearch">Yamabiko</a>はスモールスタートを支える便利な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DF%A5%C9%A5%EB%A5%A6%A5%A7%A5%A2">ミドルウェア</a>としても使えると思います。よろしければ是非触ってみてください。不明点などあれば<a href="https://twitter.com/yoshi_ken">@yoshi_ken</a>までメッセージください!</p>
<p>発表資料は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Slideshare">Slideshare</a>にアップしております。</p>
<iframe src="http://www.slideshare.net/slideshow/embed_code/31016362" width="597" height="486" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px 1px 0; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
<p> <div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/y-ken/introducing-elasticsearch-for-mysql-users" title="MySQLユーザ視点での小さく始めるElasticsearch" target="_blank">MySQLユーザ視点での小さく始めるElasticsearch</a> </strong> from <strong><a href="http://www.slideshare.net/y-ken" target="_blank">Kentaro Yoshida</a></strong> </div></p>
<h2>他に参加された方のブログ記事(随時更新)</h2>
<ul>
<li><p>第3回elasticsearch勉強会を開催しました! #elasticsearchjp - @johtaniの日記 2nd<br/>
<a href="http://blog.johtani.info/blog/2014/02/08/hold-3rd-elasticsaerch-meetup-in-tokyo/">http://blog.johtani.info/blog/2014/02/08/hold-3rd-elasticsaerch-meetup-in-tokyo/</a></p></li>
<li><p>第3回elasticsearch勉強会 [2014/02/07(Fri.)]に参加してきました - ほわいとぼーど<br/>
<a href="http://a3no.hatenablog.com/entry/2014/02/09/022405">http://a3no.hatenablog.com/entry/2014/02/09/022405</a></p></li>
<li><p>第 3 回 elasticsearch 勉強会に行ってきた - ようへいの日々精進<br/>
<a href="http://inokara.hateblo.jp/entry/2014/02/07/233057">http://inokara.hateblo.jp/entry/2014/02/07/233057</a></p></li>
<li><p>[-*煙猴*-]: 第3回elasticsearch勉強会に参加してきた<br/>
<a href="http://www.smokeymonkey.net/2014/02/3elasticsearch.html">http://www.smokeymonkey.net/2014/02/3elasticsearch.html</a></p></li>
</ul>
yoshi-ken