Apache SolrCloudでクラスタ環境構築入門 (クラスタ構築〜分散インデシング〜フェールオーバーまで)


# はじめに

Solr vs ElasticSearchな今日この頃ですが、SolrCloudでのレプリケーション環境構築を試してみました。

「solr -e cloud」で同一サーバー上にexampleのSolrCloud環境は簡単に構築できるのですが、具体的に何をやっているのかよくわからないので、複数サーバーで実際に使うであろう手順を踏んでの構築を試みてました。

先に感想としては、RDBMSでMaster-Slaveでのレプリケーション環境はよく構築していましたが、SolrCloudではZooKeeperを用いてのレプリケーション、フェールオーバー、ノーダーノード自動選出など中央集中管理が非常に魅力的だな感じました。それとドキュメントが充実していてわかりやすいのがいいですね。

# 今回、SolrCloudで構築したい全体像

今回は最小のクラスタ構成を構築してみるという趣旨で、シャード、ノード、Zookeeperをそれぞれ2つずつ。(Zoopkeeperの構築については省略してます)

![QiitaSolr.001.jpeg](https://qiita-image-store.s3.amazonaws.com/0/18841/df6627c0-8bbc-2e05-57ed-661d02cd36ad.jpeg "QiitaSolr.001.jpeg")


# 構築環境

今回試す環境は以下の通り。

- OS X EI Capitan 10.11.4
- Vegrant 1.8.1
- VirtualBox 5.0.16
- Ansible
- Ubuntu ubuntu 14.04
- Solr 6.0
- ZooKeeper 3.4.8
- Java 1.8.0

## 1. ノードを作成

### 192.168.33.10にノード1を作成

まずはノード1を作成。ポートは8001を指定します。

```shell
$ sudo mkdir -p myserver/node1/solr
$ sudo cp server/solr/solr.xml myserver/node1/solr/
$ sudo solr start -cloud -s /opt/solr/myserver/node1/solr -p 8001 -z 192.168.33.20:2181,192.168.33.21:2181 -h 192.168.33.10
```


### 192.168.33.10にノード2を作成

同様にノード2も作成。ポートは8002を指定します。

```shell
$ sudo mkdir -p myserver/node2/solr
$ sudo cp server/solr/solr.xml myserver/node2/solr/
$ sudo solr start -cloud -s /opt/solr/myserver/node2/solr -p 8002 -z 192.168.33.20:2181,192.168.33.21:2181 -h 192.168.33.10
```

### 192.168.33.11にノード3を作成

まずはノード3を作成。ポートは8003を指定します。

```shell
$ sudo mkdir -p myserver/node3/solr
$ sudo cp server/solr/solr.xml myserver/node3/solr/
$ sudo solr start -cloud -s /opt/solr/myserver/node3/solr -p 8003 -z 192.168.33.21:2181,192.168.33.21:2181 -h 192.168.33.11
```


### 192.168.33.11にノード4を作成

同様にノード4も作成。ポートは8004を指定します。

```shell
$ sudo mkdir -p myserver/node4/solr
$ sudo cp server/solr/solr.xml myserver/node4/solr/
$ sudo solr start -cloud -s /opt/solr/myserver/node4/solr -p 8004 -z 192.168.33.21:2181,192.168.33.21:2181 -h 192.168.33.11
```

## 2. コレクションの作成

最小構成でシャード2 x レプリケーション2でコレクションを作成してみます。

サンプルデータを挿入したいので「configsets」はスキーマーレスな「data_driven_schema_configs」を選びます。

```
$ solr create_collection -c testcollection -d server/solr/configsets/data_driven_schema_configs -p 8001 -shards 2 -replicationFactor 2
```

管理画面にアクセスして下記のように表示されればOK。現時点ではノードは一つもありません。
http://192.168.33.10:8001/solr/#/~collections/testcollection


![Screen Shot 2016-05-10 at 7.37.56 PM.png](https://qiita-image-store.s3.amazonaws.com/0/18841/a2663d39-25c7-d0df-ab0b-755a3a2213ed.png "Screen Shot 2016-05-10 at 7.37.56 PM.png")

Cloud > Graphを見てもまだ何も表示されません。

![Screen Shot 2016-05-10 at 7.37.02 PM.png](https://qiita-image-store.s3.amazonaws.com/0/18841/19df1c84-428c-ccca-e6f3-7c2d5a91191b.png "Screen Shot 2016-05-10 at 7.37.02 PM.png")

## 3. クラスタ構築

コレクションとノードの紐付けはGUI上でもできますが(「add replica」をクリックすれば)、今後なるべく自動化していきたいので、コマンドライン上での紐付けを試してみます。

```
$ curl -XGET "http://192.168.33.10:8001/solr/admin/collections?action=ADDREPLICA&collection=testcollection&shard=shard1&node=192.168.33.10:8001_solr"
```

![Screen Shot 2016-05-10 at 7.54.03 PM.png](https://qiita-image-store.s3.amazonaws.com/0/18841/9a56b2ba-2ed1-bdef-ff20-b7db7a7043b7.png "Screen Shot 2016-05-10 at 7.54.03 PM.png")


```
$ curl -XGET "http://192.168.33.10:8001/solr/admin/collections?action=ADDREPLICA&collection=testcollection&shard=shard2&node=192.168.33.10:8002_solr"
```

![Screen Shot 2016-05-10 at 8.00.31 PM.png](https://qiita-image-store.s3.amazonaws.com/0/18841/4353712b-f170-9c72-e71c-bad3c5bee151.png "Screen Shot 2016-05-10 at 8.00.31 PM.png")

```
$ curl -XGET "http://192.168.33.10:8001/solr/admin/collections?action=ADDREPLICA&collection=testcollection&shard=shard1&node=192.168.33.11:8003_solr"
```

![Screen Shot 2016-05-10 at 8.01.11 PM.png](https://qiita-image-store.s3.amazonaws.com/0/18841/e8e38220-ab85-8544-7994-e96e1ce68db4.png "Screen Shot 2016-05-10 at 8.01.11 PM.png")


```
$ curl -XGET "http://192.168.33.10:8001/solr/admin/collections?action=ADDREPLICA&collection=testcollection&shard=shard2&node=192.168.33.11:8004_solr"
```

![Screen Shot 2016-05-10 at 8.01.41 PM.png](https://qiita-image-store.s3.amazonaws.com/0/18841/3df40d97-eaa1-e423-c23c-3a3362dfe31e.png "Screen Shot 2016-05-10 at 8.01.41 PM.png")

無事、冗長構成が出来上がりました。

## 	4. 検索テスト

テストデータを流し込んで、データを取得してみます。

```
$ sudo ./bin/post -c testcollection -host 192.168.33.10 -p 8001 example/exampledocs/books.json
```

シャード1のデータを見てみます。ドキュメントが1つ見つかりました。リクエストパラメーターに「shards=shard1」と入れることでシャードの指定ができます。

```
$curl "http://192.168.33.10:8001/solr/testcollection/select?indent=on&q=*:*&wt=json&shards=shard1"
```


```json
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":32,
    "params":{
      "q":"*:*",
      "shards":"shard1",
      "indent":"on",
      "wt":"json"}},
  "response":{"numFound":1,"start":0,"maxScore":1.0,"docs":[
      {
        "id":"978-0641723445",
        "cat":["book",
          "hardcover"],
        "name":["The Lightning Thief"],
        "author":["Rick Riordan"],
        "series_t":["Percy Jackson and the Olympians"],
        "sequence_i":1,
        "genre_s":"fantasy",
        "inStock":[true],
        "price":[12.5],
        "pages_i":384,
        "_version_":1533160426202726400}]
  }}
```

続いてシャード2。ドキュメントが3つ見つかりました。

```
$ curl "http://192.168.33.10:8001/solr/testcollection/select?indent=on&q=*:*&wt=json&shards=shard2"
```

```json
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":0,
    "params":{
      "q":"*:*",
      "shards":"shard2",
      "indent":"on",
      "wt":"json"}},
  "response":{"numFound":3,"start":0,"docs":[
      {
        "id":"978-1423103349",
        "cat":["book",
          "paperback"],
        "name":["The Sea of Monsters"],
        "author":["Rick Riordan"],
        "series_t":["Percy Jackson and the Olympians"],
        "sequence_i":2,
        "genre_s":"fantasy",
        "inStock":[true],
        "price":[6.49],
        "pages_i":304,
        "_version_":1533160426197483520},
      {
        "id":"978-1857995879",
        "cat":["book",
          "paperback"],
        "name":["Sophie's World : The Greek Philosophers"],
        "author":["Jostein Gaarder"],
        "sequence_i":1,
        "genre_s":"fantasy",
        "inStock":[true],
        "price":[3.07],
        "pages_i":64,
        "_version_":1533160427078287360},
      {
        "id":"978-1933988177",
        "cat":["book",
          "paperback"],
        "name":["Lucene in Action, Second Edition"],
        "author":["Michael McCandless"],
        "sequence_i":1,
        "genre_s":"IT",
        "inStock":[true],
        "price":[30.5],
        "pages_i":475,
        "_version_":1533160427141201920}]
  }}
```

・Distributed Search with Index Sharding:
https://cwiki.apache.org/confluence/display/solr/Distributed+Search+with+Index+Sharding


## 5. フェールオーバーのテスト

現在のクラスタの状態です。shard1、shard2ともに192.168.33.11がリーダー(黒丸)となっています。その192.168.33.11がサーバーごとぶっ飛んだ場合でも正しくデータを取得できるかを試してみます。

![Screen Shot 2016-05-12 at 7.41.39 AM.png](https://qiita-image-store.s3.amazonaws.com/0/18841/9e734443-e1e1-e962-2161-42332af48ed0.png "Screen Shot 2016-05-12 at 7.41.39 AM.png")


vagrantで強制終了・・。haltをポチッと。

```
$ vagrant halt
```

停止した192.168.33.11がグレーアウトしてリーダーが33.10に変わったことがわかります。

![Screen Shot 2016-05-12 at 7.47.00 AM.png](https://qiita-image-store.s3.amazonaws.com/0/18841/0d91d925-c89b-ec60-1d6d-38c3d70f4a80.png "Screen Shot 2016-05-12 at 7.47.00 AM.png")

この状態でもう一度データ検索してみます。

シャード1。

```
$ curl "http://192.168.33.10:8001/solr/testcollection/select?indent=on&q=*:*&wt=json&shards=shard1"
```

```
....
"response":{"numFound":1,"start":0,"maxScore":1.0,"docs":[
....
```

シャード2。

```
$ curl "http://192.168.33.10:8001/solr/testcollection/select?indent=on&q=*:*&wt=json&shards=shard2"
```

```
....
"response":{"numFound":3,"start":0,"maxScore":1.0,"docs":[
....
```

シャードの指定をしなかった場合。

```
$ curl "http://192.168.33.10:8001/solr/testcollection/select?indent=on&q=*:*&wt=json"
```

```
....
"response":{"numFound":4,"start":0,"maxScore":1.0,"docs":[
....
```

無事、取得できました。



実稼働するにはまだ調査・検証しなければいけないことがたくさんありますが、とりあえずは簡易的なクラスタ構成で基本的な動作のみを試してみました。冒頭にもあげましたが、ドキュメントがわかりやすく、APIも使いやすいので、比較的導入しやすいのではと思いました。(もちろん、大変なことは多々あるでしょうが・・)



# 参考サイト・書籍

- SolrCloud

SolrCloud公式ドキュメント。
https://cwiki.apache.org/confluence/display/solr/SolrCloud

- Collections API

コレクションを操作したい場合は下記URL参照。
https://cwiki.apache.org/confluence/display/solr/Collections+API