Solr(Master-Slave) を Vagrant で構築する

# Solr(Master-Slave) を Vagrant で構築する

Vagrant で Solr を レガシーな Master-Slave 構成で構築しました．
Solr のバージョンは 6.2.0 です．

![masterslave.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246211/416dd7e0-a35f-c1d3-2d90-f7bf122895c4.png)


## 構成

Solr の構築はシェルでやることにしました．

```text
D:\vagrant\solrmasterslave
┣Vagrantfile
┗create_solr.sh
```

### Vagrantfile

- OS は CentOS 7 を使用します．
- プロビジョナでシェルを実行します．

```ruby
slave_cnt = 2

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"

  config.proxy.enabled  = true
  config.proxy.http     = "http://user_id:password@proxy_address:proxy_port"
  config.proxy.https    = "http://user_id:password@proxy_address:proxy_port"
  config.proxy.no_proxy = "localhost,127.0.0.1"

  config.vm.define "master" do | master |
    master.vm.hostname = "master"
    master.vm.network "private_network", ip: "192.168.33.40"
    master.vm.provision :hosts, :sync_hosts => true
    master.vm.provision :shell, path: "./create_solr.sh"
  end
  
  (1..slave_cnt).each do |i|
    config.vm.define "slave#{i}" do | slave |
      slave.vm.hostname = "slave#{i}"
      slave.vm.network "private_network", ip: "192.168.33.4#{i}"
      slave.vm.provision :hosts, :sync_hosts => true
      slave.vm.provision :shell, path: "./create_solr.sh"
    end
  end
  
end
```

### create_solr.sh

Standalone のときと同じです．
ただ文書の登録は後のお楽しみにとっておきます．

```bash
# Java をインストールする
yum install -y java-1.8.0-openjdk

# Solr を構築する
cd /usr/local/src/
yum install -y wget
wget https://archive.apache.org/dist/lucene/solr/6.2.0/solr-6.2.0.tgz
tar xzf solr-6.2.0.tgz
./solr-6.2.0/bin/install_solr_service.sh solr-6.2.0.tgz

# core を作成する
sudo -u solr /opt/solr/bin/solr create -c examplecore
# 文書は登録しない

# Port を開放する
systemctl enable firewalld.service
systemctl start firewalld.service
firewall-cmd --zone=public --add-port=8983/tcp --permanent
firewall-cmd --reload
```


## Solr を構築する

```powershell
> pwd
D:\vagrant\solrmasterslave
> vagrant up
```

## Master を設定する

- Solr を停止します．
- core にある solrconfig.xml に Master の設定を追加します．
- Solr を起動します．

```bash
> vagrant ssh master
$ su root
$ service stop solr
$ vi /var/solr/masterslave/master/data/examplecore/conf/solrconfig.xml
$ service start solr
```

```xml
  <requestHandler name="/replication" class="solr.ReplicationHandler" >
    <lst name="master">
      <str name="replicateAfter">commit</str>
      <str name="replicateAfter">optimize</str>
      <str name="replicateAfter">startup</str>
      <str name="confFiles">schema.xml,stopwords.txt</str>
    </lst>
  </requestHandler>
```

## Slave を設定する

- Solr を停止します．
- core にある solrconfig.xml に Slave の設定を追加します．
- Solr を起動します．

```bash
> vagrant ssh slave1
$ su root
$ service stop solr
$ vi /var/solr/masterslave/master/data/examplecore/conf/solrconfig.xml
$ service start solr

> vagrant ssh slave2
$ su root
$ service stop solr
$ vi /var/solr/masterslave/master/data/examplecore/conf/solrconfig.xml
$ service start solr
```

```xml
  <requestHandler name="/replication" class="solr.ReplicationHandler" >
    <lst name="slave">
      <str name="masterUrl">http://master:8983/solr/examplecore</str>
      <str name="pollInterval">00:00:30</str>
    </lst>
  </requestHandler>
```

## Replication 確認

Master に文書を登録して Slave に反映されるか確認します．
まず，core を作成しただけなので検索結果が空であることを確認します．

```cmd
> curl -X GET "http://192.168.33.40:8983/solr/examplecore/select?q=*:*&fl=id&wt=json&indent=on" --noproxy 192.168.33.40
{
  "responseHeader":{
    "status":0,
    "QTime":23,
    "params":{
      "q":"*:*",
      "indent":"on",
      "fl":"id",
      "wt":"json"}},
  "response":{"numFound":0,"start":0,"docs":[]
  }}
> curl -X GET "http://192.168.33.41:8983/solr/examplecore/select?q=*:*&fl=id&wt=json&indent=on" --noproxy 192.168.33.41
{
  "responseHeader":{
    "status":0,
    "QTime":23,
    "params":{
      "q":"*:*",
      "indent":"on",
      "fl":"id",
      "wt":"json"}},
  "response":{"numFound":0,"start":0,"docs":[]
  }}
> curl -X GET "http://192.168.33.42:8983/solr/examplecore/select?q=*:*&fl=id&wt=json&indent=on" --noproxy 192.168.33.42
{
  "responseHeader":{
    "status":0,
    "QTime":23,
    "params":{
      "q":"*:*",
      "indent":"on",
      "fl":"id",
      "wt":"json"}},
  "response":{"numFound":0,"start":0,"docs":[]
  }}
```

