ひたすら繰り返すことが大きな成功への道
当然だが、実装当初から高い性能が出るわけではない。検証して、ボトルネックを測定して、それをもとに改善案を作成して、それを実装して、再び検証する。このサイクルを何回繰り返したか分からないくらい繰り返したと坂本氏は語る。
このときに頼りになるのは、プロセッサ時間やメモリなどの資源をどれくらい使っているのかを関数呼び出しごとに確認するプロファイリングと、リクエストなどのユーザーが指定した測定区間内で、どの処理にどれくらいの時間を使ったのかを確認するトレーシングだ。
今回、クエリの処理をプロファイリングとトレーシングで調べたところ、転置インデックスのダウンロードとデコードに時間がかかっていた。転置インデックスが最大で約20MBにまで膨らんでしまい、毎回ダウンロード、デコードしていると、プロセッサ時間をかなり消費するのだ。
そこで、転置インデックスのサイズを縮小するために「インデックスのインデックス」という新しいデータ構造を導入した。転置インデックスに対してさらにマッピングテーブルを作るというわけだ。これを作れば、転置インデックスの部分的なダウンロードとデコードが可能になる。
また、クエリを確認していると、何回も同じクエリが発生していることが分かった。そこで、転置インデックスのダウンロード、デコード、ターゲットのIDを検索までの処理を、丸ごとキャッシュできないかと考えた。こうすることで、Sampleのバイト位置がキャッシュから分かるようになり、転置インデックスの処理が丸ごと不要になった。
ほかにもDownload Bufferのチューニングや、並列処理数のチューニング、「Nginx」から「Envoy」への移行などいろいろ手を尽くしたが、すべて仮説を立てて実装し、結果を測定するサイクルをひたすら繰り返すことで成果を出してきた。その結果、プロセッサ使用率を90%から6%まで下げることができ、レイテンシの値もCassandraにかなり近づけることができたという。
今回のプロジェクトでは、年間約1億円弱のコストを削減できた。半年ほど経ったが、一度も障害は発生していない。10億種類のMetricsも保持しており、いつでも簡単にスケールアウトできる。Cassandraにも負けないレイテンシで検索できるので、もはやCassandraも要らないのではという声も出始めた。
今回坂本氏は、難易度が高く不確実性を伴う課題に挑戦するときに意識したいポイントを、実例を交えて説明した。まずは言語化。要求はみんな持っているはず。それをきちんと要件の形にして、成功を定義すること。次は、早くアウトプットして、早く結果を得て、それを高速に回して、計測と改善を繰り返すこと。坂本氏は「これをあきらめずにとにかく繰り返せば、絶対に上手くいく。計測と改善を、成功するまで根性で繰り返すことが大切だ」と語って公演を締めくくった。