PostgreSQL互換の分散SQLデータベースYugabyteDBの紹介

この記事は [SRA Advent Calendar 2023](https://qiita.com/advent-calendar/2023/sra) の17日目の記事です。

業務で分散データベース YugabyteDB について調査・検証する機会があったので、YugabyteDB の概要、特長、アーキテクチャについて書きたいと思います。

# YugabyteDB とは

YugabyteDB は、PostgreSQL および Cassandra と互換性を持ち、一貫性、拡張性、高可用性を兼ね備えたクラウドネイティブな分散型 SQL データベースです。

# YugabyteDBの特長

YugabyteDB には次のような特長があります。

## PostgreSQL/Cassandra 互換

YugabyteDB は RDBMS の PostgreSQL および NoSQL の Cassandra と高い互換性を持ち、PostgreSQL や Cassandra から YugabyteDB への移行に伴うアプリケーションの修正は少なくて済みます。

## 一貫性と拡張性の両立

従来の RDBMS では、SQL を使って複雑な集計や検索などの操作が可能です。また、トランザクションに対応しており、厳密なデータの一貫性が保証されるのが特長です。RDBMS は一貫性を保つためにもともとは 1台のサーバで実行するよう設計されているので、拡張しにくいというデメリットがあります。同じ状態を持つ複数サーバを用意して、読み取り処理を分散させることは可能ですが、書き込み処理は一貫性を保つために複数のサーバで並行して処理できません。データが大規模になると、処理速度が低下してしまうというのが RDBMS の大きな課題の1つとなります。

RDBMS のこういった性能課題に対して、NoSQL はデータの一貫性を犠牲にしているので、水平方向拡張性や可用性に優れています。必要に応じて自由に拡張できるので、大規模なデータであっても高速に処理できます。

YugabyteDB はこのような性能と一貫性のトレードオフをなくした、「一貫性」、「拡張性」、「高可用性」を兼ね備えたクラウドネイティブな分散データベースです。


## 読み取り・書き込み負荷分散

ローカルのディスクへアクセスしてデータを処理する RDBMS は複数のノードにまたがってデータを処理する YugabyteDB より処理速度は速いですが、大規模データになると、処理性能が落ちてしまいます。サーバのスペックを増やすことで性能が改善されますが、限界があります。同じ状態を持つ複数サーバを用意して、読み取りは分散して処理することはできますが、書き込みは一貫性を保つために、分散して処理できません。そのため、RDBMS は大規模データの書き込み処理能力が求められるアプリケーションには適していません。

YugabyteDB は水平方向拡張性や柔軟性に優れているため、処理するデータ量の増減に応じて、柔軟にスケールアウト/スケールインできます。また、RDBMS の書き込み処理が分散できないという弱点に対して、YugabyteDB はどのノードでも書き込み処理を行え、複数のサーバで分散して処理できるので、大規模で同時接続数が多いシステムでは、RDBMS と比べて高い性能を実現できます。

YugabyteDB は 1台のサーバではさばけないほど膨大なデータを扱い、今後もデータ量の増加が予想されるようなアプリケーションに適しています。


## 高可用性・耐障害性

従来のデータベースでは高可用性を実現するには、外部クラスタリングソフトウェアを利用するのが一般的です。クラスタリングソフトウェアは、常にデータベースサーバを監視し、プライマリに障害が発生した場合、レプリカを昇格し、レプリカへ切り替えることで、サービスを継続します。ただし、このような構成では系統切り替え時に若干のダウンタイムが発生するというデメリットがあります。

YugabyteDB には高可用性機能がビルトインされており、追加クラスタリングソフトウェアを導入する必要がなく、シンプルな構成で継続的な可用性を実現できます。また、系統切り替え処理は必要ないので、データベースノードに障害が起きたとしても、ダウンタイムなくデータベースの運用を続行できます。従来のデータベースの HA 構成より可用性に優れています。

また、YugabyteDB はマルチ AZ、マルチリージョン、マルチクラウド、ハイブリッドクラウド構成にも対応しているため、クラウドサービス、リージョン、データセンターなど、あらゆる規模での耐障害性を提供しています。


## 企業競争力を高める俊敏性

クラウドネイティブ時代に、企業の競争力を高める、俊敏性が強く求められています。従来のデータベースでは可用性や拡張性を実現するために、構成が複雑になってしまい、俊敏性が失われてしまいます。YugabyteDB は可用性と拡張性を併せ持ったオールインワンのソリューションなので、より迅速にデータベースクラスタを構築でき、リリースサイクルを短縮することができます。

さらに、フルマネージドサービスである YugabyteDB Managed も提供されています。管理コンソールで数回クリックするだけで指定したクラウド上にデータベースクラスタを迅速に構築できます。従来のように、サーバの構築、OS やミドルウェアのインストール・設定などのインフラ作業を行わなくて済むので、ビジネスを支えるアプリケーションの開発に集中でき、より俊敏性を高め、TCO 削減を実現できます。

## 地理分散

地理分散というのは、地理的に離れた複数の場所にまたがったデータベースクラスタのことで、デプロイメントパターンの1つです。

近年、データセンター障害や自然災害が発生した際に、早期復旧または事業継続を図るための対策の重要性が高まっています。地理分散デプロイメントを利用することで、データセンターの障害や自然災害が起こったとしても、サービスを中断することなく、継続して利用可能です。特定のリージョンで障害が起こっても、別のリージョンにあるノードが処理を継続するため、リージョン障害に対する回復力を持たせることが可能になります。

また、地理的に分散した場所にまたがるアプリケーションの場合にも活用できます。例えば、グローバルに広がった複数の拠点にまたがって YugabyteDB をデプロイし、利用ユーザの近いところにデータを配置することで、よりレイテンシーを抑えることが可能になります。

また、個人情報など機密性の高い情報を国内や特定の地域のデータセンターに保管する、といったユースケースに最適です。

## 様々な稼働環境に対応

YugabyteDB はオンプレミスやクラウド、仮想環境はもちろん、Kubernetes などのコンテナプラットフォームも含め、様々な環境に対応しており、マルチクラウドやハイブリッドクラウドでも利用できます。

また、YugabyteDB ではデプロイメントパターンや構成オプションが多く用意されており、アプリケーション要件に応じて、柔軟に環境や構成を選ぶことができます。

# YugabyteDB のアーキテクチャ

## 従来の RDBMS との違い

従来の RDBMS ではプライマリしか書き込み処理を受け付けられないという特性があり、冗長構成する場合は、書き込み処理をプライマリに送って、ストリーミングレプリケーションを使ってプライマリとレプリカの同期を行うのが一般的です。

一方、YugabyteDB ではプライマリとレプリカといった役割がなく、すべてのノードがプライマリとして振る舞い、書き込み処理を受け付けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397575/2f6e2a0b-f2d5-1b3f-6281-7dd3688f9f16.png)

