データベースをデータソースにElasticsearchへデータ投入する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

藤本です。

来週はついにElastic{ON}: The Elasticsearch User Conferenceです。私も参加します。英語力に難ありですが(海外旅行を)楽しんできます。

先日、様々なファイルをデータソースにElasticsearchへデータ投入するをエントリしました。今回はデータベースをデータソースにElasticsearchへデータ投入する方法をご紹介します。

概要

Elasticsearchはリアルタイムデータ分析、ログ解析、全文検索など様々なユースケースで活用することができます。例えば、Excelでデータ蓄積して、グラフ化・集計を行っているのであれば、Elasticsearchにデータ投入して、Kibanaで可視化することができます。ログをSyslogで集約して、grepやawkを駆使してパフォーマンス解析しているのであれば、logstashやfluentdなどでメッセージ解析し、Elasticsearchに集約、Kibanaで可視化することができます。ブログサイトの記事をDBに投入していてアプリケーションによって検索処理ロジックを実装しているのであれば、Elasticsearchの字句解析・トークナイズにより、よりクレバーで高速な検索をElasticsearchに委ねることができ、実装を減らすことが可能です。これらはElasticsearchのよくあるユースケースです。分かってはいるが、正直試さないと本当に想定する利用方法が可能なのか、実装が少なくて済むのか、パフォーマンスは早いのか、判断することができません。

そこで今回はElasticsearch導入の取っ掛かりとなるべく、既にあるデータをElasticsearchに持っていく方法をデータソース別にご紹介し、まずはElasticsearchやKibanaを触っていただければ幸いです。

環境情報

  • Elasticsearchサーバ
    • IPアドレス:10.255.0.100
    • Elasticsearchバージョン:2.1.1    
  • DBサーバ
    • IPアドレス:192.168.99.110
    • DBエンジン:MySQL 5.6.28
    • データベース:db
    • テーブル:blog(カラム:id, title, text)
       
  • Logstash実行環境(OSXローカル)
    • Logstashバージョン:2.1.1

Logstashインストール

Logstashのインストールは様々なファイルをデータソースにElasticsearchへデータ投入するのLogstashインストールの章をご参照ください。

RDBMSからElasticsearch

RDBMSの特定のテーブル、カラムのデータをElasticsearchにインデックスします。RDBMSと書きましたが、基本的にJDBC DriverがあるDBは対応しています。今回はMySQLで試してみます。

利用するLogstash Plugins

logstash-input-jdbc

Input Pluginsのlogstash-input-jdbcを利用します。logstash-input-jdbcはJDBC接続でDBに接続することが可能です。JDBC Driverさえ用意すれば、対応するDBからデータ取得が可能です。MySQL、PostgreSQL、OracleDB、MSSQLなど代表的なDBには対応していることとなります。

テストデータ

テストデータは概要に書いたブログサイトをユースケースとします。テーブルのカラムはID、タイトル、本文です。とりあえず私の直近3回のブログをサンプルデータとして、INSERTしています。

# mysql -h 192.168.99.110 -u fujimoto -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.6.28 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use db
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from blog;
+----+--------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | title                                                                                                        | text                                                                                                                                                                                     |
+----+--------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | SenseによるElasticsearchへの楽々API発行                                                                      | ## はじめに藤本です。気づけば一月も終わりかけていますが、、、2016年一本目です。今年もよろしくお願いします。  チープなタイトルですが、Sense便利です!Elasticsearchを使っていて、Sense使っていない方は是非使ってみてください!以上!## 概要ElasticsearchのSearch APIの検証やテストデータ投入やその準備などでAPIを実行する時、私はターミナルからcURLコマンドを使って実行していました。簡単なAPIであれば苦ではありませんが、リクエストボディのJSONが長くなったり、似たようなAPIを幾つか流したりする場合、cURLコマンドでは手間です。そんなElasticsearchへのAPI実行を楽にしてくれる操作ツールのSenseをご紹介します。・・・(略) |
|  2 | Ansible 2.0の新機能 Docker Connection Pluginを使ってDockerコンテナの構成管理をしてみた                       | ## はじめに藤本です。※ 本ブログ執筆時点ではAnsible 2.0はrc3です。GAリリース時にこのブログの通りにいかないことがあるかもしれませんのでご注意ください。## 概要Ansible 2.0からDockerのConnection Pluginが追加されました。Ansible 1.x系では標準モジュールだけでDockerコンテナをリモートから構成管理したい場合、コンテナ内でsshdを起動して、SSHポートをDockerホストと紐付けたりする必要があり、エージェントレス(ホストの構成を変えずに)が特徴のAnsibleとしては微妙な感じでした。Ansible 2.0で追加されたDockerのConnection Pluginを利用すれば、Docker Remote APIを利用したコンテナのプロビジョニングが可能となりました。Ansible実行環境からDockerホストへRemote APIを実行できる環境であれば、Dockerコンテナでsshdを起動しておく必要がありません。今回はOSX上のVirtualBox上のDockerホスト(Docker Toolbox)に対して、ansible-playbookでWEBサーバをプロビジョンすることを目標します。・・・(略) |
|  3 | Fluent BitのOutput PluginsにElasticsearchが追加されました                                                    | ## はじめに藤本です。弊社メンバーから<a href="https://github.com/fluent/fluent-bit" target="_blank">fluent-bit</a>のOutput PluginsにElasticsearchが実装されたことを教えていただいたので早速試してみました。## 概要Fluent BitはC言語で実装された軽量なデータコレクタです。センサーのような非力な機器でデータ収集に向いています。先日リリースされたv0.5でElasticsearchへの出力が実装されました。動作を確認してみましたのでご紹介します。センサーデータをグラフ化できたら方が面白かったと思いますが、今回はAmazon LinuxのCPU/MEM使用状況を送信して、Kibana(Timelion)で可視化します。・・・(略) |
+----+--------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

JDBC Driver

適当なJDBC Driverをダウンロードしてください。

# wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.38.tar.gz
--2016-01-27 17:21:23--  https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.38.tar.gz
Resolving dev.mysql.com... 137.254.60.11
Connecting to dev.mysql.com|137.254.60.11|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://cdn.mysql.com//Downloads/Connector-J/mysql-connector-java-5.1.38.tar.gz [following]
--2016-01-27 17:21:24--  http://cdn.mysql.com//Downloads/Connector-J/mysql-connector-java-5.1.38.tar.gz
Resolving cdn.mysql.com... 23.67.184.96
Connecting to cdn.mysql.com|23.67.184.96|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3938241 (3.8M) [application/x-tar-gz]
Saving to: 'mysql-connector-java-5.1.38.tar.gz'

mysql-connector-java-5.1.38 100%[=============================================>]   3.75M  10.5MB/s   in 0.4s

2016-01-27 17:21:24 (10.5 MB/s) - 'mysql-connector-java-5.1.38.tar.gz' saved [3938241/3938241]

# tar xzf mysql-connector-java-5.1.38.tar.gz

Logstash設定ファイル例

  1. inputにjdbcを指定し、logstash-input-jdbcを利用します。
  2. 指定可能なパラメータは公式ドキュメントをご参照ください。
    今回は最低限のDriver、Driver Class、URL、Username、Password、SQLを指定しています。
  3. outputにelasticsearchのプラグインはElasticsearchホスト、データ投入するindexを指定しています。
# cat jdbc.conf
input {
  jdbc {
    jdbc_driver_library => "mysql-connector-java-5.1.38/mysql-connector-java-5.1.38-bin.jar"
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    jdbc_connection_string => "jdbc:mysql://192.168.99.110:3306/db"
    jdbc_user => "fujimoto"
    jdbc_password => "**********"
    statement => "SELECT title,text from blog"
  }
}

output {
  elasticsearch {
    hosts => ["10.255.0.100"]
    index => "blog"
  }
}

Elasticsearchへの取り込み

作成した設定ファイルを基にLogstashを起動し、DBからElasticsearchへデータを送ります。

# curl 10.255.0.100:9200/_cat/indices
yellow open .kibana 1 1 1 0 3.1kb 3.1kb

# logstash-2.1.1/bin/logstash -f jdbc.conf
Settings: Default filter workers: 2
Logstash startup completed
Logstash shutdown completed

# curl 10.255.0.100:9200/_cat/indices
yellow open blog    5 1 3 0  390b  390b
yellow open .kibana 1 1 1 0 3.1kb 3.1kb

blogというINDEXが作成されました。

データはというと、、

