YugabyteDBのアーキテクチャーをドキュメントから眺めてみる

# What's？

YugabyteDBのドキュメントから、アーキテクチャーに関するものを眺めていってざっくり把握してみたいと思います。

# 対象とするYugabyteDBのバージョン、ドキュメント

対象とするYugabyteDBのバージョンは現時点のLTSである2.20とします。

ドキュメントとしては、この配下のページをピックアップして見ていきます。

https://docs.yugabyte.com/v2.20/architecture/

## 対象ページ

このあたりかなと。

- https://docs.yugabyte.com/v2.20/architecture/design-goals/
- https://docs.yugabyte.com/v2.20/architecture/concepts/
  - https://docs.yugabyte.com/v2.20/architecture/concepts/universe/
  - https://docs.yugabyte.com/v2.20/architecture/concepts/yb-tserver/
  - https://docs.yugabyte.com/v2.20/architecture/concepts/yb-master/

必要に応じて、図も引用します。

# デザインゴール

まずはこちらから。

https://docs.yugabyte.com/v2.20/architecture/design-goals/

要約的に抜粋してみます。

- 一貫性（Consistency）
  - CAP定理とスプリットブレイン
    - YugabyteDBはCAP定理でいうCP
    - ネットワーク分断が発生した場合は、多くの書き込み可能なメンバーが残ったRAFTグループピアで新しいリーダーを選出する
      - リース（リーダーであることを示すロックのようなもの）のデフォルト値は2秒
  - 単一行の書き込みを線形化する
    - すべての操作がアトミックであり、リアルタイムで行った操作順と一致する順番で実行される
  - 複数行に対するACIDトランザクション
    - Serializable、Snapshot（Repeatable Read）、Read Committedの3つのトランザクション分離レベルをサポートする
    - YSQLのは3つすべてのトランザクション分離レベルをサポートし、デフォルトはSnapshot
    - YCQLは`BEGIN TRANSACTION`構文を使うことでSnapshotのみをサポート
- クエリー
  - YSQL
    - PostgreSQLのSQLと互換性のあるSQL API
    - join、分散トランザクション、外部キー制約などをサポート
    - PostgreSQLのネイティブクエリーレイヤーを再利用（PostgreSQLのソースk－度を使っている）
      - https://www.yugabyte.com/blog/why-we-built-yugabytedb-by-reusing-the-postgresql-query-layer/
      - https://github.com/yugabyte/yugabyte-db/tree/v2.20.4.0/src/postgres
  - YCQL
    - OLTPおよびHTAPに最適な準リレーショナルSQL API
    - 分散トランザクション、強い一貫性のあるセカンダリーインデックス、ネイティブなJSONカラムをサポート
- パフォーマンス
  - C++で実装
  - 以下のワークロード特性を考慮して設計
    - 高い書き込みスループット
    - クライアントに対する高い並行性
    - （ノードあたりのデータ総量に対する）高いデータ密度
    - ユースケースに応じて増え続けるイベントを処理する能力
- 地理的分散
  - ノードを以下のような配置でデプロイできる
    - 単一ゾーン
    - 複数のゾーン
    - 地理的にレプリケーションされた複数のリージョン
    - 複数のクラウド（パブリッククラウド、プライベートクラウドの両方を含む）
- クラウドネイティブアーキテクチャー
  - 市販のハードウェアで実行可能
  - Kubernetesに対応
  - Apache 2.0ライセンスのオープンソース

# ユニバース

キーコンセプトから「Universe」を見てみます。

https://docs.yugabyte.com/v2.20/architecture/concepts/universe/

ユニバース、と言われてもなんのことやらと思うのですが、YugabyteDBにおける分散データベースを構成するノードのグループ（仮想マシン、物理マシン、コンテナなど）を指しているようです。

> A YugabyteDB universe is a group of nodes (virtual machines, physical machines, or containers) that collectively function as a resilient and scalable distributed database.

こう書くとクラスターのことでは？と思いたくなりますが、ユニバースとクラスターという用語が同じような意味で使われていることはあるものの、必ずしも同じではないようです。

> Note that sometimes the terms universe and cluster are used interchangeably. However, the two are not always equivalent, as described in Universe vs. cluster.

ユニバースは以下の特徴を持つもののようです。

- データの管理単位
  - YSQLではRDBMSの「データベース」、YCQLではApache Cassandraの「キースペース」と同じ論理単位として扱われる
  - AZやリージョンへの配置要件、レプリケーション係数などの設定を見ながら、ユニバース内のノード間でシャーディング、レプリケーション、負荷分散を自動調整する
- コンポーネントサービス
  - ユニバースはYugabyteDBタブレットサーバー（YB-TServer）とYugabyteDBマスターサーバー（YB-Master）という2セットのサーバーで構成される
  - YB-TServerとYB-MasterのサーバーのセットはRaftをビルディングブロックとして2つの分散サービスを形成する
  - 各サービスの役割
    - YB-TServer
      - テーブルなどのユーザーデータのホスティング、すべてのクエリーの処理を担当
    - YB-Master
      - システムのメタデータの保持
      - テーブルの作成、変更、削除などのシステム全体の操作の調整
      - 負荷分散などのメンテナンス操作の開始

以下は、4ノードで構成されたユニバースの例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309669/fec8c8a4-d56c-5a49-9454-89a2b489f62f.png)

