40
Hyper Hyper Estraier Estraier 設計と実装 設計と実装 株式会社ミクシィ 平林 幹雄 [email protected] 2006年11月6日 「オープンソースの全文検索、DBMSシステム」 講演資料

Hyper Estraierの設計と実装

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Hyper Estraierの設計と実装

Hyper Hyper EstraierEstraierのの設計と実装設計と実装

株式会社ミクシィ 平林 幹雄[email protected]

2006年11月6日「オープンソースの全文検索、DBMSシステム」 講演資料

Page 2: Hyper Estraierの設計と実装

アジェンダアジェンダ

• Hyper Estraierの概要

• N.M-gramインデックス

• スケールアウト戦略

Page 3: Hyper Estraierの設計と実装

Hyper Hyper EstraierEstraierの概要の概要

Page 4: Hyper Estraierの設計と実装

Hyper Hyper EstraierEstraierとはとは

• 読み方– ハイパーエストレイ(ア|ヤ)(ー)?

– estraier: [古仏] 迷う、はぐれる = stray

• 全文検索システム– 大量の文書を対象に「フリーワード検索」ができる

– 予め転置インデックスを用意することで高速に処理• 文書規模Nに対する時間計算量

– 全体のインデクシング = O(N) = データ量に比例

– 毎回の検索 = O(log N) = データ量の対数に比例

– N-gram法による漏れのない検索• 形態素解析の併用による精度向上

Page 5: Hyper Estraierの設計と実装

用途用途

• Web検索システム

– 特定のサイトの検索機能

– クローラ連携で、いわゆるWebサーチエンジンを実現

• メール検索システム

– 個人のメールボックスやメーリングリストアーカイブを検索

• ファイル検索システム

– 企業などのファイルサーバ上の文書を検索

– 個人のデスクトップ検索システム

• RDBの全文検索インデックス

– RDBMSに組み込んで任意のレコードを検索

Page 6: Hyper Estraierの設計と実装

ツールキットツールキット

• 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サーバ

Page 7: Hyper Estraierの設計と実装

アプリケーションアプリケーション

• 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

Page 8: Hyper Estraierの設計と実装

デモンストレーションデモンストレーション

• Wikipedia日本語版の検索システム– 約28万個の記事、合計1591MB、UTF-8

– アーカイブのXMLデータを加工してインポート

• 検索式– AND検索、OR検索、フレーズ検索、ワイルドカード検索

• スコアリング– 適合度順(TF-IDF)、更新日時順

• 属性検索– タイトル前方一致、タイトル中間一致

• 特殊検索– 類似文書検索、類似文書隠蔽(クリッピング)

• 表示機能– ヒント表示、スニペット表示、元データハイライト表示

Page 9: Hyper Estraierの設計と実装

システムアーキテクチャシステムアーキテクチャ

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

Page 10: Hyper Estraierの設計と実装

N.MN.M--gramgramインデックスインデックス

Page 11: Hyper Estraierの設計と実装

転置インデックスとは転置インデックスとは

• トークンの出現情報のデータベース– どのトークンがどのレコード(文書)にあるか

– 対象の規模にあまり依存しない検索性能• c.f.) 逐次探索方式(grep)

– トークンはレコード内のテキストから抽出• 分かち書き vs. N-gram論争

• Hyper EstraierではN-gramインデックスを実装– 検索漏れがない

– 辞書のメンテナンスが不要

– 多言語対応が容易

Page 12: Hyper Estraierの設計と実装

NN--gramgramインデックスの欠点インデックスの欠点

• インデックスが大きくなりすぎる

– トークン数が文字数とほぼ同じ

• 本日は晴天なり → 本日・日は・は晴・晴天・天な・なり

– 各トークンに対応するデータ量が大きい

• 連接判定のために出現位置情報の記録が必要

• インデクシングに時間がかかりすぎる

– スケーラビリティの限界はインデクシング時間の制約による

• 検索速度も遅くなる

– スループットを上げるには多くのマシンが必要

Page 13: Hyper Estraierの設計と実装

効率的なデータベースによる対策効率的なデータベースによる対策

• QDBM: Quick Database Manager

– UNIX-DBM系譜のファイルデータベース

• e.g.) NDBM、GDBM、Berkeley DB

– 「key/value」構造

– ライブラリとしてアプリケーションに組み込む

• SQL等の処理が不要

• ネットワーク経由のオーバーヘッドも不要

– Cによる実装

• mmapを利用するなどして最適化

– ハッシュ表とB+木をサポート

Page 14: Hyper Estraierの設計と実装

ハッシュ表とハッシュ表とB+B+木木

• ハッシュ表– キーにハッシュ関数を適用して探索空間を縮小

• O(1)の時間計算量• 探索は完全一致のみ

– キーの重複は不可• 値に配列等の構造を持たせて対処