# curl "10.255.0.100:9200/blog/_search?pretty"
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "blog",
      "_type" : "logs",
      "_id" : "AVKCRCkoT6ZmspEx0XmU",
      "_score" : 1.0,
      "_source":{"title":"SenseによるElasticsearchへの楽々API発行","text":"## はじめに藤本です。気づけば一月も終わりかけていますが、、、2016年一本目です。今年もよろしくお願いします。  チープなタイトルですが、Sense便利です!Elasticsearchを使っていて、Sense使っていない方は是非使ってみてください!以上!## 概要ElasticsearchのSearch APIの検証やテストデータ投入やその準備などでAPIを実行する時、私はターミナルからcURLコマンドを使って実行していました。簡単なAPIであれば苦ではありませんが、リクエストボディのJSONが長くなったり、似たようなAPIを幾つか流したりする場合、cURLコマンドでは手間です。そんなElasticsearchへのAPI実行を楽にしてくれる操作ツールのSenseをご紹介します。## SenseとはSenseはElasticsearchを開発しているElastic社が提供するAPI発行するための便利機能が詰まったWEBツールです。  当初、Senseは<a target=\"_blank\" href=\"https://www.elastic.co/products/marvel\">Marvel</a>の1コンポーネントとして利用可能な機能でした。それがSense 2.0からはKibanaのプラグインとして完全無償でリリースされました。それでは実画面交えながら機能をご紹介します。・・・(略)","@version":"1","@timestamp":"2016-01-27T08:47:30.515Z"}
    }, {
      "_index" : "blog",
      "_type" : "logs",
      "_id" : "AVKCRCkoT6ZmspEx0XmV",
      "_score" : 1.0,
      "_source":{"title":"Ansible 2.0の新機能 Docker Connection Pluginを使ってDockerコンテナの構成管理をしてみた","text":"## はじめに藤本です。※ 本ブログ執筆時点ではAnsible 2.0はrc3です。GAリリース時にこのブログの通りにいかないことがあるかもしれませんのでご注意ください。## 概要Ansible 2.0からDockerのConnection Pluginが追加されました。Ansible 1.x系では標準モジュールだけでDockerコンテナをリモートから構成管理したい場合、コンテナ内でsshdを起動して、SSHポートをDockerホストと紐付けたりする必要があり、エージェントレス(ホストの構成を変えずに)が特徴のAnsibleとしては微妙な感じでした。Ansible 2.0で追加されたDockerのConnection Pluginを利用すれば、Docker Remote APIを利用したコンテナのプロビジョニングが可能となりました。Ansible実行環境からDockerホストへRemote APIを実行できる環境であれば、Dockerコンテナでsshdを起動しておく必要がありません。今回はOSX上のVirtualBox上のDockerホスト(Docker Toolbox)に対して、ansible-playbookでWEBサーバをプロビジョンすることを目標します。## Docker Connection PluginDocker Connection Pluginはソースコードをザッと目を通した限り、ファイル転送に`docker cp`、コマンド実行を`docker exec`で実行しているようです。インベントリファイルではDockerホストを指定するのではなく、コンテナ名を指定します。そのためデフォルトではローカルホスト上のDockerコンテナに対して、処理を実行します。リモートホスト上のDockerコンテナに対して処理を実行したい場合、環境変数の`DOCKER_HOST`でリモートホストを指定する必要があります。・・・(略)","@version":"1","@timestamp":"2016-01-27T08:47:30.518Z"}
    }, {
      "_index" : "blog",
      "_type" : "logs",
      "_id" : "AVKCRCkoT6ZmspEx0XmW",
      "_score" : 1.0,
      "_source":{"title":"Fluent BitのOutput PluginsにElasticsearchが追加されました","text":"## はじめに藤本です。弊社メンバーから<a href=\"https://github.com/fluent/fluent-bit\" target=\"_blank\">fluent-bit</a>のOutput PluginsにElasticsearchが実装されたことを教えていただいたので早速試してみました。## 概要Fluent BitはC言語で実装された軽量なデータコレクタです。センサーのような非力な機器でデータ収集に向いています。先日リリースされたv0.5でElasticsearchへの出力が実装されました。動作を確認してみましたのでご紹介します。センサーデータをグラフ化できたら方が面白かったと思いますが、今回はAmazon LinuxのCPU/MEM使用状況を送信して、Kibana(Timelion)で可視化します。・・・(略)","@version":"1","@timestamp":"2016-01-27T08:47:30.519Z"}
    } ]
  }
}

DBのデータがインデックスされています。

ネットワークの壁がある場合

今回の方法の場合、Logstash実行環境からDBサーバへJDBC接続可能、ElasticsearchへAPI発行可能な環境である必要があります。オンプレ環境などであれば、条件を満たすことは難しいこともあると思います。条件を満たしていない環境でも回避方法が2つあります。

Logstashによるリレー

Logstashはlumberjackという独自プロトコルによってLogstashからLogstashへデータを渡すことができます。これでLogstash間でデータをリレーすることでDB -> Logstash -> Logstash -> ・・・ -> Elasticsearchというようにデータを投入することができます。

ファイル出力

MySQLやPostgreSQLなどはテーブルの内容をCSVファイルで出力することができます。CSVファイルで出力できれば、先日ご紹介した様々なファイルをデータソースにElasticsearchへデータ投入するのCSVファイルからElasticsearchの章の方法で、Logstashを使ってElasticsearchへデータを投入することができます。

DynamoDBからElasticsearch

検証したので書いていたら、既にメソられていました。

Logstash Plugin for Amazon DynamoDBを使ってDynamoDBとElasticsearchを同期するをご参照ください。

まとめ

いかがでしたでしょうか?
RDBMS、DynamoDBからElasticsearchへデータを投入する方法をご紹介しました。
Logstashは本当に色々なPluginを用意しています。既にあるデータをElasticsearchに置き換えて試したい場合、Logstashが対応しているかどうか是非一度見てみてください。