CockroachDBレビュー:存続のために構築されたスケールアウトSQLデータベース

ごく最近まで、データベースを購入するときは、スケーラビリティか一貫性かを選択する必要がありました。MySQLなどのSQLデータベースは強力な一貫性を保証しますが、水平方向に適切に拡張することはできません。(スケーラビリティのための手動シャーディングは、誰もが楽しむことではありません。)MongoDBなどのNoSQLデータベースは美しくスケーリングしますが、結果整合性しか提供しません。(「十分長く待つと、正しい答えを読むことができます」-これは金融取引を行う方法ではありません。)

2017年2月にリリースされたGoogleCompute Engine(GCE)で実行されるフルマネージドリレーショナルデータベースサービスであるGoogle Cloud Spannerは、SQL互換性、リレーショナルスキーマ、ACIDトランザクション、強力な外部整合性を維持しながら、NoSQLデータベースのスケーラビリティを備えています。Spannerは、ノード間のコンセンサスに到達するためにPaxosアルゴリズムを使用する、シャーディングされ、グローバルに分散され、複製されたリレーショナルデータベースです。

Spannerの代替案の1つであり、このレビューの主題は、Spannerに精通した元Google社員によって開発されたオープンソースの水平方向にスケーラブルな分散SQLデータベースであるCockroachDBです。CockroachDBは、データストレージシステムの設計のためにGoogleのSpannerから借用しており、ノード間のコンセンサスに到達するためにRaftアルゴリズムを使用しています。

Cloud Spannerと同様に、CockroachDBは、RocksDB上のCockroachDBの場合のように、トランザクションで一貫性のあるKey-Valueストアの上に構築された分散SQLデータベースです。CockroachDBの主な設計目標は、ACIDトランザクションのサポート、水平方向のスケーラビリティ、および(とりわけ)存続可能性であるため、この名前が付けられています。

CockroachDBは、ディスク、マシン、ラック、さらにはデータセンターの障害に耐えるように設計されており、遅延の中断を最小限に抑え、手動による介入は必要ありません。もちろん、これを実現するには、複数のディスク、マシン、ラック、およびデータセンターを使用して、CockroachDBの対称ノードの多くのインスタンスのクラスターを実行する必要があります。

Googleデータセンターで時刻同期に使用できるTrueTimeAPIを使用するCloudSpannerとは異なり、CockroachDBは、ノードとデータセンター間で時刻を正確に同期するために原子時計とGPS衛星時計の存在を期待できません。これには多くの意味があります。まず、Google TrueTimeは、7ミリ秒のクラスター内のノード間のクロックオフセットの上限を示します。これは十分に小さいため、Spannerノードは書き込み後7ミリ秒待機してから、トランザクションがコミットされたことを報告し、外部の整合性を保証します。

TrueTimeまたは同様の機能がない場合、CockroachDBはNTPにフォールバックする必要があります。これにより、100ミリ秒から250ミリ秒の間のクロック同期の上限が与えられます。その大きな時間枠を考えると、CockroachDBは書き込み後に待機しません。代わりに、読み取りの前に待機することがあります。基本的に、トランザクションの開始よりも大きいタイムスタンプを持つ値を読み取る場合は、一貫性を保証するためにトランザクションを再開します。

CockroachDBクラスター内のすべてのノードに、GPSまたは原子時計から取得できるクロックオフセットの小さな上限がある場合、これは主要なパブリッククラウドで利用できるようになったばかりであり、--linearizable フラグを使用して実行するのが理にかなっています。これにより、Spannerと同様に、コミットが成功する前に最大クロックオフセットを待機します。

CockroachDBのしくみ

各CockroachDBノードは、次の5つのレイヤーで構成されています。

  • クライアントのSQLクエリをKey-Value操作に変換するSQL
  • 複数のKey-Valueエントリへのアトミックな変更を可能にするトランザクション
  • 複製されたKey-Value範囲を単一のエンティティとして提示する配布
  • レプリケーション。多くのノード間でKey-Value範囲を一貫して同期的にレプリケートし、リースを介した一貫した読み取りを可能にします。
  • ディスク上のKey-Valueデータの書き込みと読み取りを行うストレージ

SQLレイヤーは、Yaccファイルに対するクエリを解析し、それらを抽象構文ツリーに変換します。CockroachDBは、抽象構文ツリーから、Key-Valueコードを含むプランノードのツリーを生成します。次に、プランノードが実行され、トランザクションレイヤーと通信します。