## YugabyteDB の内部構造

YugabyteDB は YB-Master と YB-TServer の2つコンポーネントから構成されています。

YB-Master と YB-TServer の役割は以下の通りです。

* YB-Master: クラスタ全体のメタデータの管理、構成管理
*  YB-TServer: アプリケーションからのクエリを処理して、データとして保持

YB-Master は Raft という分散合意アルゴリズムを使って、冗長化しています。YugabyteDB のノードをデプロイすると、YB-Master と YB-TServer が自動的に作成されますが、YB-Master は最大 replication factor の数までしか作成されません。

replication factor とはデータのコピーの数のことです。つまり、同一データを保持する tablet peer における tablet の数のことです。(tablet については後述します。)

例えば、replication factor = 3 で 5ノードのクラスタを作成すると、以下のような構成になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397575/5dc1e0ed-353e-e260-9988-b2ace2fb3fee.png)

## YB-TServerの内部構造

ここでは、YB-TServer の内部構造について紹介します。

YB-TServer はクエリを処理するクエリレイヤとデータを処理するストレージレイヤの2つのレイヤに分かれています。

クエリレイヤは PostgreSQL 互換の API および Cassandra 互換の API をサポートしています。クエリレイヤは PostgreSQL のクエリ処理部分を再利用しているので、PostgreSQL との高い互換性を実現しています。クエリレイヤがクライアントリクエストを受け付けて、クエリを処理して、下位ストレージレイヤに送ります。

下位のストレージレイヤでは、テーブルとインデックスのデータは、自動的に複数のシャード(YugabyteDB では tablet と呼ばれる。以降、tablet) に分割され、各ノードの DocDB に分散配置されます。ノード間でデータの複製は tablet 単位で行われ、同じデータを持っている、複数の tablet 群が tablet peer と呼ばれます。各 tablet peer は1つの leader と複数の follower から構成され、内部的に Raft という合意アルゴリズムを使っています。基本的にはユーザからの書き込み・読み取り処理は leader に対して実行されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397575/82d041d3-00b3-4f4b-c4f7-d4c9cd67b48d.png)

# 障害時にもサービスが継続

YugabyteDB では、書き込み・読み取り処理は基本的には leader tablet に対して実行されますが、leader tablet がダウンしたら、どうのようにサービスを継続させるのか。ここでは、障害が発生した場合の挙動について説明します。

leader がダウンしたら、YugabyteDB が自動的に障害の発生を検出でき、3秒以内にいずれかの follower を leader に昇格させ、処理を継続します。table peer 単位で一定の値の tablet 数(=replication factor) を維持しないといけないため、別のノードに follower がリバランスされます。

クライアントからの接続は透過的に新しいリーダーに継続し、ユーザにデータベースノードがダウンしたことを意識させることなく継続使用が可能となります。また、leader と follower 間では、同期レプリケーションのため、ノード障害が発生しても、データの損失はありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397575/c8a767ca-3bb7-d7f7-32e8-fae0fe8644d7.png)

# スケールアウト

YugabyteDB では、簡単にノード数を増やすことができるので、アクセス数が増えた場合にも、容易に対応できるというメリットがあります。ノードを追加すると、leader と follower がノード間で均等に配置されるように自動的にリバランスされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397575/4e0aab42-ac20-29ab-049a-efca130f5ec4.png)

# 終わりに

今回は、PostgreSQL/Cassandra 互換の分散 SQL データベース YugabyteDB の概要や特長、アーキテクチャについて紹介しました。

YugabyteDB を使うことによって、サービスのダウンタイムの短縮、高い可用性、大容量データに対する高い処理性能など多くのメリットを得られます。PostgreSQL と高い互換性を持ち、アプリケーションの修正は少なくて済むので、比較的容易に移行できます。既存の PostgreSQL では解決できない書き込み性能問題や障害によるダウンタイムを改善したい場合は、YugabyteDB の使用を検討してみてはいかがでしょうか。