TiDB移行PoCの一番のハードルは仕組みを理解してもらうことだった
DBのコストが高い
「インフラをAzureからAWSへ移行したことでシステムは安定するようになったがインフラコストが高い、、、特にDBがRDS ON SQL SERVERを使っており、高い、、、」
これは私が所属する部署内で何年も言われてきた課題ですが、実際OSSの安いデーターベースに移行をしようとしても他のプロジェクトが優先され、DB移行自体がプロジェクト化されることはなく長らく物事は進んでいませんでした。
ですが、ある時、システムの品質を高めてバグを減らそうという取り組みが社内で広がり数カ月ほど新規開発がストップするタイミングがありました。
「今がチャンスだ!」ということで、私は手を挙げて、データーベース移行に向けて技術調査や検証をすることになりました。
私が関わっていたシステム
私が関わっていたシステムの概要は以下の通りです。
-
B2B2Cの金融サービス
-
マルチテナント
-
インスタンス分離のテナント管理
-
サービス停止する場合はテナント側と調整が必要
-
細かいバグでも顧客によっては激しく追求される
-
テナント当たりのユーザー数は1万から40万、ものによっては1400万人ほど
ミッションクリティカルな金融ドメインで、尚且つToB向けのシステムなのでさらに高い品質を求められるものです。
最初に挙がった候補はAWSのAurora
最初に候補が挙がったデーターベースは、Auroraシリーズでした。
社内での利用事例も豊富で、インフラコストも比較的安い、リードレプリカも使える、AWSのエコシステム内で完結する、そういった理由から良さそうとの話が挙がりました。
一方でAuroraを使う場合、無停止でインスタンスサイズを弾力的に変更することはできません。
私が関わっていたシステムは停止時間を簡単に設けることができない関係で、なるべく余裕を持ったサイジングをしていたため、スケールを無停止で柔軟に変更できないRDBではコストの最適化が柔軟にできないという懸念が浮上しました。
そして、どのテナントも最初は「自社サービスで持っているユーザ数くらいは増えると思う」という予測を立てており、それに合わせてDBのサイジングをするものの、実際はそんなにユーザ数は伸びないといったケースをいくつも見てきました。
そのため、実際リリースしてみるとDBのリソースはかなり余っているが、顧客調整しないとDBのサイズダウンはできないため、リソースを余した状態で使い続けるという無駄な状態が続いていました。
そこで候補に挙がったNewSQL
そこで最近流行りのNewSQLはどうだろうかと候補に挙がりました。
NewSQLはACIDトランザクションをサポートしつつ、無停止で更新系・参照系を水平スケール可能な分散DBです。
NoSQLでは実現できなかった強整合性・可用性・スケーラビリティを提供するDBジャンルとして近年注目されているジャンルですね。
代表的なサービスは、Google Spanner・CockroachDB・YugabyteDB・TiDB・AuroraDSQL(2024~2025年当時はGAしていなかった)などです。
PoCを実施していた2024~2025年当時、NewSQLはかなり盛り上がりを見せており、日系企業ではPayPay・Mercari・DMM・レバテック・東京ガス・カプコン・LINE Yahooなどの企業がTiDBを検証・導入しているという情報が多数上がっていました。
元祖NewSQLのSpannerはベンダー違いで見送り
元祖NewSQLであるGoogle Spannerについては、TrueTime APIというグローバルクロックの仕組みが他NewSQLと比べてかなり洗練されているという情報は得ていました。
ただ、インフラをAWSで管理していたことから、導入時のハードルが高く、複数クラウドベンダーを使うことによる管理の複雑化もあるだろうとして、一旦見送ろうという判断になりました。
また導入先のシステムは日本国内での運用をしているため、グローバルクロックの仕組みがそこまで洗練されていなくてもそこまで問題にならないだろうということも理由としてありました。
YugabyteDB/CockroachDBは日本法人・リージョンが無かったため見送り
YugabyteDB/CockroachDBについては当時日本法人がなかったこと、日本リージョンでマネージドサービスが提供されていなかったことから見送りとなりました。
また日系企業で利用実績がほぼ皆無という状況だったため、PDM・部長陣の承認を得ることが難しいということも見送らざるを得なかった理由です。
Cockroach DBについては名前がキショすぎるというのも個人的な見送り理由としてありました。
Cockroach DBについて調べると、Gが大量に出てくるという状況も耐え難いもので、命名した人の神経を疑いたくなる気持ちになりました(笑)。
マジで名前変えてほしいなと思ってます。
AWSのDSQLはGAしておらず見送り
DB移行を検討していたタイミングでDSQLが発表されましたが、GAされていないことや外部キー制約をサポートしていなかったことから、我々のシステムで使うには時期尚早だとして見送りました。
またAWSも「既存システムをDSQLに置き換えるのではなく、新しいシステムを作るときにDSQLが使えないか検討してみてね」というユースケースを提示していたため、「まぁ公式が移行を推奨していないのであれば、検討する必要もあまりないな」という感じでもありました。
TiDBが有力候補に
そこでTiDBはどうだろうかとざっくり調べてみると、なんだか良さそうだという話になりました。
-
日系企業(金融サービス含む)での豊富な利用実績
-
サポート企業(PingCap)が日本法人を持っており、日本語で技術サポートを受けることが可能
-
DBユーザ単位での柔軟なリソース制御機能
-
ノンブロッキングなオンラインDDL機能
-
無停止でのDBバージョンアップが可能
-
無停止でのスケールアップ・ダウン・アウト・インが可能
-
AWS上で動くマネージドサービスの提供もある
-
インデックス断片化のメンテナンスフリー(ストレージ上でLSM Treeという仕組みを利用しているため)
-
サブコンポーネントとして列指向DB(TiFlash)を簡単に導入可能(ALTER TABLEするだけ)
-
高いMySQL互換性(プロシージャなど一部機能は使えない)
特にマルチテナントな決済サービスという特性を持つ我々のサービスにとって、柔軟なリソース制御機能があること、無停止でスケーリングできることはかなりの魅力的に映りました。
一方でPayPay社が出している記事で、「TiDBはスケーラビリティに優れるが多くのノード数が必要になるためコスト最適化が難しい。カリカリにチューニングしたRDBに比べるとインフラコストがかかる」といった話も見かけていました。
DB移行PoCのスタート
魅力的な特徴があるTiDBですが、本当にこれでコスト削減ができるのかという点は疑問が残るままだったので、実際に動かしてみて検証をしてみようと、DB移行PoCがスタートしました。
またいざTiDBがダメだったとしてもバックアッププランとして同様にMySQL互換性があるAuroraMySQLも検証することとしました。
PoCの計画
限られた期間・人数(ほぼ自分一人)でPoCを進める必要があったため、重要なところから段階的に検証していこうとして以下の計画を立てました。
-
コアドメインの処理に絞った検証
-
小規模・中規模・大規模テナントのデータ量での検証
我々のシステムではバッチ処理の中で多数のプロシージャを使っており、すべての機能を改修した上でTiDBを検証することはPoC期間中に無理そうだったので、コアドメインである処理に焦点を絞ってPoCを進めていくこととなりました。
動作検証のための改修
といっても動作検証のためにした改修はあまり多くありませんでした。
コアドメインの処理はほぼORM(jOOQ)を通していたため、基本的にはJDBCコネクタをMySQLのものに変えることで動作しました。
ただ、jOOQ ではSQL Serverのロック取得の構文をサポートしておらず、raw sqlで実装していた部分があったため、その部分については直すこととなりました。
最初は信じられないほど遅かった
ところがどっこい、動かしてみると決済の処理が数秒かかりSLOを満たさないことがわかりました。
これでは使い物になりません。
そこでスロークエリーレポートを見てみると、決済処理前にユーザ情報を取得するクエリがWaitしていることがわかりました。
もう少し踏み込んで見てみると、特にJOINしているレコード数が少ないマスターテーブルがボトルネックとなっていることがわかりました。
これらの情報をもとに色々調べてみると、TiDBでは排他ロックしか利用できないこと、ロック対象が外部キー制約を貼っている場合は親側も排他ロックしてしまうことがわかりました。
我々のケースでは親側のマスターテーブルが少数のレコードしかないため、そこのロック取得待ちとなりスループットが低下しているということでした。
ただここで貼っていた外部キー制約はよくよく考えてみると貼らなくても良かったのではというもので、概念上は孫・子・親という関係になっているが、テーブル上では孫と親で直接外部キー制約を貼っている状態でした。
そのため不要な外部キー制約として剥がして、再試験することで無事SLOを満たす結果が得られました。
同様にAuroraMySQLでも試験を実施しましたが、シングルノードのDBであり分散DBと異なり無駄なネットワークオーバーヘッドがないことから、10~50ミリ秒単位でTiDBよりレイテンシが速いという結果が得られました。
コスト試算
一通り試験結果が得られたため、コスト試算をすることにしました。
AuroraMySQLのコスト試算は非常にシンプルに出せました。
元々RDSのSQL Serverを使っていたため、同様のサイズのインスタンス費用を調べるだけでいくらかかるかを算出することができました。
問題はTiDBです。
TiDBではリソース使用量(ディスクI/O)を抽象化した単位としてRequest Unitという指標があります。
ですが、このリソース使用量が曲者で、ワークロードやクラスター構成によってそのクラスターで消費できる最大のRequest Unitが変わるため、 クラスターの最大RU / 1テナントあたりのRUといった形で簡単にテナント収容数を出すことができません。
これは困った、、、となりましたが、PingCapのSAさんと相談して、TiDBのCPUをフルで使い切るように負荷をかけてその時点のRU使用量をクラスターのキャパシティとしてコスト試算しようということになりました。
その結果、RDS SQL Serverが高すぎるということもありますが、TiDBにテナントを詰め込んで統合管理することで40%程度はインフラコストが下げられそうだということがわかりました。
またAuroraMySQLについてもマルチAZ運用した場合はTiDBと同程度のコストがかかりそうということがわかりましたので、単純な試算ではどちらもコストメリットは得られそうだとの結果になりました。
運用面についても調査
コスト試算をする傍らでRDS(SQL Server)でやれていた運用がTiDBでも可能なのかということも調査することになりました。
大方問題なさそうでしたが、一部は乗り越えるべき壁がありました。
1つはTiDBコンソールの監査ログの保持期間が90日と短いという問題です。
我々のサービスは不正アクセス禁止法のルールに則り2〜3年は監査ログを保持していましたので、これについてPingCap社と相談したところ、「監査ログの量はたかがしれているので保持期間を延長するよ」として調整してもらいました。
もう一つは1つのTiDBクラスターで複数テナントのDBを管理することになるが、TiDBではクラスターレベルのリソースアラートしか提供されていないということでした。
元々我々のサービスはテナントごとにDBインスタンスを立ててそれぞれリソースモニタリングしていたので、そのモニタリングができなくなってしまうというわけですね。
これについては、TiDB CloudでPromethausエンドポイントが提供されているため、RUの消費量を定期的に取得して、一定時間内でテナントごとに作成したDBユーザごとに設定したRU上限値を超えていないかをモニタリングする仕組みを構築することで事なきを得ました。
コストメリット・可用性・スケーラビリティからTiDBが良さそうだという結果に
この検証の結果、私の中ではTiDBいいじゃん!という結論にいたりました。
他のエンジニアたちにも結果を伝えると良いリアクションが得られました。
「TiDBいいね!スケーラブルで無停止でスケーリングできたり、テナントごとにリソース制御できるじゃん!」
「テナントごとのインスタンス分離から共有リソースでの管理になって、よりマルチテナントっぽくなるね!」
めでたし、めだたし、、、、
とはなりませんでした。
さぁ検証結果報告だ!と思ったら、PDM・部長陣は不安そうな顔をしている
さぁ、PDMや部長陣に報告してTiDB移行で決まりだ!と思って話を軽く前出ししてみたら、エンジニアほど嬉しそうな顔をしていませんでした。
正直びっくりしました。
「今年かなり波が来ているNewSQLが検証の結果、我々のサービスでもフィットしそうだということがわかったんだよ〜?」
「CAP定理を乗り越える人類の英知が詰まった仕組みが商用利用可能なラインまで来てるんだよ!?」
「デフォルトで冗長化されているから、1ノード死んでもサービス止まらないんだよ!?金融サービスにぴったりでしょ!?」
そう思っていましたが、私とPDM・部長陣との温度差はかなりありました。
馴染みのないものに対する漠然とした不安
色々話を効いてみると、「そもそもTiDBって名前をよく聞かない」「DB行こうってリスクでかいし、有名なDB使った方が安心」「新しい仕組みを我々で運用できるの?」「導入顧客に説明できるの?」といった様々な不安な声が聞こえてきました。
要は「馴染みのないものに対する漠然とした不安」というものが大きかったように感じました。
ノリでAuroraになりそうだったので待ったをかけた
散々検証してきて、色々情報整理して、その結果TiDBに良さそうだねぇと思っていたのに、漠然とした不安が立ち込めておりノリでAuroraになりそうだったので、「一旦落ち着きませんか?」という提案をしました。
確かにAuroraはいいDBですが、漠然とした不安でAuroraにするという消極的な技術選定は長い目で見たときの競争優位性を失う懸念があったり、消極的な技術選定が組織に根付くことの長期的なリスクもあると感じました。
そこで「AuroraもTiDBもMySQL互換DBであり、どちらもコスト削減自体はできるのでDB移行プロジェクト自体はスタートしませんか?」「その中で本当に適したものを3ヶ月後に最終決定しませんか?」という提案をし、アプリ改修やさらなる性能試験をしつつ、その傍らで時間をかけてエンジニア以外にも教育活動をして全員の技術理解度を上げて冷静に技術選定をできるように話を持っていきました。
草の根での教育活動
Auroraについてはみんなよく知っていたのでそもそもNewSQLのコンセプトは何なのか、どういった背景で誕生したのかといったことから皆に伝えていくことにしました。
振り返ってみるとかれこれ10回以上は色んな場所で色んな角度で説明をしていた気がします。
具体的には以下のトピックについて何回も何回も説明をしました。
-
更新系の水平スケールというRDBで解決できない課題とNewSQL誕生
-
柔軟なリソースグループ機能による安全なマルチテナント運用
-
無停止でのスケーリングによるコスト最適化、安全性の担保
-
TiDBのアーキテクチャ(計算ノードとストレージノードの分離)
-
TiDBでクエリが実行される際の内部のフロー
-
NewSQL利用時のトレードオフ(分散システムになるのでスループットは高いがレイテンシが増える)
またちょうどTiDBの書籍も出版されたので至るところでみんなに読んでみて!とオススメしたりもしていました。
さらにPingCap社から「20万くらいするワークショップに無料招待するけど来ます?」という提案をいただいたので、他のエンジニアも参加してもらい、内部構造を深く理解してもらうということもしました。
徐々にみんな慣れてきた
こういった活動を繰り返してきた結果、徐々にみんなの理解が追いついてきた気がしました。
特にPDMの一部の人が紹介したTiDBの本を買ってくれたり、自分に「MTGをセットして話を聞かせてくれない?」かと言ってくれたりと、自発的に動き始めたあたりから、エンジニア以外のメンバーの不安が消えつつ理解も深まってきていそうだという気がしました。
協議の結果、、、、TiDBを利用することに決定!
そろそろ頃合いだということで、部長陣・経営層にPoCの結果を説明し、一つ一つ検証した結果やいつ頃投資対効果が得られるのかといった話までして、最終的にTiDBを利用することになりました。
「PayPayやどこそこも使っているよ」という他社事例も説明に盛り込んでいたので、そこで安心感を持ってくれた人もいたそうです(それはそれで消極的だなぁ、、という気もしますが)。
おわりに: TiDB移行PoCの一番のハードルは仕組みを非エンジニアメンバーに理解してもらうことだった
振り返ってみるとDB移行のPoCで一番大変だったのは、非エンジニア層に対して新しいコンセプトの技術をちゃんと理解してもらうことだったなと思いました。
「散々検証したのにその結果よくわからんからダメとなるの理不尽すぎないか、、、」と途中、心が折れそうになりましたが、諦めずに仕組みの説明をしまくって皆に理解してもらった上で技術選定ができたのは良かったと思います。
リスクが高い技術選定に対して、消極的にならずに検証結果と仕組みの理解、将来のシステムの適合性などを持って合理的に判断できたのではないかと思います。
このプロジェクトを通して、「ファクトに基づいた合理的な意思決定をするためにはまず未知の対象を未知でなくす」といった努力が必要なのかもなという教訓が得られました。
また、非エンジニアのメンバーが不安に思ったときにサボらずに説明責任を果たすことができたのは、エンジニアとしてちゃんと仕事と向き合えた気がして、1つ達成感が得られました。
おしまい