Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

PHPからInfluxDBに繋いでみた

最近PHPからいろいろなデータベース(RDBMS以外も)に繋ぐことが多くなっていた中で、InfluxDBにも繋ぐ必要が出てきたのでざっくりまとめてみました。
間違ってる所があれば、指摘をお願いします;-)

基本的な環境

  • CentOS 6.4(x86_64, ClouderaのQuickStartVM)
  • PHP 5.6.8
  • InfluxDB 0.8.8(rpm)

InfluxDBとは

InfluxDBは時系列データを格納するためのオープンソースなデータストアで、Goで書かれています。
InfluxData (InfluxDB) | Time Series Database Monitoring & Analytics
とりあえず、以下のページをざっと読むと良いかと。

2015/05/12現在、最新版は0.8.8で0.9をそろそろリリースするとアナウンスされています(が、なかなか出てきません。。。)。
特徴としては、以下の様なものがあります。

  • クラスタ環境も構築可能
  • SQLに似た問い合わせ言語が用意されており、基本的な集約関数やJOINも利用可能。
  • HTTP(S) APIJSONが強力で、データ登録や問い合わせだけでなくデータベース作成などいろいろ操作できる
  • 管理画面が組み込みで用意されている

インストール

RedHatCentOS向けにrpmが用意されているので、それをインストールするのが楽チンです:-)

$ sudo rpm -ivh http://s3.amazonaws.com/influxdb/influxdb-latest-1.x86_64.rpm

InfluxDB関連のファイルは、/opt/influxdbに配置されます。設定ファイルは/opt/influxdb/shared/config.tomlです。設定オプションは、以下を参照してください。

InfluxDBを起動・停止してみる

起動・停止は、serviceコマンドで行います。

$  sudo service influxdb start
Setting ulimit -n 65536
Starting the process influxdb [ OK ]
influxdb process was started [ OK ]
$ 

起動後、8083、8086、8090、8099の4ポートでLISTENしていることを確認して下さい。

$ sudo netstat -tnlp | grep -P "80(83|86|90|99)"
tcp        0      0 0.0.0.0:8083                0.0.0.0:*                   LISTEN      12943/influxdb
tcp        0      0 0.0.0.0:8086                0.0.0.0:*                   LISTEN      12943/influxdb
tcp        0      0 0.0.0.0:8090                0.0.0.0:*                   LISTEN      12943/influxdb
tcp        0      0 0.0.0.0:8099                0.0.0.0:*                   LISTEN      12943/influxdb
$ 

LISTENできていない場合は、/opt/influxdb/shared/log.txtを確認してみてください。

管理画面を使ってデータベース作成〜データ登録する

まずはデータベースの作成を行います。HTTP(S) APIでもデータベースを作成できますが、とりあえず用意されている管理画面からデータベースを作成してみます。

1. ログインする

ブラウザから、http://[ホスト名]:8083/ にアクセスするとログイン画面が表示されます。

デフォルトのusernameとpasswordは"root"ですので、入力し"connect"ボタンを押下します。

2. データベースの作成

ログインすると、以下の様なデータベース一覧画面が表示されます。

とりあえず、"test"というデータベースを作ってみました。ここでは、データベース名に"test"と入力し、右下の"Create Database"ボタンを押下します。ここでは割愛しますが、Shard Specsではデータの保存期間やクラスタ構成時の分割数を指定します。詳細は、以下を参照してください。

データベース作成が成功すると、一覧に作成済みのデータベースが表示されます。

3.データベース接続用のユーザーを登録する

データベースを作成したら、データベース接続用のユーザーを追加しましょう。
先ほどの画面に表示されているデータベース一覧からデータベース名"test"をクリックすると、ユーザーの登録画面になります。

接続用ユーザーのユーザー名とパスワードを入力し、"Create"ボタンを押下します。

4.データを登録する

ここまでできたら、データを登録してみましょう。
画面上部のメニューの"Databases"をクリックすると先ほどのデータベース一覧画面になりますので、"Explore Data"リンクをクリックします。すると、データの参照・登録画面になりますので、下にある"Write Point"からデータを登録します。

InfluxDBには、RDBMSのテーブルのように"シリーズ(Series)"と呼ばれるテーブル的なものがあります。データはオブジェクトのJSON形式で1レコードに相当します。この時、キーがRDBMSでいうカラム名に相当します。フォーマットの詳細は、以下を参照してください。

まずは、

  • Time Series Name:series01
  • Values:{"event": "test", "value": "123"}

と入力し、"Write Point"ボタンを押下します。

これでボタンの右に"200 OK"と表示されればデータ登録完了です。続けて何件かデータを登録します。

5.問い合わせを実行してみる

データをある程度登録したら、先ほどの画面の上にある"Read Points"から問い合わせを実行してみます。
"Query"に

SELECT * FROM series01

と入力し、登録済みのデータが全件出力されればOKです。

この時、データとしては登録していないはずの

  • time
  • sequence_number

というカラムも出力されていると思いますが、データ登録した日時のタイムスタンプ(ms単位)とシーケンス番号になります。これはInfluxDBが付与したもので、これら2カラムでユニークになります。
その他集約関数やデータ削除、シリーズの削除については、以下を参照してください。

