t0mmy.log

日々のコンピュータ周りのこと

Elastic stack 1node運用

この記事は、Elastic stack Advent Calendar 2016の10日目の記事です。

Elastic Stackがっつりお世話になっています。
下はFilebeatから、上はKibanaまで使用していますが、Filebeat以外は1node構成です。
1node構成でのログデータ取込みについて書きたいと思います。
CentOS6.8、Elastic Stack5.02で検証しています。

構成

f:id:t0mmy_jpn:20161208230126p:plain

1node構成では、スケールアウトをしない前提で構築することが多いと思います。
Kibanaの検索と集計も重要ですが、ログデータ取込みが所定時間内に完了することも重要です。
そこで、今回はログデータ取込みの処理速度に焦点をあてます。

処理速度に関わる大きな要素

f:id:t0mmy_jpn:20161208230132p:plain

ログデータを加工すると遅くなる

  • LogstashのFilter処理は、ログデータを加工するので、処理速度が下がります。
  • ElasticsearchのTemplate処理からのmappingは、ログデータを加工するので、処理速度が下がります。
    (例えば、Logstashでパースした値を数値としてElasticsearchに代入する場合、String -> Integerの変換がされる)

Kibanaで表示したいグラフを決めて、なるべく少ない加工をするようにします。

取込むファイルサイズを減らす

処理するファイルサイズを小さくすれば、
処理速度を上げる必要は減るので、一考の余地ありです。

加工はCPUがやっている

今回の1node構成の場合、大抵のケースはCPUを増強することで解決します。
大体2Core -> 4Coreで1.5倍に向上しました。
後はnodeを増やしてスケールアウトするしか…。
ElasticStackはデフォルト設定で割とやってくれているイメージはありますが、
どうしてもチューニングが必要な場合は、次の公式ブログが参考になります。

Logstash configuration tuning
Elasticsearchインデックス作成におけるパフォーマンス考慮事項

Logstashで処理速度を計測する

チューニングするにしても、処理速度を把握しないとどうしようもありません。
LogstashのFilterにはmetricsという便利なプラグインがあります。
metricsプラグインはイベント単位での処理速度を教えてくれます。
イベントとは、LogstashやFilebeatが処理する単位です。
multilineプラグインを使ってなければ、ログファイル1行が1イベントです。

metricsプラグインの使い方

次のようなLogstashの設定ファイルを書きます。
それぞれを/etc/logstash/conf.dに格納し、 initctl start logstashで運用します。

input.conf
Filebeatでdocument_typeでログを仕分けている前提

input {
    beats {
        port => 5043
    }
}

filter.conf

filter {
    grok {
        /* ログのフィルタ処理 */
    }
    metrics {
        meter => "events"
        add_tag => "metric"
        flush_interval => 10
    }
}

output.conf
syslog-*は適宜変更

output {
    if [@metadata][type] == "syslog-secure" or [@metadata][type] == "syslog-messages" {
        elasticsearch {
            hosts => [ "localhost:9200" ]
            manage_template => false
            index => [ "%{[@metadata][type]}-%{+xxxx.ww}" ]
            document_type => "%{[@metadata][type]}"
        }
    }
    if "metric" in [tags] {
        elasticsearch {
            hosts => [ "localhost:9200" ]
            index => [ "logstash-metrics-%{+YYYY}" ]
        }
    }
}

metricsプラグインのグラフ例

logstash-metrics-*インデックスに値が格納されますので、Kibanaでグラフにできます。
Metricbeatと組み合わせた例です。

f:id:t0mmy_jpn:20161208230112p:plain

取込処理が終わったことを検知する

Logstashのmetricの値はElasticsearchに格納されているので、
次のようなスクリプトを使えばできます。Python2でElasticsearchのsearchAPIを使ってます。

#!/usr/bin/env python
# -*- cording: utf-8 -*-

import json
import urllib
import os

host = "localhost"
index = "logstash-metrics-*"
url = "http://"+ host + ":9200/" + index + "/_search"
jsonfile = "get_metric.json"

dirpath = os.path.abspath(os.path.dirname(__file__))
jsonpath = os.path.join(dirpath, jsonfile)
f = open(jsonpath)
data = json.load(f)
f.close()

query = json.dumps(data)
response = urllib.urlopen(url, query)
result = json.loads(response.read())
rate = result["aggregations"]["rate"]["value"]
print(rate)

rate_round = round(rate)
if rate_round == 0:
    print("All data is transmitted!")
else:
    print("Filebeat is still running : " + str(rate_round))

get_metric.json
最新5分間のevents.rate_1mの最小値を得るクエリ

{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "now-5m",
        "lte": "now"
      }
    }
  },
  "aggs": {
    "rate": {
      "min": {"field": "events.rate_1m"}
    }
  },
  "size": 0
}

検知の活用例

