はじめに
社内で伊藤 直也さんと田中 慎司さんが書かれた
『Web開発者のための大規模サービス技術入門』 を輪読しました。
今回は、僕が担当した 第5回の「大規模データ処理[実践]入門」についてまとめます。
なお、本書は2010年に出版された本であるため、
少なくとも第5回の内容は今では当たり前のことという印象を受けました。
それでも、しっかりと文章で学んでおくことは大事だと思うのでまとめます。
★印は個人メモです。
以下まとめ
大量なデータを扱う場面
全文検索やデータマイニングなど RDBMSで処理できない規模のデータを
処理したい場面は多く存在します。
では、RDBMSが使えない規模のデータをどう処理すればいいでしょうか。
データを抽出
結論から言うと、RDBMSで扱うことができないデータは、適宜RDBMSから 抽出 して利用します。
具体的には
バッチ処理でRDBMSからデータを抽出し、
別途インデックスサーバのようなものを作って、そこに入れていきます。
★ ここで言っているインデックスサーバというのは、例えば全文検索用であれば
「検索用にチューニングした(検索しやすくした)データ構造」と考えるべきでしょう。
★ 最近は、Fluentd を使用してログを外部に吐き出してから解析したりしますよね。
それと考え方は一緒だと思います。
インデックスサーバにはRPC(Remote Procedure Call)を使ってアクセスします。
(なお、RPCと言いましたが、現在では Web API でのアクセスが一般的なので、以降、 Web API を例に使用します)
イメージとしては下図のようになります。
用途特化型のインデクシング
上述した方法を、はてな社(著者がはてな社出身の方なのでよく出てきます)では、
用途特化型インデクシング と呼ぶそうです。
用途特化型インデクシングとRDBMS
RDBMS はデータソートや統計処理、JOIN など、データに対して様々な処理を行うことができます。
しかし、汎用的故に、特定の目的だけに使うときには、それ用にチューニングしたデータ構造、
すなわち 用途特化型インデクシング を使う方が圧倒的に速くなります。
★ 先ほど言っていた Fluentd を用いたログ解析システム は ログ解析用にチューニングしたものと言えるでしょうか。
用途特化型インデクシングの使用例: 全文検索エンジン
全文検索エンジンでは、以下3点の要求をどう満たすか 考える必要があります。
- 大量のデータから検索したい
- 高速に検索したい
- 「いい感じ」の文書を上位に持ってきたい
特に難しいのが 「いい感じ」を持ってくるところ。
★ ここでいう「いい感じ」とは、関連度の高いキーワード とかでしょうか。
コンテキストによって「いい感じ」は変わってくるので皆さんが考える「いい感じ」を想像して読みすすめてください。
RDBMS では要件を満たせない
RDBMS は特定のカラムでしか並び替えることができません。
例えば、作成日時で並べ替えるとか、名前のアルファベット順で並び替えるとかですね。
はてな社では、「いい感じ」の文章を上位に持ってくるために
スコアリング処理 を使用しているそうです。
しかし、スコアリング処理には、文章が持つさまざまな情報を複合的に利用する必要があります。
これは特定のカラムでしか並び替えできない RDBMS が苦手する分野です。
よって、ここで 用途特化型インデクシング が必要となります。
★ いろんな人が投稿した記事(文章)を単語レベルに分割して
保存とかしているんでしょうか?
とにかく、文章全文が保存されたデータソースから検索するのではなくて、
より検索しやすい形に整形されたデータソースに対して
検索をかけることが大事ということが分かってもらえれば幸いです。
はてな社では、スコアリングしやすいデータ構造に変換してやる処理(検索インデックス)を
自前で作成しています。(≒ 全文検索エンジンを自作)
すなわち、用途特化型インデクシングを作成し、全文検索しているわけですね。
理論と実践
全文検索システムは、RDBMS の JOIN を使って実現することもできるでしょう。(多分)
一方で、「RDBMS で JOIN を使わない」というのはよく聞く話です。
僕もコードレビューで、クエリ高速化のために JOIN を使わないように言われたことがありますし、
その考え方は理解できます。
しかし、それはRDS研究者からすれば「RDBMS で JOIN を使わないなんて、
RDS を否定しながら RDS を使うようなもの」と言われてしまいます。
ここで大事なのは、
「RDBMS で JOIN を使わない」というノウハウは 『実践』的にはすごく有益なノウハウであること。
しかし、JOIN句を使えば、全文検索システムを作ることができるし、
他の様々な場面においても JOIN句を使用することで解決できる問題はたくさんあります。
こっちは 『理論』 の話。
理論側では、JOIN句を使わないのは、バッドノウハウです。
何が言いたいかというと、
大規模な Webアプリケーション を運用・開発しようとすると、
実践も理論も両方やっていかないといけない ということです。
直面した課題に対して、ある側面ではバッドノウハウであっても、
他の面から見たときにグッドノウハウであることがあります。
我々エンジニアに求められるのは、実践も理論も両方をバランス良く使う力です。