InfluxDB-CLI

「管理画面もいいけど、やっぱ黒い画面よね」という方向けにInfluxDB-CLIというものもあります。
今のところ、Go/Ruby/Node.js製のものがあるようですが、今回はNode.js製のものをインストールしてみました。

$ sudo yum install -y nodejs npm --enablerepo=epel
$ sudo npm install influxdb-cli -g
$ 

コマンドは"influxdb-cli"です。

$ influxdb-cli --help
InfluxDB SQL CLI
Usage: influxdb-cli

Options:
  -h, --hostname  Host [%s]                             [default: "localhost"]
  --port          Port [%s]                             [default: 8086]
  -s, --secure    Use HTTPS if flag is present          [default: false]
  -u, --user      User [%s]                             [default: "root"]
  -a, --auth      HTTP basic auth [%s]                  [default: ""]
  -p, --password  Password [%s]                         [default: "root"]
  -d, --database  Database [%s]                         [default: "db"]
  --pretty        Display time in a human readable way  [default: false]

$ influxdb-cli --database=test
test> Connecting to http://localhost:8086/db/test ...
test> ✔ ready
test> select * from series01;
┌────────┬────────┬────┬───┐
│ time          │ sequence_number │ value │ event │
├────────┼────────┼────┼───┤
│ 1431424603006276961510001789test  │
│ 14314090029592769614900013     │ baz   │
│ 14314089986662769614800012     │ bar   │
│ 14314089836682769614700011     │ foo   │
│ 1431408976749276961460001456test  │
│ 1431408770502276961450001123test  │
└────────┴────────┴────┴───┘
Query took  9 ms
test>

やっぱこっちの方が扱いやすいですね:-)

PHP+InfluxDB

ようやくPHPからInfluxDBに繋げてみます(汗)
InfluxDBには各言語向けのクライアントライブラリが公開されていますので、それを使います。

2015/05/12現在、InfluxDB 0.9用と0.8.x用が公開されていますが、今回は後者を利用します。インストールはcomposerで。

$ vi composer.json
$ cat composer.json
{
    "require": {
        "crodas/influx-php": "0.1.*"
    }
}
$ ./composer.phar install
$ 

続いて、以下の様なテスト用スクリプト(test.php)を作成します。接続先のポート番号は8086です。

<?php
require_once __DIR__ . '/vendor/autoload.php';

define('INFLUXDB_HOST', 'localhost');
define('INFLUXDB_PORT', 8086);
define('INFLUXDB_NAME', 'test');
define('INFLUXDB_USER', [接続用ユーザーのユーザー名]);
define('INFLUXDB_PASS', [接続用ユーザーのパスワード]);

$client = new crodas\InfluxPHP\Client(INFLUXDB_HOST, INFLUXDB_PORT, INFLUXDB_USER, INFLUXDB_PASS);
$db = new crodas\InfluxPHP\DB($client, INFLUXDB_NAME);
$query = "SELECT * FROM series01";
try {
    var_dump($db->query($query));
} catch (Exception $e) {
    var_dump($e->getMessage());
}

で、実行。管理画面から確認したデータが取得できていればOKです。

$ php -v
PHP 5.6.8 (cli) (built: May  8 2015 14:17:31)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2015, by Zend Technologies
    with Xdebug v2.2.7, Copyright (c) 2002-2015, by Derick Rethans
$ php test.php
class crodas\InfluxPHP\Cursor#4 (1) {
  private $storage =>
  array(6) {
    [0] =>
    class stdClass#5 (4) {
      public $time =>
      int(1431424603)
      public $sequence_number =>
      int(276961510001)
      public $event =>
      string(4) "test"
      public $value =>
      string(3) "789"
    }
    [1] =>
    class stdClass#6 (4) {
      public $time =>
      int(1431409002)
      public $sequence_number =>
      int(276961490001)
      public $event =>
      string(3) "baz"
      public $value =>
      string(1) "3"
    }}
$ 

データのバックアップと移行

開発用環境など「とりあえずそれなりの量のデータが入っていれば良い」という状態にしたい場合、opt/influxdb/shared/data以下のファイルをコールドバックアップ&リストアすることで、データを移行することができます。
ただし、データベースのRetensionの設定によってはデータ保持期限切れでデータが消えてしまうので、移行後にHTTP(S) APIを使ってデータベースの設定を変更する必要があるかもしれません。

$ sudo service influxdb stop
$ sudo \rm -rf /opt/influxdb/shared/data
$ sudo tar zxf data.tgz -C /opt/influxdb/shared/
$ curl -X POST "http://localhost:8086/cluster/shard_spaces/test/test?u=root&p=root" -d '{ "retentionPolicy": "inf" }'
$ sudo service influxdb start
$ 

あとは、バックアップ/リストアツールもいくつかと公開されているようなので、それを使ってみるのも手かもしれません。

まとめ

またもや「ちゃんと繋げられましたよー」で終わっちゃいますが。。。(汗)
InfluxDBへの接続自体はライブラリのお陰でほとんど苦労することなくできると思います。
あと、SQLっぽい問い合わせ言語が使えるのはメリットが大きいんですが、結構クセがあるので「えっ?」ということが多いことに注意です。