例えば、過去のサンプルデータを順々に投入していくテスト等で使っています。
過去3ヶ月分のデータを日毎のログファイルとして保存してあるので、
Filebeatの設定ファイルを書き換えるようにしてあげれば、3ヶ月分の疑似運用テストができたり。

f:id:t0mmy_jpn:20161208230117p:plain

処理速度以外に1nodeで気を付ける点

シャード数を少なくしましょう。1シャード当たり1GB-1.5GBに収まるようにします。 ログデータによって、日毎、週毎等でインデックスを作成する頻度を変えています。
インデックス当たりのシャード数を1に、レプリカを0にするテンプレートをElasticsearchに入れましょう。
他のテンプレートはorderの値を1以上に設定します。

{
    "order": 0,
    "template": "*",
    "settings": {
        "index": {
            "number_of_replicas": 0,
            "number_of_shards": 1,
            }
        }
    }
}

まとめ

1nodeで構築する場合は、Kibanaに表示する内容に制限をかけるほうがいいと思います。
それでもダメならCPUを増強しましょう!それでもダメなら1nodeやめましょう!
身も蓋もないまとめですが、以上がElastic stack Advent Calendar 2016の10日目の記事でした。

WEB+DB Vol.94のOSSによるデータ分析基盤の構築メモ

WEB+DB PRESS Vol.94のOSSによるデータ分析基盤の構築で、
Embulk、Re:dash、Digdagを触ってみました。
Docker Machineが仮想マシンで使えない、CentOSだとRe:dash入らない等、
無知ゆえに結構手こずりました。 連載の行間メモ中心です。

環境

Ubuntu Server 14.04.5 LTS
Mac持ってないからしょうがなく、Re:dashの要求仕様により選定。)

WindowsのVirtual Box上で仮想マシン2台で構築。
Virtual Boxのネットワーク設定はアダプター1でブリッジ接続。
WindowsからターミナルソフトでUbuntuを操作したかったので。

共通設定

### SSH接続できるようにする
$ sudo apt-get install openssh-server

### IP確認 && ターミナルソフトで接続
$ ifconfig eth0

仮想マシン1台目

共通設定を実施する。  

Javaランタイムインストール

$ sudo add-apt-repository ppa:openjdk-r/ppa
$ sudo apt-get update
$ sudo apt-get install openjdk-8-jre

参考:Ubuntu 14.xにOpenJDK 8環境を構築 - Qiita

Embulkインストール

$ curl --create-dirs -o ~/.embulk/bin/embulk -L "http://dl.embulk.org/embulk-latest.jar"
$ chmod +x ~/.embulk/bin/embulk
$ echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc

$ embulk --version
embulk 0.8.14

参考:GitHub - embulk/embulk: Embulk: Pluggable Bulk Data Loader. http://www.embulk.org

Vim設定

### TABを半角スペース2個にする
$ cat << EOF > ~/.vimrc
set expandtab
set tabstop=2
set shiftwidth=2
EOF
$ source ~/.vimrc

サンプルデータ取得

$ wget http://www.mizuhobank.co.jp/rate/market/csv/quote.csv
### 先頭2行を削除する
$ sed -i -e '1,2d' quote.csv
### 31-33列目に空白の列を含むため除去する(サブシェル使用バージョン)
$ (rm quote.csv; cut -d ',' -f 1-30,34- >quote.csv) <quote.csv