- ユニバースとクラスターの違い
  - ユニバースは1つのプライマリークラスターと0個以上のレプリカクラスターで構成される
  - プライマリークラスターの特徴
    - 読み書きの両方が可能
    - （プライマリー）クラスター内のノードのレプリケーションは同期的に実行される
    - Raftにおけるリーダーとフォロワーが含まれる
  - レプリカクラスターの特徴
    - Read Only
    - レプリカクラスターに送信された書き込みリクエストは、プライマリークラスターに自動的に再ルーティングされる
    - データはプライマリークラスターから非同期レプリケーションで取り込まれる
    - レプリカクラスターを地理的に近い場所に置くことで、地理的に分散された位置にあるクライアントの読み取りレイテンシを低減できる
    - レプリカクラスター内のノードはプライマリークラスターに対するRaftオブザーバーとして機能する

# YB-TServerサービス

キーコンセプトから「YB-TServerサービス」を見てみます。

https://docs.yugabyte.com/v2.20/architecture/concepts/yb-tserver/

以下に特徴を挙げておきます。

- YB-TServerサービスはタブレットサーバーとも呼ばれ、YugabyteDBクラスターに対するリクエストの入出力を扱う
- テーブルのデータはタブレットという単位に分割（シャーディング）される
- 各タブレットはレプリケーション係数に応じた1以上のタブレットピアで構成される
- 各YB-TServerは1つ以上のタブレットピアをホストする

以下は、ひとつのテーブルに16個のタブレットがあり、レプリケーション係数が3、ノードが4つのYugabyteDBユニバースの例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309669/5f4739d5-6ee7-2f4e-5853-32f680a19219.png)

この図において、異なるYB-TServerサービスでホストされている各タブレットに対応するタブレットピアはRaftグループを形成し、相互にレプリケーションを行います。

つまり、16タブレットあるのでRaftグループとしては16個、あるタブレットに対して3つのピア（peer 1～peer 3）があるという構成ですね。

これ以上の詳細はレプリケーションレイヤーに関するドキュメントを見ることになります。

https://docs.yugabyte.com/v2.20/architecture/docdb-replication/

なお、ストレージレイヤーはRocksDBを拡張したDocDBというデータストアで構成されているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309669/02ecfe0b-ab1f-fd76-82ea-3464b89d4eee.png)

https://docs.yugabyte.com/v2.20/architecture/layered-architecture/

https://docs.yugabyte.com/v2.20/architecture/docdb/persistence/

# YB-Masterサービス

最後は、キーコンセプトから「YB-Masterサービス」を見てみます。

https://docs.yugabyte.com/v2.20/architecture/concepts/yb-master/

YB-Masterサービスはテーブルやタブレットの場所、ユーザーやロールおよび関連付けられた権限などのシステムメタデータやレコードを保持するものです。  
また、負荷分散やレプリケーションしきれていない場合の再レプリケーションの開始といったバックグラウンド操作の調整、テーブルの作成、変更、削除などの管理操作の実行も行います。

こちらの図を見ると、各ノードのYB-Master間でRaftグループを構成し、YB-TServer群からYB-Masterのリーダーに対してハートビートを行うようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309669/515b444f-c0d8-762c-466c-0872fcba189c.png)

まとめると、YB-Masterサービスには以下の機能があります。

- ユニバース全体の管理操作の調整
  - ユーザーによるテーブルの作成、変更、削除のリクエスト、テーブルのバックアップの作成など
  - これらをタブレットをホストしているYB-Serverの状態に関係なく、すべてのタブレットに操作が伝播することを保証する
- システムのメタデータの保存
  - 名前空間、テーブル、ロール、権限、YB-TServerのタブレット割り当てに関する情報など
  - 冗長性確保のためにRaftを使ってYB-Master全体にレプリケーションされる
- YB-TServerをタブレットの信頼できるソースとして割り当てる
  - YB-Masterはすべてのタブレットと、タブレットをホストしているYB-TServerを保存している
  - スマートクライアントに対して、タブレットとホストしているYB-Serverのマップから適切なYB-Serverを選択、直接通信させて効率的に処理を行わせるなどが可能
- バックグラウンド操作
  - データの配置と負荷分散
    - `CREATE TABLE`のようなYB-TServer全体に対する初期配置を決める際に、ユーザーの定義データに対する制約を適用して負荷を均一にする
    - ノードの増減に合わせて負荷のバランスをとり、データ配置制約を自動的に適用する
  - リーダーのバランス
    - 各YB-TServerによって提供されるタブレットの数がユニバース全体で均一にする
    - 各ノードで対称的な数のタブレットピアリーダーが存在するようにする
  - 長期にわたってYB-TServerに障害があった場合の再レプリケーション
    - 障害の継続期間が閾値を超えると、障害が発生したYB-TServerのタブレットのデータを代替のYB-TServerに再レプリケートするよう選出する
    - 再レプリケートはユニバースのフォアグラウンド操作に影響を与えないよう、YB-Masterのリーダーによりスロットル方式で開始される

# ひとまず

こんなところで。

コア機能や階層型アーキテクチャーといったところにも目を通した方がいいかもしれません。

https://docs.yugabyte.com/v2.20/architecture/core-functions/

https://docs.yugabyte.com/v2.20/architecture/layered-architecture/