バツイチちゃんがSolrのこと書いてたので、インケンはElasticsearchのこと書きます。
xmlよりjson派なインケンとしてはsolrなんかより、elasticsearch押しです。solr使ったことないけどね!
elasticsearchはRESTリクエスト飛ばせば、検索登録更新削除すべて行うことができるのですが、RabbitMQのプラグインを使うと、登録更新削除をキューにメッセージ投げるだけでいいので、大変便利です。
MQにメッセージ投げる際には、elasticsearchのbulk api形式で送る必要があります。
その辺がわかりづらかったので、サンプル交えてご紹介します。
elasticsearch、rabbitmqプラグインのインストールは割愛します。
elasticsearchにrabbitmq用のインデックスを登録する
まずはelasticsearchにrabbitmqのサーバー情報を設定します。
curl -XPUT 'http://elasticserver:9200/_river/rabbitmq/_meta' -d '{ "type" : "rabbitmq", "rabbitmq" : { "host" : "192.168.0.1", "port" : 5672, "user" : "guest", "pass" : "guest", "vhost" : "/", "queue" : "elasticsearch", "exchange" : "elasticsearch", "routing_key" : "elasticsearch", "exchange_declare" : true, "exchange_type" : "direct", "exchange_durable" : true, "queue_declare" : true, "queue_bind" : true, "queue_durable" : true, "queue_auto_delete" : false, "args" : { "x-ha-policy" : "all" } }, "index" : { "bulk_size" : 100, "bulk_timeout" : "10ms", "ordered" : false } }'
RabbitMQを冗長化してる場合はこんな感じ
curl -XPUT 'http://elasticserver:9200/_river/rabbitmq/_meta' -d '{ "type" : "rabbitmq", "rabbitmq" : { "addresses" : [ { "host" : "rabbitmq-host1", "port" : 5672 }, { "host" : "rabbitmq-host2", "port" : 5672 } ], "user" : "guest", "pass" : "guest", ...... ..... }'
これでmqにelasticsearchっていうキューができます。
RabbitMQ経由でデータを登録変更削除する
サンプルとして以下のインデックスを想定します。
curl -XPUT 'http://elasticserver:9200/google/photo/_mapping' -d ' { "photo" : { "properties" : { "caption" : {"type" : "string"}, "upload_datetime" : {"type" : "date", "format" : "yyyy-MM-dd HH:mm:ss"} } } }'
これにデータを登録する場合、MQにこんな感じでメッセージを投げます。
PHPサンプル
//登録、変更 $message = '{ "index" : { "_index" : "google", "_type" : "photo", "_id" : "'.$photo_id.'" } }' . '\n'; $message .= '{ "photo" : { "caption" : "写真の説明だよ" , "upload_datetime" :"'. date("Y-m-d H:i:s").'" }}' . '\n'; $message .= '{ "create" : { "_index" : "google", "_type" : "photo", "_id" : "'.$photo_id.'" } }'; publish_mq( 'elasticsearch', $message); //MQに投げる処理
登録と変更は同じです。すでにIDが存在すると更新になります。
//削除 $message = '{ "delete" : { "_index" : "google", "_type" : "photo", "_id" : "'.$photo_id.'" } }' . '\n'; $message .= '{ "create" : { "_index" : "google", "_type" : "photo", "_id" : "'.$photo_id.'" } }';
ポイントは、改行です。
JSONでOKなんだと思って、以下のように一行で投げるとエラります。
//これNG $message = '{ "delete" : { "_index" : "google", "_type" : "photo", "_id" : "'.$photo_id.'" } , "create" : { "_index" : "google", "_type" : "photo", "_id" : "'.$photo_id.'" } }';
そして上記のサンプルの場合、captionってデータに改行コードが入ってるとエラるので、それも除去してあげる必要があります。
いかがでしょうか、もちろんRESTでelasticsearchに直接データをPOSTすることもできますが、すべて一旦MQに投げとくと処理待ちも回避できて良いと思います。