More Related Content More from Hiroshi Ono (20) Hyper Estraierの設計と実装1. 2006年11月6日
「オープンソースの全文検索、DBMSシステム」 講演資料
Hyper Estraierの
設計と実装
株式会社ミクシィ 平林 幹雄
mikio@users.sourceforge.net
4. Hyper Estraierとは
• 読み方
– ハイパーエストレイ(ア|ヤ)(ー)?
– estraier: [古仏] 迷う、はぐれる = stray
• 全文検索システム
– 大量の文書を対象に「フリーワード検索」ができる
– 予め転置インデックスを用意することで高速に処理
• 文書規模Nに対する時間計算量
– 全体のインデクシング = O(N) = データ量に比例
– 毎回の検索 = O(log N) = データ量の対数に比例
– N-gram法による漏れのない検索
• 形態素解析の併用による精度向上
5. 用途
• Web検索システム
– 特定のサイトの検索機能
– クローラ連携で、いわゆるWebサーチエンジンを実現
• メール検索システム
– 個人のメールボックスやメーリングリストアーカイブを検索
• ファイル検索システム
– 企業などのファイルサーバ上の文書を検索
– 個人のデスクトップ検索システム
• RDBの全文検索インデックス
– RDBMSに組み込んで任意のレコードを検索
6. ツールキット
• C言語のライブラリ
– 各種アプリケーションに組み込み可能
• オブジェクト指向風味のインターフェイス
– 各種言語バインディング
• Java、Ruby、Perl、PHP、Python、Haskell
• 典型的アプリケーションの標準添付
– インデックス管理用コマンド
• コマンドラインでインデックス構築と検索
– 検索用CGIスクリプト インデクサ クローラ 検索フォーム P2Pサーバ バインディング
• Webインターフェイスで検索 全文検索ライブラリ(libestraier)
– インデックス管理用サーバ データベースライブラリ(libqdbm)
• P2P型の検索機構 ファイルシステム
• マルチプラットフォーム
– UNIX(Linux、xxxBSD、Solaris、HP-UX、Mac OS X)およびWindowsで動作
– GNU LGPLに基づくオープンソース製品
7. アプリケーション
• Web検索システム
– 同梱のコマンドとCGIスクリプトだけでOK
– 賢いクローラも標準添付!
– mod_estraier
• メール検索システム
– mhファミリなら、同梱のコマンドとCGIスクリプトだけでOK
– Mew、Kamailv3、ximapd、秀丸メール
• ファイル検索システム
– 同梱のコマンドとCGIスクリプトだけでOK
– PDF、Word、Excel、PowerPointなどにも対応
– Strigi、gdestraier、DesktopHE、hyper-estraier-mode
• RDBの全文検索インデックス
– RDBMSに組み込んで任意のレコードを検索
– pgestraier、acts_as_searchable
8. デモンストレーション
• Wikipedia日本語版の検索システム
– 約28万個の記事、合計1591MB、UTF-8
– アーカイブのXMLデータを加工してインポート
• 検索式
– AND検索、OR検索、フレーズ検索、ワイルドカード検索
• スコアリング
– 適合度順(TF-IDF)、更新日時順
• 属性検索
– タイトル前方一致、タイトル中間一致
• 特殊検索
– 類似文書検索、類似文書隠蔽(クリッピング)
• 表示機能
– ヒント表示、スニペット表示、元データハイライト表示
9. システムアーキテクチャ
handle original documents
users / user agents
document repository
administrate the system search for documents
documents
fetch documents
extract text data
gatherer searcher compose query
text filter query composer
application domain
connect as a writer: register/remove document objects connect as a reader: search/retrieve document objects
text analyzer
database manager
inverted index
other utilities
document data meta data
core library of Hyper Estraier
11. 転置インデックスとは
• トークンの出現情報のデータベース
– どのトークンがどのレコード(文書)にあるか
– 対象の規模にあまり依存しない検索性能
• c.f.) 逐次探索方式(grep)
– トークンはレコード内のテキストから抽出
• 分かち書き vs. N-gram論争
• Hyper EstraierではN-gramインデックスを実装
– 検索漏れがない
– 辞書のメンテナンスが不要
– 多言語対応が容易
12. N-gramインデックスの欠点
• インデックスが大きくなりすぎる
– トークン数が文字数とほぼ同じ
• 本日は晴天なり → 本日・日は・は晴・晴天・天な・なり
– 各トークンに対応するデータ量が大きい
• 連接判定のために出現位置情報の記録が必要
• インデクシングに時間がかかりすぎる
– スケーラビリティの限界はインデクシング時間の制約による
• 検索速度も遅くなる
– スループットを上げるには多くのマシンが必要
13. 効率的なデータベースによる対策
• QDBM: Quick Database Manager
– UNIX-DBM系譜のファイルデータベース
• e.g.) NDBM、GDBM、Berkeley DB
– 「key/value」構造
– ライブラリとしてアプリケーションに組み込む
• SQL等の処理が不要
• ネットワーク経由のオーバーヘッドも不要
– Cによる実装
• mmapを利用するなどして最適化
– ハッシュ表とB+木をサポート
14. ハッシュ表とB+木
• ハッシュ表
– キーにハッシュ関数を適用して探索空間を縮小
• O(1)の時間計算量
• 探索は完全一致のみ
– キーの重複は不可
• 値に配列等の構造を持たせて対処
– 各文書のメタデータ情報や元テキストの記録に利用
• key=文書ID、value=メタデータ/テキスト
• B+木
– キーをB木(多進平衡木)で編成して二分探索
• O(log N)の時間計算量 (キャッシュにより実質O(1) )
– 比較関数による探索(前方一致、範囲一致)
– キーの重複が可能
• カーソルによりレコードを走査
– 転置インデックスや属性インデックスに利用
• キー=トークン/属性値、value=文書IDの配列
15. ハッシュ表のイメージ
キー 値
キー 値
ハッシュ関数
キー 値
キー 値
セパレートチェーン
キー 値
キー 値
キー 値
ハッシュバケット
16. B+木のイメージ
キー 値
キー 値
キー 値 キー 値
キー 値
二分探索
キー 値
キー 値
キー 値
二分探索 キー 値
二分探索
キー 値
キー 値
キー 値
キー 値
キー 値
キー 値
キー 値
キー 値
17. N-gramインデックスの構造
• トークンをデータベースの検索キーにする
• レコードの値はトークンの出現位置情報
– 「文書ID」と「文書内オフセット」のペア
• 実際は、文書ID毎に後続を可変長でまとめる
– 文書内オフセットによりトークンの連接を判定
本日は晴天なり
本日: (1:52), (1:89), (2:7), (2:128), (2:223), (2.300)...
は晴: (1:23), (1:22), (1:92), (2:9), (2:102), (3:8)...
18. N.M-gramインデックスとは
• N-gramインデックスの空間効率と時間効率を改善
する手法
• 基本的な構造はN-gramインデックスと同じ
• 連接判定のアルゴリズムが違う
– N-gram法の「文書内オフセット」を使わなくても連接判
定はできる
– 後続M個のトークンのハッシュ値を代用する
• 文書内オフセットよりもデータ長が短くてよい
• 後続1個のトークンを用いればN.1-gram、2個ならN.2-gram...
• Hyper Estraierでは2.2-gramを採用
19. N.M-gramインデックスの構造
• トークンをデータベースの検索キーにする
• レコードの値は文書IDとハッシュ値のペア
フ ァ イ ル ① 検索語からトークンを取り出す
② トークンのハッシュ値を算出
「ファ」 0x99 0xF6
「ァイ」 0x8F 0xFF
③ 転置インデックス内のレコードを
「イル」 0xFF 0xFF
取得し、ハッシュ値を比較
ファ: 0x00, 0x00, 0x00, 0x01, 0x99, 0xF6, 0x00
ァイ: 0x00, 0x00, 0x00, 0x01, 0x8F, 0x02, 0x8F, 0x6D, 0x00
イル: 0x00, 0x00, 0x00, 0x01, 0x88, 0x66, 0xB1, 0x1D, 0x00
20. N.M-gramインデックスの長所
• 空間効率の改善
– インデックスのサイズが減少
• 文書内オフセットよりハッシュ値の方が情報量が少ない
• 時間効率の改善
– インデックスの更新が高速化
• インデックスのサイズが減少した分、writeの量が減る
– 1回の検索(read)で絞り込む能力が高い
• read = クエリの文字数 ÷ (トークンN文字+後続M文字)
21. N.M-gramインデックスの短所
• 検索ゴミが増える
– false dropの問題
• クエリがN+M文字を超える場合
• ハッシュ値が衝突した場合 (1/256Mの確率)
– でも、気にしない。
• N-gram法はどうせ検索ゴミが多い
• スニペット作成時にfalse dropを検査して回避可能
• term frequencyによるスコアリングの精度低下
– トークンの出現回数を保持しないため
– でも、気にしない。
• 日付等の属性でソートする場合には必要ない
• スコア情報を別途で持てばよい
24. スケーラビリティの向上策
• スケールアップ
– 高性能の機材を使って性能を向上させる戦略
– 少数のハイエンドのサーバ機
– 集中型ストレージにデータを格納
• スケールアウト
– 多数の機材を使って性能を向上
– 多数の廉価PCサーバ
– 各々のサーバにデータを分散
• Hyper Estraierはスケールアウトを重視
25. スケールアップの特徴
• 長所
– 設計が楽
– プログラミングが楽
– メンテナンスが楽
• 短所
– 最終的にどのくらいのサービス規模(ユーザ数)になるかを
見積もって機材の選定をしないといけない
• 見積もりを誤ると、投資が無駄になるか、とんでもない追加投
資が必要になる
– 導入時の設備投資にやたら金がかかる
• 稟議が通らねぇー orz
26. スケールアウトの特徴
• 長所
– サービス規模の増大に伴って台数を逐次増加できる
– 導入時の設備投資に金がかからない
• 短所
– 設計が大変
• どのデータがどのノードにあるかを管理するDBが必要
– プログラミングが大変
• ネットワークプログラミング
• 分散トランザクション的な処理
• ミドルウェア的なものがあると楽 → Hyper Estraierが支援
– メンテナンスが大変
• インストールや障害対応等を自動化する管理ツールが必要
29. P2P連携のイメージ
• アプリケーションとノードサーバはC/S型接続
• ノードサーバ間はP2P型接続
• 通信プロトコルはHTTPベース
node master
application
node server node server node server
node API
C/S index P2P index P2P index
P2P P2P
node master
application
node server node server node server
node API
C/S index P2P index P2P index
30. ノード間の多階層メタ検索
• 各ノードは他のノードに一方的にリンクを張る
– リンク先の許可は不要
• 検索時にはグラフ構造を動的にツリー構造に変換
Graph of Links Search from the node A
node B
node A node B
node A node C
node D
Search from the node B
node C node D
node C
node B node A
node D
Search from the node D
Search from the node C
node B node A
node D node C
node C
31. 水平と垂直
• ホリゾンタルサーチ
user
– 対象の全文書を対象に広く浅く検索する
merger
• e.g.) Google、Yahoo他
node node node node
– 分散処理のノード数は比較的少ない
– 単一のエントリからのメタ検索で対処
• バーティカルサーチ
– 特定の文書を対象に狭く深く検索する
• e.g.) GMail、Yahooのディレクトリ検索 user user user user user user user
– 分散処理のノード数が比較的多い node node node node node node node
– 個々のノードを探索するだけでよい
32. ホリゾンタルサーチの戦略
• マシンの数をできるだけ減らしたい
– 投資を抑えたい、メンテを楽にしたい
– メタ検索の遅延を抑えたい
• 個々のノードの能力を最大化したい user
merger
– 1つのマシンに1つのインデックス
node node node node
– 検索系と更新系の分離
indexer indexer
• スループットの確保
• 更新系で作ったインデックスを検索系にコピー
• どちらかが死んでもサービスが完全停止しないで済む
33. 親子インデックス作戦
• インデックスを2つに分割
– 子インデックス:頻繁に更新される小さいインデックス
– 親インデックス:更新は子インデックスをマージするのみ
• ローカルメタ検索
– 親子をメタ検索して結果を動的にマージして提示
search node
searcher
search node indexer
parent index child index
searcher merge
copy child index
search node
searcher child index
parent index child index copy
merge
34. バーティカルサーチの戦略
• マシンの数をできるだけ減らしたい
– 投資を抑えたい、メンテを楽にしたい
• 個々のマシンに乗せるノードを増やしたい
– ひとつのマシンに1000個単位のノード
• 個々のインデックスのデータ量は比較的小さい
• インデックスのフットプリントは極小化
– 検索系と更新系は同一
• 検索と更新が同時に起こることは稀
• 元データは別のマシンで管理
• 死んだ場合はインデックスを作り直す
35. 擬似ノードサーバ
• 全ノードを常駐させることは不可能
– メモリとファイルディスクリプタが足りない
– 生存監視が面倒
• CGIスクリプトとして実装
– クエリを受け取る都度、インデックスを開く
• 対象が多いのでコネクションプールの効果は薄い
– Apacheの機能(キャッシュ等)が利用可能
node
web server index index
indexer index index
searcher index index
36. 擬似インデックス
• 新規文書は個別のファイルに保存
– 逐次探索方式で検索
– 通常のインデックスと同じAPI = 擬似インデックス
• 一定の規模になったらインデックスにマージ
– インデックスの更新頻度を抑えたい
– 一気にやった方がキャッシュが利くので効率が良い
• インデックスと擬似インデックスをメタ検索
node
index
searcher
pseudo index
38. まとめ
• 全文検索システムHyper Estraier
– 高性能・高機能の全文検索システム
– アプリケーションが簡単に作れるツールキット
• N.M-gramインデックス
– QDBMを利用して基本性能を確保
– N-gramインデックスの空間効率・時間効率を改善
• スケールアウト戦略
– サービス規模の拡大に随時対応できる
– P2P機構による分散処理
– ホリゾンタルサーチとバーティカルサーチで別個の戦術
39. 詳しくは…
• Hyper Estraierのプロジェクトページ
– http://hyperestraier.sourceforge.net/
• デモサイト(Wikipedia検索)
– http://athlon64.fsij.org/~mikio/wikipedia/estseek.cgi
• メーリングリスト(日本語/英語)
– http://lists.sourceforge.net/lists/listinfo/hyperestraier-users-ja
– http://lists.sourceforge.net/lists/listinfo/hyperestraier-users