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