トランザクションレイヤーは、クロスレンジトランザクションとクロステーブルトランザクションを含むクラスター全体で2フェーズコミットを使用してACIDトランザクションセマンティクスを実装し、単一のステートメントをトランザクションとして扱います(自動コミットモードとも呼ばれます)。2フェーズコミットは、トランザクションレコードと書き込みインテントを投稿し、読み取り操作を実行し、検出された書き込みインテントをトランザクションの競合として処理することで実行されます。

ディストリビューションレイヤーは、同じノード上のトランザクションレイヤーからリクエストを受信します。次に、どのノードがリクエストを受信する必要があるかを識別し、適切なノードのレプリケーションレイヤーにリクエストを送信します。

レプリケーションレイヤーはノード間でデータをコピーし、Raftコンセンサスアルゴリズムを実装することでこれらのコピー間の整合性を確保します。レプリケーションゾーンを使用して、クラスター、データベース、およびテーブルレベルでレプリケーション係数を制御できます。コンセンサスアルゴリズムは書き込みにのみ使用され、レプリカのクォーラムが範囲への変更に同意してから、それらの変更がコミットされる必要があります。

ストレージレイヤーは、RocksDBを使用してデータをキーと値のペアとしてディスクに保存します。CockroachDBは、同時要求を処理し、一貫性を保証するために、マルチバージョン同時実行制御(MVCC)に大きく依存しています。この作業の多くは、ハイブリッド論理クロック(HLC)タイムスタンプを使用して実行されます。

Spannerと同様に、CockroachDBはタイムトラベルクエリをサポートしています(MVCCによって有効化されています)。これらは、デフォルトで毎日行われる最新のデータベースガベージコレクションまでさかのぼることができます。

CockroachDBのインストールと使用

CockroachDBは、少なくとも開発とテストのために、Mac、Linux、およびWindowsオペレーティングシステムで実行されます。Production Cockroachデータベースは通常、Linux VMまたはオーケストレーションされたコンテナーで実行され、多くの場合、複数のデータセンターのパブリッククラウドでホストされます。CockroachDBのWindowsバイナリはまだベータ段階であり、本番環境には推奨されていません。Appleはサーバーハードウェアを製造していません。

コックローチラボ

上のスクリーンショットでわかるように、MacにCockroachDBをインストールするための4つのオプションがあります。私は4つの中でおそらく最も簡単なものとしてHomebrewを選びました。

ちなみに、Cockroach Labsは、DockerでCockroachDBなどのステートフルアプリケーションを実行するのは難しいため、本番環境へのデプロイにはお勧めできません。代わりに、KubernetesやDockerSwarmなどのオーケストレーションツールを使用してクラスターを実行するという警告をサイトに投稿しています。次のセクションでは、コンテナのオーケストレーションオプションについて説明します。

Macへのインストールはbrew install cockroach上記のように簡単です。私の場合、Homebrewの自動更新には、実際のCockroachDBのインストール(数秒しかかからなかった)よりもはるかに長い時間がかかりました(お茶を淹れるのに十分な時間)。

CockroachDBをインストールすると、ローカルクラスターを起動するのはかなり簡単cockroach certですが、クラスターを安全にしたい場合は、コマンドを使用してセキュリティ証明書を生成する追加の手順があります。クラスターを実行すると(cockroach startノードごとに1回コマンドを使用し、後続のノードを最初のノードのクラスターに参加するように設定)、ブラウザーを使用して任意のノードのWeb管理ページに接続し、組み込みcockroach sqlクライアントを使用してSQLを送信できます。任意のノードへのクエリ。ほとんどのブラウザは、CockroachDBで生成された証明書を持つサイトについて文句を言いますが、その悲惨な警告をクリックして、サイトに進むことができるはずです。

推奨されるCockroachDBの本番設定は、開発インスタンスとテストインスタンス用に設定されたデフォルトとは異なります。必要に応じて、1ノードクラスターで開発できます。本番環境では、少なくとも3つのノードが必要であり、各ノードを別々のマシン、VM、またはコンテナーで実行し、各インスタンスに追加のキャッシュとSQLメモリを提供する必要があります。デフォルト設定は、キャッシュとSQLメモリでそれぞれ128MBです。推奨される実稼働設定は、RAMの25%ごとに与えることです。

cockroach start --cache=25% --max-sql-memory=25%

実行するノードが多いほど、復元力は向上します。ノードが大きく高速であるほど、パフォーマンスは向上します。1秒あたり2,000回の書き込みと1秒あたり10,000回の読み取りを提供するGoogleCloud Spannerノードとほぼ同等のパフォーマンスのノードが必要な場合は、8つのCPUと8GBのRAMを備えたGCEのn1-highcpu-8インスタンスのようなものが必要です。 、(回転するディスクではなく)ローカルSSDディスクを使用します。

ノードをさまざまなデータセンターに分散させるほど、データセンターレベルの障害に対する耐性を確保できます。ただし、コストがかかります。データセンター間のラウンドトリップレイテンシはデータベースのパフォーマンスに直接影響し、大陸間クラスターのパフォーマンスは、すべてのノードが地理的に近接しているクラスターよりも著しく劣ります。

Cockroach Labsは、AWS、Digital Ocean、GCE、およびAzureにデプロイするための詳細な手順を提供します。推奨される構成では、ネイティブマネージドロードバランシングサービスまたはHAProxyなどのオープンソースロードバランサーのいずれかのロードバランサーを使用します。

オーケストレーションにより、CockroachDBクラスターの運用オーバーヘッドをほとんどゼロにすることができます。Cockroach Labsは、KubernetesとDockerSwarmを使用して本番環境でこれを行う方法を文書化しています。GitHubのCockroachDB-CloudFormationリポジトリは、開発とテストのために単一のアベイラビリティーゾーンでAWSCloudFormationとKubernetesを使用する方法を示しています。これを本番環境に適合させるには、CloudFormationテンプレートを変更して複数のアベイラビリティーゾーンを使用する必要があります。

CockroachDBのプログラミングとテスト

CockroachDBはPostgreSQLワイヤープロトコルをサポートしているため、Postgresまたは少なくともPostgresのサブセットに対してプログラミングしているかのようにコードを記述します。このページには、最も一般的なサーバー側言語を含む、さまざまなプログラミング言語バインディングでテストされたドライバーが一覧表示されます。このページには、10のプログラミング言語と5つのORMのサンプルがリストされています。ドキュメント内のリストにいくつかの可能性のあるマイナーなバグを見つけましたが、コードを読んだときに大きな驚きはありませんでした。cockroach実行可能ファイルに組み込まれている対話型クライアントを使用してSQLを実行することもできます。

CockroachDBロードジェネレーター専用のリポジトリとパフォーマンステスト用のリポジトリがありますが、CockroachDBを他のデータベースと有意義な方法で比較しようとしている場合は特に、CockroachDBクラスターのベンチマークは簡単ではありません。1つの問題は、ノード間のネットワークがCockroachDBクラスターの律速段階になる可能性があることです。

考慮すべきもう1つの事実は、ほとんどの従来のSQLデータベースはデフォルトでSERIALIZABLE分離モードで実行されないということです。代わりに、より厳密でないモードを使用してパフォーマンスを向上させます。CockroachDBは、デフォルトでシリアル化可能な分離モードを使用します。さらに、まだ進行中のCockroachDBのSQL結合パフォーマンスをTPC-Cスイートでテストするのは少し不公平です。

それでも、CockroachDBの運用能力を簡単に確認できます。たとえば、データベースをスケールアップするには、多くのデータベースを停止して再起動する必要があります。特にオーケストレーションツールを使用している場合、CockroachDBにロード中のノードを追加するのは簡単です。たとえば、上のスクリーンショットは、Kubernetesクラスター内のノードを変更して表示するコマンドを示しています。下のスクリーンショットは、ノードが追加されたときに監視対象のクラスターを示しています。負荷生成ツールは、プロセス全体を通じて継続的に実行されました。

さらに印象的なデモンストレーションは、CockroachDBクラスター内の自動クロスクラウド移行を示しています。それを正義にするためには本当にビデオが必要です。ビデオはリンクされたブログ投稿でホストされています。

CockroachDB SQL 

CockroachDBのSQLは、データ操作に非標準の構文を使用するCloud SpannerのSQLとは異なり、多かれ少なかれ標準です。ただし、CockroachDBSQLにはまだ多くの機能がありません。

たとえば、V1.1には、V1.2で計画されているJSONサポートがありません。また、ロードマップにないXML解析もありません。V1.2で計画されている行レベルのカスケードがなく、ロードマップにないカーソルとトリガーがありません。地理空間インデックスは、将来ロードマップに追加される可能性のある「潜在的な」追加です。

特に、2016年のSQL結合の最初のCockroachDB実装は、意図的に単純化され、2次スケーリングを示したため、大規模なデータセットのクエリには使用できませんでした。協同組合の学生によって行われたV1.0のバージョンは、ハッシュ結合を実装し、多くの結合操作を線形にスケーリングしました。これにより、CockroachDBはSQLiteのレベルになりました。2018年のいつか、最近の資金調達を考えると、CockroachDBは、PostgreSQL結合のように拡張できる結合パフォーマンスと、クラスター全体に分散されたSQL結合処理を備えているはずです。