– 各文書のメタデータ情報や元テキストの記録に利用• key=文書ID、value=メタデータ/テキスト

• B+木– キーをB木(多進平衡木)で編成して二分探索

• O(log N)の時間計算量 (キャッシュにより実質O(1) )

– 比較関数による探索(前方一致、範囲一致)– キーの重複が可能

• カーソルによりレコードを走査

– 転置インデックスや属性インデックスに利用• キー=トークン/属性値、value=文書IDの配列

Page 15: Hyper Estraierの設計と実装

ハッシュ表のイメージハッシュ表のイメージ

キー 値

ハッシュバケット

ハッシュ関数

キー 値

キー 値

キー 値

キー 値

キー 値

キー 値

セパレートチェーン

Page 16: Hyper Estraierの設計と実装

B+B+木のイメージ木のイメージ

キー 値

キー 値

キー 値

キー 値

キー 値

キー 値

キー 値

キー 値

キー 値

二分探索

二分探索キー 値

キー 値

キー 値

キー 値

キー 値

キー 値

キー 値

キー 値

二分探索

Page 17: Hyper Estraierの設計と実装

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)...

本 日 は 晴 天 な り

Page 18: Hyper Estraierの設計と実装

N.MN.M--gramgramインデックスとはインデックスとは

• N-gramインデックスの空間効率と時間効率を改善する手法

• 基本的な構造はN-gramインデックスと同じ

• 連接判定のアルゴリズムが違う– N-gram法の「文書内オフセット」を使わなくても連接判

定はできる

– 後続M個のトークンのハッシュ値を代用する• 文書内オフセットよりもデータ長が短くてよい

• 後続1個のトークンを用いればN.1-gram、2個ならN.2-gram...

• Hyper Estraierでは2.2-gramを採用

Page 19: Hyper Estraierの設計と実装

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

① 検索語からトークンを取り出す

② トークンのハッシュ値を算出

③ 転置インデックス内のレコードを取得し、ハッシュ値を比較

Page 20: Hyper Estraierの設計と実装

N.MN.M--gramgramインデックスの長所インデックスの長所

• 空間効率の改善

– インデックスのサイズが減少

• 文書内オフセットよりハッシュ値の方が情報量が少ない

• 時間効率の改善

– インデックスの更新が高速化

• インデックスのサイズが減少した分、writeの量が減る

– 1回の検索(read)で絞り込む能力が高い

• read = クエリの文字数 ÷ (トークンN文字+後続M文字)

Page 21: Hyper Estraierの設計と実装

N.MN.M--gramgramインデックスの短所インデックスの短所

• 検索ゴミが増える– false dropの問題

• クエリがN+M文字を超える場合

• ハッシュ値が衝突した場合 (1/256Mの確率)

– でも、気にしない。• N-gram法はどうせ検索ゴミが多い

• スニペット作成時にfalse dropを検査して回避可能

• term frequencyによるスコアリングの精度低下– トークンの出現回数を保持しないため

– でも、気にしない。• 日付等の属性でソートする場合には必要ない

• スコア情報を別途で持てばよい

Page 22: Hyper Estraierの設計と実装

N.MN.M--gramgramインデックスの性能インデックスの性能

• 2.2-gramインデックスのサイズ

– 2-gram(異なり語数が同じ)の約90%

– 4-gram(絞込み性能が同じ)の約30%

– 構築時間は2-gramとほぼ同じ

• 2.2-gramの検索時間

– 2-gramの約40%

– 3-gramの約120%

Page 23: Hyper Estraierの設計と実装

スケールアウト戦略スケールアウト戦略

Page 24: Hyper Estraierの設計と実装

スケーラビリティの向上策スケーラビリティの向上策

• スケールアップ

– 高性能の機材を使って性能を向上させる戦略

– 少数のハイエンドのサーバ機

– 集中型ストレージにデータを格納

• スケールアウト

– 多数の機材を使って性能を向上

– 多数の廉価PCサーバ

– 各々のサーバにデータを分散

• Hyper Estraierはスケールアウトを重視

Page 25: Hyper Estraierの設計と実装

スケールアップの特徴スケールアップの特徴

• 長所– 設計が楽

– プログラミングが楽

– メンテナンスが楽

• 短所– 最終的にどのくらいのサービス規模(ユーザ数)になるかを

見積もって機材の選定をしないといけない• 見積もりを誤ると、投資が無駄になるか、とんでもない追加投

資が必要になる

– 導入時の設備投資にやたら金がかかる• 稟議が通らねぇー orz

Page 26: Hyper Estraierの設計と実装

スケールアウトの特徴スケールアウトの特徴

• 長所– サービス規模の増大に伴って台数を逐次増加できる

– 導入時の設備投資に金がかからない

• 短所– 設計が大変

• どのデータがどのノードにあるかを管理するDBが必要