Master に文書を登録します．

```powershell
> vagrant ssh master -c "sudo -u solr /opt/solr/bin/post -c examplecore -p 8983 /opt/solr/example/exampledocs/*.xml"
```

再度検索してみます．

```cmd
> curl -X GET "http://192.168.33.40:8983/solr/examplecore/select?q=*:*&fl=id&wt=json&indent=on" --noproxy 192.168.33.40
{
  "responseHeader":{
    "status":0,
    "QTime":6,
    "params":{
      "q":"*:*",
      "indent":"on",
      "fl":"id",
      "wt":"json"}},
  "response":{"numFound":32,"start":0,"docs":[
      {
        "id":"GB18030TEST"},
      {
        "id":"SP2514N"},
      {
        "id":"6H500F0"},
      {
        "id":"F8V7067-APL-KIT"},
      {
        "id":"IW-02"},
      {
        "id":"MA147LL/A"},
      {
        "id":"adata"},
      {
        "id":"apple"},
      {
        "id":"asus"},
      {
        "id":"ati"}]
  }}
> curl -X GET "http://192.168.33.41:8983/solr/examplecore/select?q=*:*&fl=id&wt=json&indent=on" --noproxy 192.168.33.41
{
  "responseHeader":{
    "status":0,
    "QTime":11,
    "params":{
      "q":"*:*",
      "indent":"on",
      "fl":"id",
      "wt":"json"}},
  "response":{"numFound":32,"start":0,"docs":[
      {
        "id":"GB18030TEST"},
      {
        "id":"SP2514N"},
      {
        "id":"6H500F0"},
      {
        "id":"F8V7067-APL-KIT"},
      {
        "id":"IW-02"},
      {
        "id":"MA147LL/A"},
      {
        "id":"adata"},
      {
        "id":"apple"},
      {
        "id":"asus"},
      {
        "id":"ati"}]
  }}
> curl -X GET "http://192.168.33.42:8983/solr/examplecore/select?q=*:*&fl=id&wt=json&indent=on" --noproxy 192.168.33.42
{
  "responseHeader":{
    "status":0,
    "QTime":27,
    "params":{
      "q":"*:*",
      "indent":"on",
      "fl":"id",
      "wt":"json"}},
  "response":{"numFound":32,"start":0,"docs":[
      {
        "id":"GB18030TEST"},
      {
        "id":"SP2514N"},
      {
        "id":"6H500F0"},
      {
        "id":"F8V7067-APL-KIT"},
      {
        "id":"IW-02"},
      {
        "id":"MA147LL/A"},
      {
        "id":"adata"},
      {
        "id":"apple"},
      {
        "id":"asus"},
      {
        "id":"ati"}]
  }}
```

Replication が実行されて Master のインデックスが Slave にも反映されました．


## あとがき

一気に Master-Slave 構成を構築する際の Vagrantfile，シェル，構成です．
共有ディレクトリを用意して，設定済みの solrconfig.xml を配布します(solrconfig.xml には Master，Slave の設定を追記しています)．

```ruby
slave_cnt = 2

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.synced_folder "./shared", "/home/vagrant/shared", owner: "vagrant", group: "vagrant"

  config.proxy.enabled  = true
  config.proxy.http     = "http://user_id:password@proxy_address:proxy_port"
  config.proxy.https    = "http://user_id:password@proxy_address:proxy_port"
  config.proxy.no_proxy = "localhost,127.0.0.1"

  config.vm.define "master" do | master |
    master.vm.hostname = "master"
    master.vm.network "private_network", ip: "192.168.33.40"
    master.vm.provision :hosts, :sync_hosts => true
    master.vm.provision :shell, path: "./create_solr.sh"
    master.vm.provision :shell, path: "./setup_master.sh"
  end
  
  (1..slave_cnt).each do |i|
    config.vm.define "slave#{i}" do | slave |
      slave.vm.hostname = "slave#{i}"
      slave.vm.network "private_network", ip: "192.168.33.4#{i}"
      slave.vm.provision :hosts, :sync_hosts => true
      slave.vm.provision :shell, path: "./create_solr.sh"
      slave.vm.provision :shell, path: "./setup_slave.sh"
    end
  end
  
end
```

```bash
service solr stop
\cp -f /home/vagrant/shared/master/solrconfig.xml /var/solr/data/examplecore/conf/solrconfig.xml
service solr start
```

```bash
service solr stop
\cp -f /home/vagrant/shared/slave/solrconfig.xml /var/solr/data/examplecore/conf/solrconfig.xml
service solr start
```

```text
D:\vagrant\solrmasterslave
┣Vagrantfile
┣shared
┃┣master
┃┃┗solrconfig.xml
┃┗slvae
┃  ┗solrconfig.xml
┣create_solr.sh
┣setup_master.sh
┗setup_slave.sh
```