老朽化したHBaseのデータ処理基盤をTiDBに移行
渡邉氏が所属するグループIT推進本部のデータプロダクトユニットは、「データの力で事業成長を加速させる」をミッションに掲げている組織横断での課題解決チームだ。ミッション遂行のために、チームではデータ処理基盤の開発・運用および生成AIの活用などに取り組んでいる。
サイバーエージェントでは、2010年にリリースした大規模データ処理基盤「Patriot」を運用してきたが老朽化。これにともない、現在データプロダクトユニットが刷新に取り組んでおり、HBaseで運用してきた部分を新たにTiDBに置き換えようとしている。
たとえば、Sparkなどによる分析結果の集計データをTiDBに書き込み、それらのデータに対して、さまざまなシステムからクエリなどの処理を行うことを目指す。他にも蓄積されたデータは、レコメンドや検索でも利用されるという。サイバーエージェントでは、プライベートクラウド「Cycloud」を運用しており、旧データ処理基盤はCycloudのVM上に構築されている。加えて、将来的にKubernetesクラスターに新しいシステムを載せていくことになるため、「今回刷新するデータ処理基盤もKubernetesクラスターに載せています」と渡邉氏。なるべく運用担当者の負荷を減らしていきたいという。
旧データ処理基盤で利用してきたHBaseは、データモデルがワイドカラム型のNoSQLデータベースの1つ。リージョンという単位でキーレンジとして論理的に分割しており、それらを管理するリージョンサーバーが存在している。なお、リージョンサーバーに対するリージョンの管理や割り当てを行うマスターがあり、ZooKeeperを利用してクラスター全体の障害検知やメタデータ管理を行う。
そして、クライアントはリージョンサーバーに接続してデータを読み込むため、これは「TiKV」とかなり似た構造になるとして「TiKVはHBaseを元に開発されており、似たアーキテクチャになっています」と渡邉氏は説明した。
しかし、明瞭な違いもいくつか存在する。たとえば、TiDBのデータモデルはリレーショナル型であることだ。加えてHBaseはトランザクションをサポートしないが、TiDBはサポートできる。一方、TiDBはトランザクションの分離レベルがスナップショットアイソレーション(Snapshot isolation)になっている点などには注意したいと渡邉氏。HBaseではセカンダリ・インデックスに対応せず、JOINによる検索もサポートしていないなどの留意点もある。他にも、レイテンシーにおいて差がでる場面もあるため、1桁ミリ秒程度が要求される場合は考慮すべきだとアドバイスを送った。
大規模なHBase環境が抱える課題
HBaseの課題は“運用負荷”だろう。特にHadoopエコシステムやZooKeeperへの依存性が高く、設定やチューニングが複雑になってしまいがちだ。渡邉氏は「そもそもHBaseを理解している人材も少なく、運用や開発の難易度は高いでしょう」と話す。また、リージョンサーバーが停止してしまうと、長時間のダウンタイムが発生してしまう点、ユーザーごとのデータ管理が難しく、アクセス制御やリソース使用量の計測、費用分配なども複雑になる点などを指摘する。
さらに大きな課題となるのが、“クラウドネイティブ環境への適用”だ。HBaseをKubernetes上で運用するハードルは高く、クラウド間やデータセンター間の移行も容易ではないため、システム環境の変化に柔軟に対応できない。加えて、HBaseではアプリケーション側でスキーマやトランザクション管理を意識する必要があるだけでなく、Javaクライアント以外の公式サポートが乏しいなど、開発効率も損なわれる。
そうした理由からもサイバーエージェントでは、移行先としてTiDBを選定。その理由の1つが「HBaseと同等の性能をもっていること」だ。TiDBでは、HBaseと同様に手動でシャーディングすることなくリード/ライト(Read/Write)の双方でスケールアウトできる。先述したようにレイテンシーの側面でHBaseに劣ってしまうケースもあるが、サイバーエージェントでの利用範囲内では十分な性能が発揮できているという。
2つ目の選定理由は、先に示したHBaseの課題を解決できる点だ。TiDBはクラウドネイティブ環境下で適用しやすく、Kubernetes向けのコントローラーである「TiDB Operator」を使うことでTiDBクラスターを容易にデプロイ可能だという。また、構築や監視、バックアップなどに必要なツールも取りそろえられており、運用者向けだけでなく、ユーザー向けダッシュボードも提供されているため、エラーやスロークエリの発生なども簡単に確認できる。
なお、選定における重要要素である耐障害性について、サイバーエージェントではクラスターのノードを意図的にダウンさせて検証。その結果として、多少サービスへの影響はあるものの、許容範囲に収まることが確認できたと渡邉氏。HBaseと比べて運用管理の負担も軽くなるだけでなく、ダウンタイムが短くなることもわかったという。
一方、TiKVに関してはQPSの低下が見られたものの、これはリージョンのリーダーがダウンした際に、次のリーダー選出までに10秒ほどかかることが原因だとする。TiDBに関しては、ノードダウンで接続しているクライアントはコネクションエラーとなるが、クライアントがリトライすれば問題ないとも話す。
「TiDBは、ユーザー管理機能が優れており、強力かつ柔軟なセキュリティとアクセス制御が可能です」と渡邉氏。特定ユーザーがリソースを使い過ぎることを防止するためのレート制限機能があり、ダッシュボードから各ステートメントがどれくらいリソースを消費しているかなども容易に把握できる。たとえば、1ヵ月あたりどれくらいリソースを使ったのか、そのデータをSQLで取得できるため、該当部門への費用請求も簡単だという。
TiDBはMySQL互換があるため、既存データベースがMySQLの場合、ユーザーの実装負荷も低く、学習コストをかけずに既存ツールを利用できる点もTiDBの評価ポイントとなる。複雑なクエリも実行でき、TiFlashで分析クエリも高速に処理可能だ。データの一貫性も担保されるため、アプリケーション側も単純化できるとして「アプリケーション開発者が本来の機能実装に専念できます」と渡邉氏は述べる。
TiDB移行後の性能と運用面での効果
HBaseからTiDBへの移行においては、MySQLからの移行のように公式ツールが用意されていない。サイバーエージェントでは大規模移行となったため、それを高速に行える仕組みも必要となった。そこで利用したのはSparkだ。Hadoop Inputフォーマットが利用でき、HBaseのスナップショットテーブルを読み込めるだけでなく、JDBCを用いてTiDBにデータを書き込める点が決め手になったという。
はじめにHBaseのデータを正規化してTiDBにテーブルを作り、HBaseとTiDBの双方に書き込む。このとき、HBaseとTiDBの双方で、書き込みが失敗した場合のリトライやエラーハンドリングを考慮しておく必要がある。その後、HBaseのテーブルスナップショットを作成すると、Sparkを利用して移行先のTiDBテーブルに書き込みを実行。二重書き込みを終了後、TiDBのみに書き込むように設定することで移行を完了できると渡邉氏。
なお、Sparkジョブの実装にはカスタムデータソースが用いられている。これは、JDBCデータソースでは「INSERT IGNORE」など特定のInsertオプションを使用できないためだ。また、HBaseからのデータ取得時にスキーマ変換を手動で行う必要があり、ここには時間と労力がかかってしまうという。実際にサイバーエージェントでは、こうした方法でダウンタイムなしに移行を完了している。もちろん、インクリメントやコンペアアンドスワップの操作など、データ間での依存関係が強い部分がある場合には、ダウンタイムなしで移行することが難しいケースもあるという。
現在、移行後の環境では、ノード障害などが発生するも問題なく自動復旧できており、障害対応にともなう運用負荷が上がることはないとする。また、マルチテント環境下でユーザー管理も問題なく実現されており、MySQL互換という特性からさまざまなツールが使えることも負担軽減につながっているという。
なお、スループットについては並列数を上げることで、HBaseと変わらない性能を発揮できており、レイテンシーは若干劣るが許容範囲に収まっているとした。
これについては、HBaseはクライアントから直接リージョンサーバーにアクセスするが、TiDBコンポーネントはステップ数が増加することが悪化の要因ではないかと渡邉氏。他にもバッチによる書き込みにおいて問題が発生した際には、RocksDBプラグインである「Titan」を適用することで解消できたとも説明する。
最後に渡邉氏は、HBaseからTiDBへの移行における留意点として、クエリエンジンの接続部分で問題が発生しやすかったり、バッチで書き込む際には追加実装やチューニングが必要だったりする点を挙げた。今後は、次世代のTiSparkの機能拡張で課題解決を進めていくだけでなく、ベクトル型データを格納したいとの要望も多いため、ベクトル探索機能の実装にも期待するとして講演を締めくくった。