はじめに
この文章は、Groongaドキュメント読書会1で学んだ事のメモです。
元のテキストで分からなかった事を中心に書きました。
1. Groongaの特徴
テキスト: http://groonga.org/ja/docs/characteristic.html
1.1. Groongaの概要
転置索引とは
通常の索引(index)とは「転置」(逆になっている)。
全文検索エンジンの世界においては、文章からキーワードを抽出して、マッピングを保存しておくもの。
通常は「文章⇒キーワード」な所を、「キーワード⇒文章」という流れで検索するので「転置(逆)」という。
※この理解は誤っていました。コメントで@ktouさんが詳しく解説してくださっています。
カラムストアと列指向データベース
一般的に、カラムストアと列指向データベースは同義のような形で使われる。
厳密にいうと、列指向データベースは設計思想でカラムストアはデータアクセスの実装方法との事。
1.2. 全文検索と即時更新
更新しながらでも検索できるという優れた特徴を持っている
通常は書き換えるために一時的にデータをロックするが、Groongaは書き換えるのではなく、別の場所にデータを書き込んだ後にそちらを参照するようにリンクを変える形で更新するため、書き換え中に壊れたデータを取得してしまうことがない(ATOMICに更新可能)。
複数の転置索引を統合するような重い処理を必要としない
通常、転置索引は作成コストが大きいので、一度作ると後からは変更できない。
そのような時は新しい索引を作成して検索するため、複数の索引を併用して検索している。
それがあまりに増えるとオーバーヘッドが多いため、そのような時に統合という処理を行っている。
これが非常に高コストであるため、実行中は全体の性能が劣化する。
Solrなど、通常の全文検索エンジンはこれを行っているが、Groongaは転置索引の変更が可能であるため不要。
なぜGroongaは転置索引の変更が可能なのか
Groongaはインデックスの各データの間に隙間があるため、データを間に差し込める。
通常は詰めて作った方が性能が高いため、他のエンジンはこのような仕組みになっていない。
なお、隙間を食いつぶした場合はインデックスの最後に追記する形となる?
1.4. 転置索引とトークナイザ
形態素方式とN-gram方式のどちらを採用すべきか
形態素解析は辞書ベースなので新語に弱い。そういう単語が多いときはN-gramが有利。
字面を重視したい時はN-gram、意味を重視したい時は形態素解析。という使い分け方もある。
(Ngram方式だと、「京大」を検索した時に、東京大空襲がヒットしうる)
1.6. 位置情報(緯度・経度)検索
転置索引を応用して高速な位置情報検索を実現
レストランのたとえ。A,B,Cなどの位置情報を転置索引として保存。
検索する範囲の中に、転置索引のどのキーワードが引っかかるかについては別の仕組みを用いて、転置検索の範囲検索のような事をしているわけではない。
1.8. Groonga サーバ
Groonga の独自プロトコルである GQTP(Groonga Query Transfer Protocol)
ステートレスであるHTTPと異なり、GQTPはステートフルなプロトコル。
そのため、連続して検索を行う場合オーバーヘッドが少ない。また、1回の転送量が少なくてすむ。
HTTPについては、Basic認証などの認証が出来る上、クライアントライブラリが豊富。
そのため、通信速度がボトルネックになるならGQTPを検討する価値があるが、通常はHTTPの方が扱いやすい。
なお、rubyのライブラリはどちらのプロトコルでも使える。
1.9. Groonga ストレージエンジン
Groonga 単体での利用、およびに MyISAM, InnoDB との連携
ここでいう単体とはMroongaのストレージモード。連携とはラッパーモードの意。
Mroongaを使うメリットデメリット
メリットとしてはMySQLの資産が使える事(レプリケーション等。そもそもSQLでアクセスできる)
ただし、groongaの機能のdrilldownを使えないため、GROUP BY
句で表現する必要がある。
- 実際には、mroonga_commandというユーザー定義関数を使えば可能だが、応答がJSONとなるため、普通のSQL的に使うのは難しい。
Mroongaストレージエンジンで作られたDBに、別に立てたGroongaからアクセスする事も可能。
ただ、Groongaから更新すると、その変更をMroongaが検知できずデータの不整合が起きるので参照専用とすべき。
後で試す/確認するリスト
カラムストアと列指向DBの本当の違いを確認する。- 列指向DBは、カラム追加のコストが行指向よりも小さいとの事だが、逆に通常のINSERTのような操作はコストが高い?
- 転置索引の変更が可能だとの事だが、インデックスのデータ間の隙間を使いつぶした場合でも、低コストに変更できるのか?