– プログラミングが大変• ネットワークプログラミング

• 分散トランザクション的な処理

• ミドルウェア的なものがあると楽 → Hyper Estraierが支援

– メンテナンスが大変• インストールや障害対応等を自動化する管理ツールが必要

Page 27: Hyper Estraierの設計と実装

分散処理のユースケース分散処理のユースケース

• インターネット環境

– 管理されざる個人同士の協調

– P2P連携

• サービスプロバイダ

– Google、Yahoo、mixiなどの事業体

– ホリゾンタルサーチとバーティカルサーチ

Page 28: Hyper Estraierの設計と実装

Hyper Hyper EstraierEstraierののP2PP2P機構機構

• インデックスの分散管理の仕組み

• ノードサーバ

– インデックスをネットワーク経由で操作するサービス

– マルチスレッドで、検索や更新を並列処理

– ノードサーバ同士がP2P的にメタ検索をかけあう

• ノードマスタ

– 複数のノードサーバを単一プロセス内で稼動

Page 29: Hyper Estraierの設計と実装

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

Page 30: Hyper Estraierの設計と実装

ノード間の多階層メタ検索ノード間の多階層メタ検索

• 各ノードは他のノードに一方的にリンクを張る

– リンク先の許可は不要

• 検索時にはグラフ構造を動的にツリー構造に変換

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

Page 31: Hyper Estraierの設計と実装

水平と垂直水平と垂直

• ホリゾンタルサーチ– 対象の全文書を対象に広く浅く検索する

• 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

Page 32: Hyper Estraierの設計と実装

ホリゾンタルサーチの戦略ホリゾンタルサーチの戦略

• マシンの数をできるだけ減らしたい

– 投資を抑えたい、メンテを楽にしたい

– メタ検索の遅延を抑えたい

• 個々のノードの能力を最大化したい

– 1つのマシンに1つのインデックス

– 検索系と更新系の分離

• スループットの確保

• 更新系で作ったインデックスを検索系にコピー

• どちらかが死んでもサービスが完全停止しないで済む

user

merger

node node node node

indexer indexer

Page 33: Hyper Estraierの設計と実装

親子インデックス作戦親子インデックス作戦

• インデックスを2つに分割

– 子インデックス:頻繁に更新される小さいインデックス

– 親インデックス:更新は子インデックスをマージするのみ

• ローカルメタ検索

– 親子をメタ検索して結果を動的にマージして提示

indexer

child index

search node

child indexparent index

searcher

searcher

search node

child indexsearch node

child indexparent index

searcher

merge

merge

copy

copy

Page 34: Hyper Estraierの設計と実装

バーティカルサーチの戦略バーティカルサーチの戦略

• マシンの数をできるだけ減らしたい

– 投資を抑えたい、メンテを楽にしたい

• 個々のマシンに乗せるノードを増やしたい

– ひとつのマシンに1000個単位のノード

• 個々のインデックスのデータ量は比較的小さい

• インデックスのフットプリントは極小化

– 検索系と更新系は同一

• 検索と更新が同時に起こることは稀

• 元データは別のマシンで管理

• 死んだ場合はインデックスを作り直す

Page 35: Hyper Estraierの設計と実装

擬似ノードサーバ擬似ノードサーバ

• 全ノードを常駐させることは不可能

– メモリとファイルディスクリプタが足りない

– 生存監視が面倒

• CGIスクリプトとして実装

– クエリを受け取る都度、インデックスを開く• 対象が多いのでコネクションプールの効果は薄い

– Apacheの機能(キャッシュ等)が利用可能

indexindex

index index

index index

indexer

searcher

web server

node

Page 36: Hyper Estraierの設計と実装

擬似インデックス擬似インデックス

• 新規文書は個別のファイルに保存

– 逐次探索方式で検索

– 通常のインデックスと同じAPI = 擬似インデックス

• 一定の規模になったらインデックスにマージ

– インデックスの更新頻度を抑えたい

– 一気にやった方がキャッシュが利くので効率が良い

• インデックスと擬似インデックスをメタ検索

index

pseudo index

searcher

node

Page 37: Hyper Estraierの設計と実装

まとめまとめ

Page 38: Hyper Estraierの設計と実装

まとめまとめ

• 全文検索システムHyper Estraier– 高性能・高機能の全文検索システム

– アプリケーションが簡単に作れるツールキット

• N.M-gramインデックス– QDBMを利用して基本性能を確保

– N-gramインデックスの空間効率・時間効率を改善

• スケールアウト戦略– サービス規模の拡大に随時対応できる

– P2P機構による分散処理

– ホリゾンタルサーチとバーティカルサーチで別個の戦術

Page 39: Hyper Estraierの設計と実装

詳しくは詳しくは……

• 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

Page 40: Hyper Estraierの設計と実装

ご清聴ありがとうございましたHappy Hacking...