本エントリの内容
- Logstashを使ってMySQLとElasticsearch(以下ES)を同期します
- 仕事ではインフラ系のツールを触らないので変なことを書いているかもしれません
準備
- 各種ダウンロードについては省略します
- 確認した環境はES v2.4.0, Logstash v2.4.0, mysql v5.7.12, MacOSX v10.11.6 です
- ESとlogstashはv2のあと3と4を飛ばして現在v5となってますが、(たぶん)それほど変わりはないと思います。
- Logstashプラグイン logstash-input-jdbc が必要です
- 使用するRDBに対応するjdbc-connectorもインストールします
今回はMySQLなので下記サイトからjdbc-connectorをダウンロードします。
アクセスするとログインかサインアップを求められますが画面下部の「No thanks, just start my download.」リンクから普通にダウンロード可能です。
ダウンロードしたらlogstashフォルダの直下に入れておきます。
テーブル構造のポイント
ESに同期する対象レコードは、logstash側で管理する最終同期時刻とDate型レコードの指定カラムの比較で決定します。つまりupdated_atのようなカラムが必要になります。
また、RDBのレコード削除を検知することはできません。そのためdeleted_atなど論理削除を表すカラムの値ごとESに同期し、その値を見て削除されたデータかどうか判別する必要があります。
logstash設定ファイル
input {
jdbc {
jdbc_driver_library => "mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-bin.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
jdbc_connection_string => "jdbc:mysql://localhost:3306/db_name"
jdbc_user => "mysql_user"
jdbc_password => "mysql_password"
statement => "select * from books where updated_at > :sql_last_run"
type => "books"
tracking_column => updated_at
jdbc_default_timezone => Japan
}
}
output {
elasticsearch {
hosts => ["localhost"]
index => "%{type}"
document_id => "%{type}_%{id}"
}
}
tracking_columnに同期のタイムスタンプとして使用するDate型カラムを指定します。
statementには同期するデータを抽出するSQLクエリを記述します。別ファイルに書く場合は
statement_filepath => "sql/book.sql"
のように書くことが可能です。重要なのはWhere句にwhere updated_at > :sql_last_run
を指定することで、:sql_last_run にはlogstash側で管理する最終同期時刻がセットされます。
その他の設定についてはドキュメントを確認してください。例えばscheduleを設定すると同期のクーロン実行が可能になります。
https://www.elastic.co/guide/en/logstash/current/plugins-inputs-jdbc.html
同期を実行する
logstashのフォルダ構成を確認します。といっても公式からダウンロードしたlogstashフォルダにjdbc-connectorと設定ファイルを入れるだけです。
-
logstash-2.4.0 // ダウンロードしたlogstashフォルダ
- mysql-connector-java-5.1.39 // jdbc-connector
- logstash.conf
- その他もともと入ってたファイル(binフォルダなど)
このディレクトリで下記コマンドを実行すると同期が行われます。
bin/logstash -f logstash.conf
同期時刻をクリアしたい場合
logstash側で管理している最終同期時刻は**.logstash_jdbc_last_run**というファイル名でMacOSXの場合はホームディレクトリにあります(環境によって異なると思います)。
同期時刻をクリアしたい場合はこのファイルを削除するだけでOKです。