参考:指定行削除するコマンド(sed - それマグで!
参考:Linuxコマンドでテキストデータを自在に操る - orangain flavor
参考:シェルスクリプトを書くときに気をつける9箇条 - Qiita

PostgreSQLインストール

$ sudo apt-get install postgresql-9.3
### postgresユーザにパスワードを設定する
$ sudo passwd postgres
### postgresユーザに変身する(今後psqlする度に必須)
$ su - postgres
### postgreSQLにログインする
$ psql
### webdbというDBを作成する
postgres=# create database webdb;
### postgreSQLからログアウトする
postgres=# \q
### postgresユーザを終了する
$ exit

### クライアント認証設定を変更する
$ sudo vi /etc/postgresql/9.3/main/postgresql.conf
+ listen_addresses = '*' 

192.168.11.0/24は自分のLANの値に合わせる。
$ sudo vi /etc/postgresql/9.3/main/pg_hba.conf
- host    all             all             127.0.0.1/32            md5
+ host    all             all             127.0.0.1/32            trust
+ host    all             all             192.168.11.0/24         trust
$ sudo service postgresql restart

書籍ではconfig.ymlのuser項目がnaoyaですが、postgresとする。

参考:UbuntuでPostgreSQLをインストールからリモートアクセスまでの手順 - Qiita

Digdugインストール

$ sudo curl -o /usr/local/bin/digdag --create-dirs -L "https://dl.digdag.io/digdag-latest"
$ sudo chmod +x /usr/local/bin/digdag
$ digdag --version
0.8.17

仮想マシン2台目

共通設定を実施する。  

Re:dashインストール

$ wget https://raw.githubusercontent.com/getredash/redash/master/setup/ubuntu/bootstrap.sh
$ chmod +x bootstrap.sh
$ ./bootstrap.sh

参考:Setting up Re:dash instance — Re:dash documentation

後はWindowsのWEBブラウザから仮想マシン2台目のIPにアクセスすればRe:dashの画面が表示される。

WEB+DB PRESS Vol.94

WEB+DB PRESS Vol.94

grepで複数のフォルダを除外する

カレントディレクトリ以下のhogeというワードを含むファイルを探す。
※ただし、ファイルパスに.gitとsrcを含むものを除く
$grep -r 'hoge' ./ --exclude-dir={.git,src}

動作結果見てる限り、以下の物も弾いてます。
./src/huga.c
./where/src/hogehoge.c

こういうのは弾かない。
./srcd/huga.c
./xxxx/src.c

Markdownがリアルタイムプレビュー対応してた。
HatenaBlogも進化していた。
そしてMarkdownの書き方を忘れていた。

Pythonの複数バージョン共存(Windows)

目的

WindowsにPython2とPython3の環境を共存させる。
Python3を使用していたが、Python2だとどう動くのか試してみたくなったため。
ついでにiPythonも使いたい。

候補

  1. シンボリックリンク的なバッチを作って使い分ける
  2. virtualenvを使う
  3. Python3.3からの機能のpy.exeを使う

2番目のvirtualenvを使う方法がいいかと思うが、今回は3番目を選択。

実際の方法

シンボリック的なバッチを作って使い分ける

参考:#84 複数バージョンのPythonをインストールする

virtualenvを使う

参考:#104 Windows環境でvirtualenvする

py.exeを使う

Python3.3をインストールすると、$ pyを使える。
Python2を使いたい時は$ py -2 hoge.pyとし、Python3を使いたい時は$ py -3 hoge.pyとする。
インストールの順番は、Python3 => Python2として、Python2のインストール設定で
Register ExtensionsはOFFにする。

iPythonを両方で使いたい

対話式で試せるiPythonはどちらでも使用できるようにしたい。
iPythonのインストールの方法は以下のようにする。

  1. ez_setup.pyをここからダウンロード
  2. ez_setup.pyを実行して、easy_installをインストール
  3. easy_installでpipをインストール
  4. pipでiPythonをインストール

ez_setup.pyを実行

Python3.3にPATHを通しておくと、Python3.3は$ python ez_setup.pyで実行できる。
Python2の方はPATHを通さず、$ py -2 ez_setup.pyで実行する。

easy_installでpipをインストール

Python3.3の方は$ easy_install pip(もしかしたらC:\Python33\ScriptsにPATHが必要かも)
Python2の方は$ c:\Python27\Scripts\easy_install pip

pipでiPythonをインストール

Python3.3は$ pip install ipython
Python2の方は$ c:\Python27\Scripts\pip install ipython
C:\Python27\ScriptsのPATHをC:\Python33\Scriptsよりも後ろにつける。
$ ipython3でPython3.3、$ ipythonでPython2のiPythonが起動する。

MSYS版のminttyでmsysgitのgit pushしたい

目的

MSYS版のminttyでmsysgitのgit pushやgit pullできるようにする。
1番下のmsysgitとMSYSの共存の参考リンクそのまんまで環境を構築したら、 gitのcloneやpushができなかったので。

原因

  1. libcurl.exeが無い
  2. SSL certificate problem
  3. Cygwin+mintty、Windowsの対話型コンソールアプリを正しく実行できない
    確かにipythonが正しく動かないし、gitのコマンドもpushとpullだけ動かない。

対策

libcurl.exeが無い

以下を [GIT_DIR]bin/ から [MINGW_DIR]msys/1.0/bin/([VAGRANT_DIR]embedded/bin/)へコピーした

  • curl-ca-bundle.crt
  • libcurl.exe
  • libcrypto.dll
  • libssl.dll

参考:MinGWにmsysGitを移植する

SSL certificate problem

gitのhttp.sshcainfoを以下に書き換える。
git config --global http.sslcainfo [curl-ca-bundle.crtのPATH]

対話型コンソールが動かない

以下を参考にした。
Issue 56: Improve support for native console programs
具体的には#64の書き込みで、winptyを使用する。
この方法は#67で検証されているように、遅延が生じる。
MSYS版を入手し、winpty.dll、winpty-agent.exe、console.exeをmintty.exeと同じbinフォルダに入れる。
mintty.exeのショートカットを作成し、プロパティのリンク先を以下を追加する。
/bin/console /bin/bash --login

msysgitとMSYSの共存

参考:Vagrant and Chef on Windows