構成
レプリケーション対応のGroongaシステムを実装するには、いくつかのシステム構成を選ぶことができます。このドキュメントではいくつかのパターンを説明します。
利用可能なパターンは以下の通りです。
- マスタースレーブレプリケーション
- 復帰したスレーブへのデータの再送
利用できないパターンは以下の通りです。
- マルチマスターレプリケーション
- 自動でのスレーブ復旧
- 動的なスレーブ追加
- フェイルオーバー
- サービスレベルを落とすSPOF(Single Point of Failure。単一障害点)がないシステム
マスタースレーブレプリケーション
マスタースレーブレプリケーションを利用可能です。このセクションではどのようにシステムを構成すればよいかを説明します。
小さいシステム
小さいシステムでは、2つのサーバーだけがあるとします。1つがマスターGroongaサーバーで、もうひとつがスレーブGroongaサーバーです。( table_create
、 column_create
や load
のような)すべての更新系のコマンドをfluentdに送ります。fluentdでは、クライアントから groonga
inputプラグインを使ってGroongaのコマンドを受け取ります。受け取ったコマンドはそのままマスターGroongaサーバーへ素通しし、マスターGroongaサーバーからのレスポンスをクライアントへ返します。 groonga
inputプラグインは、Groongaのコマンドとそのレスポンスを素通しするときに、更新系のコマンドをfluentのメッセージに変換します。fluentのメッセージは groonga
outputプラグインでスレーブGroongaサーバーへ送られます。
この構成のときの構成図です。
update update
and and
search +---------+ search +---------+
+--------+ <------> | fluentd | <------> | master |
| | +---------+ | Groonga |
| client | update | +---------+
| | \_/
| | search +---------+
+--------+ <------> | slave |
| Groonga |
+---------+
Fluentdはクライアント側かマスターGroongaサーバー側に置きます。データを更新するクライアントが1つの場合は、クライアント側に置くのがよいでしょう。データを更新するクライアントが複数いる場合は、マスターGroongaサーバー側に置くのがよいでしょう。
レプリケーションを使えば、複数のサーバーで検索サービスを提供することができるため、パフォーマンスを向上できます。可用性を上げるためにレプリケーションを使うことはできません。もし、マスターGroongaサーバーかFluentdがダウンしたら、このシステムはデータを更新できません。(スレーブGroongaサーバーは稼働しているため、検索機能は利用可能です。)
以下は設定例です。
# マスターGroongaサーバー用設定
<source>
@type groonga
protocol gqtp # あるいは下の行を使う
# protocol http
bind 127.0.0.1 # クライアント側にFluentdを置く場合
# bind 192.168.0.1 # マスターGroongaサーバー側にFluentdを置く場合
port 10041
real_host 192.168.29.1 # マスターGroongaサーバーのIPアドレス
real_port 10041 # マスターGroongaサーバーのポート番号
# real_port 20041 # マスターGroongaサーバー側にFluentdを置く場合は
# 違うポート番号を使うこと
</source>
# スレーブGroongaサーバー
<match groonga.command.*>
@type groonga
protocol gqtp # あるいは下の行を使う
# protocol http # マスターGroongaサーバーとスレーブGroongaサーバーで
# 違うプロトコルを使うこともできる
host 192.168.29.29 # スレーブGroongaサーバーのIPアドレス
port 10041 # スレーブGroongaサーバーのポート番号
# buffer
flush_interval 1s # レプリケーションの遅延を小さくするため小さな値を使う
## 復帰したスレーブGroongaサーバーへデータ再送をサポートするために以下の
## 設定をする。
## もし、スレーブGroongaサーバーがダウンするケースを考慮しなくてもよいなら、
## 以下の設定は必要ありません。
## fluentdが再起動したときのデータ再送をサポートする設定
# buffer_type file
# buffer_path /var/log/fluent/groonga.*.buffer
## loadコマンドの1つのレコードが大きいときは大きな値を使います。
## loadコマンドの1つのレコードが1つのチャンクになります。
# buffer_chunk_limit 256m
## スレーブGroongaサーバーが長い間ダウンした後のデータ再送をサポートするには
## 大きい値を指定してください。
## 17: 約1.5日 =
## ((2 ** 0) + (2 ** 1) + ... + (2 ** 17)) / 60.0 / 60.0 / 24.0
## (デフォルト)
## 18: 約3.0日 = ((2 ** 0) + ... + (2 ** 18)) / ...
## 19: 約6.0日 = ((2 ** 0) + ... + (2 ** 19)) / ...
# retry_limit 19
## たくさんのレコードをロードするときは大きな値にします。
## loadコマンドの中の1つのレコードが1つのチャンクに対応します。
# buffer_queue_limit 10000
</match>
ダウンしたfluentdを復旧する方法
もし、fluentdがダウンしたら、fluentdを再起動するだけで復旧します。もし、fluentdが更新系のコマンドを実行している最中にダウンしたとしたら、最後の更新系のコマンドをfluentdに再送しなければいけないかもしれません。
fluentdが復旧するまでデータを更新することはできません。
ダウンしたマスターGroongaサーバーを復旧する方法
以下は、ダウンしたマスターGroongaサーバーを復旧する手順です。
- fluentdを止めます。
- スレーブGroongaサーバーがあるホストで
grndump /スレーブ/Groonga/サーバー/の/データベース/のパス > SLAVE_GROONGA_DUMP.grn
を実行します。 - マスターGroongaサーバーがあるホストで
groonga -n /マスター/Groonga/サーバー/の/データベース/の/パス < SLAVE_GROONGA_DUMP.grn
を実行します。 - マスターGroongaサーバーを起動します。
- fluentdを起動します。
復旧が完了するまでデータを更新することはできません。
ダウンしたスレーブGroongaサーバーを復旧する方法
以下はダウンしたスレーブGroongaサーバーを復旧する手順です。
- マスターGroongaサーバーがあるホストで
grndump /マスター/Groonga/サーバー/の/データベース/の/パス > MASTER_GROONGA_DUMP.grn
を実行します。 - スレーブGroongaサーバーがあるホストで
groonga -n /スレーブ/Groonga/サーバー/の/データベース/の/パス < MASTER_GROONGA_DUMP.grn
を実行します。 - スレーブGroongaサーバーを起動します。
復旧中もデータを更新することができます。もし、システムが1つのマスターGroongaサーバーだけですべての検索リクエストを処理できない場合は、そのシステムはダウンします。
fluentdのバッファキューが溢れる( buffer_queue_limit
参照)前、かつ、fluentdが再送を諦める( retry_limit
参照)前にスレーブGroongaサーバーを復旧する必要があります。以下は復旧が間に合わなかった時に復旧する手順です。
- fluentdを止めます。
- マスターGroongaサーバーがあるホストで
grndump /マスター/Groonga/サーバー/の/データベース/の/パス > MASTER_GROONGA_DUMP.grn
を実行します。 - スレーブGroongaサーバーがあるホストで
groonga -n /スレーブ/Groonga/サーバー/の/データベース/の/パス < MASTER_GROONGA_DUMP.grn
を実行します。 - スレーブGroongaサーバーを起動します。
- fluetndを起動します。
復旧が完了するまでデータを更新することはできません。
中規模のシステム
中規模のシステムでは3つ以上のGroongaサーバーがいます。fluentdは2つ以上のスレーブGroongaサーバーを copy
outputプラグインと groonga
outputプラグインで更新します。
この構成のときの構成図です。
update update
and and
search +---------+ search +---------+
+--------+ <------> | fluentd | <------> | master |
| | +---------+ | Groonga |
| client | +--------+ +---------+
| | |
+--------+ search +---------+ |
| | <------> | slave | <-+ update
| client | | Groonga | |
| | +---------+ |
+--------+ search +---------+ |
| | <------> | slave | <-+ update
| client | | Groonga | |
| | +---------+ |
+- ... -+ ... ... ...
以下は設定例です。
# マスターGroongaサーバー用設定
<source>
@type groonga
protocol gqtp # あるいは下の行を使う
# protocol http
bind 127.0.0.1 # クライアント側にFluentdを置く場合
# bind 192.168.0.1 # マスターGroongaサーバー側にFluentdを置く場合
port 10041
real_host 192.168.29.1 # マスターGroongaサーバーのIPアドレス
real_port 10041 # マスターGroongaサーバーのポート番号
# real_port 20041 # マスターGroongaサーバー側にFluentdを置く場合は
# 違うポート番号を使うこと
</source>
# スレーブGroongaサーバー用
<match groonga.command.*>
@type copy
# 最初のスレーブGroongaサーバー
<store>
@type groonga
protocol gqtp # あるいは下の行を使う
# protocol http # マスターGroongaサーバーとスレーブGroongaサーバーで
# 違うプロトコルを使うこともできる
host 192.168.29.2 # スレーブGroongaサーバーのIPアドレス
port 10041 # スレーブGroongaサーバーのポート番号
# buffer
flush_interval 1s # レプリケーションの遅延を小さくするため小さな値を使う"
## 復帰したスレーブGroongaサーバーへデータ再送をサポートするために以下の
## 設定をする。
## もし、スレーブGroongaサーバーがダウンするケースを考慮しなくてもよいなら、
## 以下の設定は必要ありません。
## fluentdが再起動したときのデータ再送をサポートする設定
# buffer_type file
# buffer_path /var/log/fluent/groonga1.*.buffer
## loadコマンドの1つのレコードが大きいときは大きな値を使います。
## loadコマンドの1つのレコードが1つのチャンクになります。
# buffer_chunk_limit 256m
## スレーブGroongaサーバーが長い間ダウンした後のデータ再送をサポートするには
## 大きい値を指定してください。
## 17: 約1.5日 =
## ((2 ** 0) + (2 ** 1) + ... + (2 ** 17)) / 60.0 / 60.0 / 24.0
## (デフォルト)
## 18: 約3.0日 = ((2 ** 0) + ... + (2 ** 18)) / ...
## 19: 約6.0日 = ((2 ** 0) + ... + (2 ** 19)) / ...
# retry_limit 19
## たくさんのレコードをロードするときは大きな値にします。
## loadコマンドの中の1つのレコードが1つのチャンクに対応します。
# buffer_queue_limit 10000
</store>
# 2番目のスレーブGroongaサーバー
<store>
@type groonga
protocol gqtp # あるいは下の行を使う
# protocol http # マスターGroongaサーバーとスレーブGroongaサーバーで
# 違うプロトコルを使うこともできる
host 192.168.29.3 # スレーブGroongaサーバーのIPアドレス
port 10041 # スレーブGroongaサーバーのポート番号
# buffer
# ...
</store>
# さらに追加のスレーブGroongaサーバー
# <store>
# @type groonga
# ...
# </store>
</match>
TODO: ...
大規模システム
大規模なシステムでは2つ以上のスレーブGroongaサーバークラスターがあります。マスターGroongaサーバーと通信するfluentdは、スレーブGroongaサーバークラスターの中にあるfluetnd(2つ以上)を使って更新します。そのために copy
outputプラグインと forward
outputプラグインを使います。スレーブクラスターはfluentdを1つ持ちます。スレーブGroongaサーバークラスターのfluentdは同じクラスター内にあるスレーブGroongaサーバーを copy
outputプラグインと groonga
outputプラグインで更新します。
この構成のときの構成図です。
update update
and and
search +---------+ search +---------+
+--------+ <--------> | fluentd | <------> | master |
| | +---------+ | Groonga |
| client | | +---------+
| | +------------------------------+
+--------+ +----------------------------------+ |
| | | slave cluster | |
| client | search | +---------+ update +---------+ | |
| | <------> | | slave | <------- | fluentd | <-+ update
+--------| | | Groonga | +---------+ | |
| | | +---------+ +-----------+ | |
| client | search | +---------+ | | |
| | <------> | | slave | <-+ update | |
+--------| | | Groonga | | | |
| | | +---------+ | | |
| ... | ... | ... ... | |
+----------------------------------+ |
+--------+ +----------------------------------+ |
| | | slave cluster | |
| client | search | +---------+ update +---------+ | |
| | <------> | | slave | <------- | fluentd | <-+ update
+--------| | | Groonga | +---------+ | |
| | | +---------+ +-----------+ | |
| client | search | +---------+ | | |
| | <------> | | slave | <-+ update | |
+--------| | | Groonga | | | |
| | | +---------+ | | |
| ... | ... | ... ... | |
+----------------------------------+ |
... ...
TODO: ...