CockroachDBをマスターする:眠れる夜を約束する「しぶとい」SQLデータベース

Database tutorial - IT technology blog
Database tutorial - IT technology blog

午前2時のアラーム:単一障害点(Single Point of Failure)という悪夢

データベースのクラッシュで叩き起こされたことがある人なら、システム復旧を待つ時のあの無力感をご存知でしょう。かつて私は、メインサーバーのハードウェア故障後、PostgreSQLのスタンバイノードをプライマリに昇格させるためだけに、貴重な20分間を費やしたことがあります。その20分間、5xxエラー率は急上昇し、上司からは絶え間なくメッセージが届き、私は震える手で手動設定のコマンドを打ち込んでいました。

MySQLやPostgreSQLは、極めて高い信頼性を誇る長年の標準です。しかし、インフラレベルでのスケーリングや自己修復(Self-healing)が必要な場合、それらはしばしばボトルネックとなります。マスター・スレーブ構成や手動のシャーディング(Sharding)の設定は非常に複雑で、ミスが起こりやすいものです。そこで私が辿り着いたのが、CockroachDBでした。

その名の通り「ゴキブリ(Cockroach)」のように、CockroachDBは最も過酷な環境でも生き残るように設計されています。これは分散型SQLデータベースであり、PostgreSQLと同じプロトコルを使用しながらも、よりモダンなアーキテクチャを備えています。クラスター内のすべてのノードは対等です。1つのノードに障害が発生しても、アプリケーションのコードを1行も修正することなく、システムが自動的にタスクを再調整します。

LinuxへのCockroachDBインストール:迅速かつ標準的な手順

Dockerに移行する前に、まずはUbuntu 22.04などのLinuxディストリビューションで、OSとの対話方法をしっかりと把握しましょう。非常に重要な技術的注意点として、CockroachDBはマシン間の時刻のズレ(Clock skew)に非常に敏感です。サーバー間で時刻を同期するために、chronyntpがインストールされていることを確認してください。

公式バイナリをダウンロードし、システムディレクトリに配置します:

curl https://binaries.cockroachdb.com/cockroach-v23.1.10.linux-amd64.tgz | tar -xz
sudo cp -i cockroach-v23.1.10.linux-amd64/cockroach /usr/local/bin/

バージョンを確認して、インストールが成功したことを確認します:

cockroach version

ターミナルにバージョンの詳細が表示されれば、準備完了です。しかし、真の力が発揮されるのは、ノード同士を接続した時です。

3ノードクラスターの構成:アップタイム99.99%への処方箋

本番環境において、「3」は最小の数字です。CockroachDBはデータの管理にRaftコンセンサスアルゴリズムを使用します。3つのノードがあれば、1つのノード(システムの33%)が完全に失われても、データベースは正常に動作し続けます。ノードが2つしかない場合、1つがダウンすると残りの1つは「過半数の喪失」状態に陥り、データの整合性を守るためにクエリの受け付けを停止してしまいます。

3つのサーバーIPを 10.0.0.1, 10.0.0.2, 10.0.0.3 と仮定します。フローを素早くテストするために、--insecure フラグを使用します。注意:実際のデプロイでは、通信上のデータを保護するために必ずSSL証明書を使用してください。

最初のノードを起動します:

cockroach start \
--insecure \
--store=node1 \
--listen-addr=10.0.0.1:26257 \
--http-addr=10.0.0.1:8080 \
--join=10.0.0.1:26257,10.0.0.2:26257,10.0.0.3:26257 \
--background

ノード2と3で、それぞれのIPを使用して同じ操作を繰り返します。最後に、クラスターの初期化コマンドを実行します(いずれか1つのノードで1回だけ実行します):

cockroach init --insecure --host=10.0.0.1:26257

CockroachDBには「マスターノード」という概念はありません。クラスター内のどのIPをアプリケーションから参照しても、データが必要な場所に適切にルーティングされる方法をシステムが自動で判断します。最適化のために、SQL接続の負荷分散を行うHAProxyを前面に配置することをお勧めします。

実地試験:理論が「Kill -9」に直面する時

クラスターが安定したら、http://10.0.0.1:8080 から管理UIにアクセスしましょう。ここでは、QPS(Query Per Second)やP99レイテンシなどの重要な指標を確認できます。チャートを眺めるだけでなく、もっと「大胆な」ことを試してみましょう。

私は以前、毎秒500リクエストの強度でデータを書き込むスクリプトを実行している最中に、kill -9 を使って1つのノードのCockroachプロセスを強制終了させたことがあります。結果は非常に印象的でした。システムはデータ領域(Ranges)のリーダーを再選出するために約2〜3秒間停止しただけで、その後は何事もなかったかのように書き込みを再開しました。厳格なACID特性のおかげで、データは完全に一致していました。

Postgresを知っていれば、SQL操作は非常に馴染み深いものです:

cockroach sql --insecure --host=10.0.0.1:26257

CREATE DATABASE itfromzero_prod;
USE itfromzero_prod;
CREATE TABLE users (id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name STRING, created_at TIMESTAMP DEFAULT now());
INSERT INTO users (name) VALUES ('Engineer_A');
SELECT * FROM users;

TypeORM, Prisma, SQLAlchemy などの主要なORMのほとんどは、CockroachDBとスムーズに接続できます。通常のSQLプログラミングの考え方を変える必要はほとんどありません。

結びに:CockroachDBは万能薬か?

率直に言って、CockroachDBが常に最良の選択肢であるとは限りません。ネットワークを介した合意形成メカニズムのため、NVMeドライブ上で単独で動作するPostgreSQLと比較すると、書き込みレイテンシ(Write Latency)は数ミリ秒高くなります。単一ノードで極めて高速な書き込み速度が必要なアプリケーションの場合は、慎重に検討してください。

しかし、データセンター全体に障害が発生してもシステムがダウンしないことを優先するのであれば、CockroachDBは救世主となります。サーバーがダウンしてから慌てて高可用性(High Availability)の解決策を探すのではなく、最初から強固な基盤を築きましょう。

Share: