アペフチ

Groongaの運用(データの守り方)

Groongaで学ぶ全文検索 2016-01-15に参加して来た。今日のテーマは運用、その中でもデータの守り方。

RDBMSでのデータの守り方

Groongaの話の前に、ファイルとRDBMSでのデータの守り方の話をしてもらった。

ファイルにデータを書き込むとデータが永続化する。書き込みの時に、途中で何らかの理由で中断が起きると途中までしか書き込まれない。「Hello」と書き込むつもりだったのに「Hel」までしか書き込まれていない、といったことが起こる。これはデータが守られていない状態だと言える。不測の事態のせいでおかしなデータを持つことになってしまっている。

RDBMSでは、こういった「おかしなデータ」が存在しないように、トランザクションを使うようになっている。トランザクションを使うと、場合によってはデータが書き込まれていないことがあるが、途中まで書き込まれているというおかしな状態になるのは防ぐことができる。

RDBMSがこうして頑張っていても、ストレージデバイスが壊れるとデータは失われてしまう。これを防ぐのは「運用」の仕事になる。

データ消失を防ぐためには、何らかの方法でコピーを取る。コピーがあればあるだけ、それら全部が同時に壊れる可能性は低くなるので、データは守られる。ただ、お金が掛かったり帯域を使用したりするというトレードオフがある。

Groongaでのデータの守り方

ここまでがデータを守る運用の一般的な話で、ここから全文検索エンジン、特にGroonga族の話。

全文検索エンジンはトランザクションに対応している物は少なく、Groongaも対応していない。こうした時におかしなデータという状態を防ぐには大きく分けて二つの方法がある。

一つはデータベースのデータのバックアップを取っておいて、データ損失が起こったら、バックアップ時点へ巻き戻す方法。この場合、バックアップ時点から障害時点までの間に新しく作られたデータは失われ、更新されたデータは更新前の物に戻る。

二つ目は、Groongaでデータがおかしな状態になったり失われたりするのを防ぐのは諦めて、マスターデータの方が失われないよう仕組みを整える方法。マスターデータがあれば、いつでもGroongaのインデックスを復旧できる。Groongaの運用では、こちらのほうが現実的。マスターデータの守り方は色々あるので、データの性質やシステムの条件などで適切な物を選ぶ。RDBMS上のデータをマスターとしたり、ファイルとして保存したり、クラウド上のデータストアに置いたり。

復旧に掛かる時間

復旧することでデータを元に戻せるが、これに時間が掛かると、ダウンタイムがそれだけ長くなってしまう。上の二つ目、マスターデータを頑張って守る方法は、Groongaの復旧では一から全てのデータを入れ直すので、最も時間がかかる。

一つ目の方法の時間の掛かり方は、バックアップ時点から障害時点までの間のデータの扱い次第。そこのデータを諦めるなら、バックアップが(コピーなどするだけで)そのまま使えるので復旧は速い。バックアップ時点から障害時点までは、コピーではなくて差分バックアップを取っておくようにする方法もある。この場合は、バックアップ時点までの復旧は速く、そこから差分バックアップの内容を適用する部分では時間が掛かる。

また、一つ目の方法、コピーを取る方法のバリエーションとして、レプリケーションもある。レプリケーションは概ねリアルタイムに全データをバックアップ取れるが、デザイン上の問題やネットワーク遅延、マスターとレプリカ間の性能の違いなどで遅延はある。

Groongaでのバックアップ

Groongaにはトランザクションがないので、書き込み中に処理が止まるとデータがおかしなことになってしまう(ことがある)。マスターデータを用意して復旧に備えるのが現実的な運用になる。この時、前述の通り復旧に時間が掛かってしまうことになるが、普段サービスしている時は一つ一つ順にデータを書き込んでいるような物でも、まとめて一度に書き込めるモードがあって、これを使うとより速く復旧できる。また、そもそもGroongaは書き込み性能が高いので、RDBMSに比べると復旧は速い。

Groonga族のMroonga、PGroongaでのバックアップは、それぞれのRDBMSの仕組みに乗るのがよい。それぞれトランザクションやレプリケーションがある。

また、MySQLの場合、InnoDBのレプリケーション先としてMroongaを選ぶことができる。こうすると、(データが守られやすい)InnoDBをマスターデータとして考えることができる。

PostgreSQLにもレプリケーションの仕組みはあるが、MySQLのレプリケーションの仕組みとはだいぶ違う。MySQLではINSERTなどの命令をレプリケーションに流すので、その命令をGroongaの物として読み替えることができた。PostgreSQLはファイルパスやファイル内のバイトオフセットなど物理的な位置を流してレプリケーションに使うので、この情報をGroongaのインデックス更新のために読み替えることができない。そこで、復旧の際には、PostgreSQLにREINDEXを書けてGroongaのインデックスを作り直すことになる。

レプリケーションではまりがちな罠

また、全文検索エンジンに限らないがレプリケーションの運用について大事なことは、システムのキャパシティを考える時にレプリカを含んではいけないということだ。マスターとレプリカを含めた台数でちょうどさばけているようなシステムは、レプリカが一台落ちただけで、システム全体が検索をさばき切れなくなって、落ちたりする。

レプリカは遊んでいるように見えるのでつい使いたくなるが使ってはいけない。正確には、レプリカを入れてちょうど検索を捌けるというようなプランニング、運用をしてはいけない。

その他

気になったので聞いてみた。マスターDBでSSDを使うのはありなのか? 実際SSDで運用している人がいた。のでありなんだろうなあ。

Groongaのデータをコピーやdumpコマンドによってバックアップ取る際、中途半端な状態のコピーになってしまうことはないのか? ある。のでシステムから切り離してバックアップするとか、バックアップ専用にテーブルを作ってバックアップ取ったら消すとか、工夫して運用する必要がある。