課題の正体を見極め、プロジェクト開始
LINEヤフーでは、Cassandraを406ノードの物理マシンから成る巨大なクラスタで運用していたが、レプリケーションやコンパクションの都合で、マシンを多めに用意しておく必要があった。その結果、年間1億数千万円もかかっていた。
すぐに追加のサーバーを確保することができず、データが急増してもすぐにスケールアウトできない課題もあった。コストを下げたい、スケーラビリティを確保したい、運用負荷を下げたいといったことが要求となった。もちろん、データを失うわけにはいかないので、データの永続性も欠かせない要求だ。
坂本氏は、「要求だけでは何も始まらない。要求を具体的な要件の形にしていかなければならない」と語る。そして要求を要件にしていく上で大切なことは、妥協できることと妥協できないことを明確にすることだと強調する。
今回のプロジェクトではCassandraを完全に置き換えることは最初からあきらめた。坂本氏は、24時間以内のデータは従来通り内製のインメモリデータベースで処理し、2週間以内のデータはCassandra、2週間以降のデータを新しいストレージに保存する方針を立てた。一方で、今後の成長も考えるとスケーラビリティは欠かせない。もちろん、データの永続性も必要だ。運用負荷の軽減も妥協できないと考えたという。
以上の判断から、具体的な要件を作成した。一部を具体的に挙げると、クエリのレイテンシはCassandraの1.5倍程度なら許容した。1営業日で必要な分をスケールアウトできるスケーラビリティを確保。そして、10億種類のMetricsを保持できて、3倍の成長に耐えられるキャパシティを求めることになった。
プロジェクトが始まった後は、Design Docを作成し、それをもとにPoC(Proof of Concept)を開発。PoCを本番環境で試し始める。ここではそれぞれの段階ですぐに結果を出し、フィードバックを得て、次の段階につなげていくこと。これを、速いサイクルで繰り返すことが最も重要だとのことだ。こうすることのメリットとして坂本氏は「早く失敗できる」という点を挙げる。「2年かけていろいろ作ってきたけど、結局何も完成しませんでした」という事態に至る可能性を下げられる。
そして坂本氏は、最初から完璧を目指す必要はないと強調する。完璧でなくても良いから、サイクルをとにかく回すこと、繰り返すことが大切だ。また、途中で戻っても良いということも坂本氏は強調した。
議論と合意形成に使う文書には何を書くのか?
Design Docは「チームや関係者との議論や合意形成に必要なことを書くもの」と坂本氏は説明する。早期の方針やアイデア、実装方針、懸念事項をまとめた初期のドキュメントということになる。
Design Docには、以下のようなことを書く。今回のプロジェクトでは、オブジェクトストレージを採用したいが、オブジェクトストレージは時系列データベース専用ではないので、データ構造を考える必要がある。複数のMetricsを1つにまとめて管理しなければならないが、どの位置に目的のSampleがあるのかが分かりにくくなる。そこで、転置インデックスの導入を考えた。任意のIDに対応するSampleが、ファイル上のどの位置にあるのかをバイト位置で記録するマッピングテーブルだ。
複数のMetricsを1つにまとめると、Sampleファイルが大きくなってしまう。そこで、オブジェクトの一部をバイト範囲で指定し、その部分だけをダウンロード可能にするByte-Range Requestという機能を使うことにした。
Sampleファイルが大きくなると、転置インデックスも大きくなってしまい、メモリを消費する。そこで、シャーディングでSampleファイルを分割することを考えた。さらに、オブジェクトストレージが低速であるため、クエリAPIにメモリベース、ディスクベース両方のキャッシュを組み込み、ダウンロードの回数を減らそうと考えた。
ここまで決まったら、1つのバケットにどのくらいのオブジェクトが入るのか、データサイズはどれくらいになるのかといったことを詳細に計算する。さらに、APIやルーティングの構成などを図にしたハイレベルデザインをDesign Docに記述し、これをもとに技術的懸念を整理しながら議論する。
関係者間で合意に至ったら、PoCに移行する。この段階では1週間以内で作れるようなごく簡単なスクリプトで作成する。実装と検証の際には、ダークローンチという手法を利用した。本番環境のAPIのやり取りを、開発中のシステムにもミラーリングするという手法だ。今回はCassandraのやり取りをオブジェクトストレージにもミラーリングした。
こうすることで、オブジェクトストレージの性能だけでなく、返す結果がCassandraと一致するのかということを本番のデータで検証できる。本番環境のユーザーに影響を与えることはない。坂本氏は「ユーザーによって投げるクエリはまったく異なる。本番相当のクエリ、本番相当のデータ量で検証しないとあまり意味がない」と語る。
今回はさらに「Feature Toggle」という仕組みも導入した。設定ファイルのブーリアン値を「false」にするだけで、デプロイなしで機能を一瞬で止めることができる。何か問題が発生しても一瞬でロールバックできるようにしておくわけだ。