YugabyteDB 2.15: 動的なワークロードの最適化

Tomohiro Ichimura
The Distributed SQL Blog
14 min readJul 1, 2022

YugbyteDB 2.15の重要なイノベーションは、みなさんがワークロードの変化に対して適応するだけでなく、成功することにも役立てていただけます。

新しいYugabyteDBの機能は、多種多様なアプリケーション、またそこから派生する予測のできないアプリケーションについても、より簡単に対応します。柔軟で、ユニファイドなデータベースを活用することで、アプリケーションを再構築することも、新しいデータベースのための環境を増やす必要もありません。

お使いのアプリケーションとそのアプリケーションに対する要件は、時事刻々と変化するため、それを予測することはほぼ不可能です。古くからの顧客は消え去り、新たな顧客が驚くべきスピードで増加している現在、新しいサービスは今までとは異なるアプリケーション・アーキテクチャを必要としています。

例えば、NoSQLに依存したアプリケーションが多くありますが、将来的にはSQLがより重要になる可能性もあります。みなさんはあらゆる可能性に対応する必要があります。

YugabyteDB 2.15は、動的なワークロードの最適化をサポートするために、以下の新しい機能を提供します。

  • Quality of Service (QoS) とマルチ・テナンシー
  • Dynamic app-aware sharding(アプリケーションに配慮した動的なシャーディング)

今後のブログポストにおいて、他の柱となる機能について詳細を説明する予定ですので、ぜひチェックしてみてください。それでは、上記機能についてもう少し詳細をみていきましょう。

Quality of Service (QoS) とマルチテナンシー

YugabyteDBを用いるアプリケーションの数と多様性が増すにつれて、QoSとマルチテナンシーの必要性を感じておりました。この新しい機能により、お客様は、最重要のサービス(もしくはSQLステートメント)における性能要件の達成が可能となり、高負荷時においても安定運用が実現されます。

特にQoSが重要となるシナリオが二つあります

  • 高負荷時のクラスタ使用率: より優先度の高いトランザクションを確保しながらも、クラスタを稼働し続けなければならない場合が想定されます。これにはアドミッション・コントロール(Admission Control)で対応します
  • マルチテナンシー: 複数のテナント、もしくはサービスがクラスタを利用した場合、特定のテナント、あるいはサービスのリソース利用制限が必要となります。これにはテナントに対する使用制限(Rate limiting)で対応します。

アドミッション・コントロールによる高負荷状態のクラスタ管理

YugabyteDBはアドミッション・コントロールを新たに実装し、高負荷状態にあるクラスタの継続的な稼働を実現します。アドミッション・コントロールはコネクションが認証・認可された後に有効となります。クエリ処理と実行における様々なステージにて動作します。以下のような制御によるQoSの実現が可能です。

QoSによるトランザクション実行時の優先順位付け

新しいYugabyteDBのトランザクション優先順位付けにより、最も重要なリクエストが、常に最初に処理されるようになります。アプリケーションはこの優先度を個別のトランザクションに適用することが可能です。もし楽観的並行性制御(optimistic concurrency control)を利用した場合、より高い優先度をもつトランザクションは、より低い優先度のトランザクションに対して優先されます。この場合、トランザクションに衝突が生じた場合、 低い優先度のトランザクションは中止されます。

この振る舞いは、セッション変数の組み合わせにて設定されます。

  • yb_transaction_priority_lower_bound ( 0.0 と 1.0の間の値)
  • yb_transaction_priority_upper_bound (0.0 と1.0の間の値)

当該のセッションにあるトランザクションは、この最大値と最小値の間のランダムな数を計算、割り当てます。もしこのトランザクションが他のものと衝突する場合、トランザクション優先度の値を比較します。より高い優先度をもつトランザクションが勝利します。

例えば、金融サービスにおいて、同じタイミングで、同じアカウントに対して入出金を処理するトランザクションがあった場合、より高い優先度を(出金処理に対して)入金処理に与えたいとします。これを実現するには、以下のようなトランザクション優先度を両方のトランザクションに設定する必要があります。

入金トランザクションは、出金処理が初期化された後に開始します、しかし出金処理が終わる前に別のセッションから入金トランザクションが処理されます。

TemenosのクラウドプラットフォームでYugabyteDBがビジネストランザクションを秒間10万件までスケールした事例も合わせてご確認ください

ノード/テナント/データベースあたりの接続数制限

YugabyteDBクラスタへの各接続にはCPUとメモリを消費します。つまり、アプリケーションにとって必要な接続数を考慮するのは重要なことです。YugabyteDBはmax_connections設定でクラスタのノードあたりのコネクション(つまりリソースを消費するコネクション)数を制限します。デプロイメントしたリソースを過剰に消費するようなコネクションの発生を防ぎます。

max_connectionsの設定値については、adminユーザにてysqlshから確認することが出来ます。

SHOW max_connections;max_connections— — — — — — — —300

同様に、テナントあたりのコネクション数の制限も重要です。これを実現するために、テナントとデータベース、さらにはユーザを紐づけ、そして、ユーザに対するデータベースあたりのコネクション数の割合を制限することが可能です。

データベースに対する接続制限は以下のように設定します。

alter database test_connection CONNECTION LIMIT 1;

設定された制限値については、以下のように確認ができます。

select datname, datconnlimit from pg_database where datname =’test_connection’;    datname     | datconnlimit— — — — — — — — + — — — — — — —test_connection |            1

書き込み主体のワークロードに対するアドミッションコントロール

YugabyteDBには、書き込みの割合の増加に伴い、(メモリからディスクへの)フラッシュやコンパクション(データ使用領域の圧縮)が維持できなった場合に書き込みを抑える拡張された制御機能があります。これの機能がない場合、ハードウェアが処理できる以上の書き込みを試みると、データベースの以下のような挙動を引き起こします:

  • スペースの増幅が増加し、ディスク容量の不足に陥ります。
  • 読み込みの増幅が増加、読み込みのパフォーマンスが著しく低下

新しいYugabyteDB 2.15の機能により、上記のような懸念を排除するべく、書き込み速度を管理可能な範囲に抑えます。この場合、YugabyteDBは、書き込みリクエストのうちの一部、あるいは全体を受け付けないことで、適切に書き込みを抑えます。

書き込みを受け付けられず、ある程度処理時間が必要となっている理由には主に二つのシナリオが考えられます。

CPU性能が十分でない環境、もしくはDisk性能が十分でない場合です。これが発生した場合、以下の症状がデータベースレイヤーに発生します。

  • フラッシュが維持できない: システムが処理できる以上の書き込みが発生しているため、memtableが大量に作成されて、結果フラッシュが必要となります。
  • データ使用領域の圧縮が維持できない: データベースが書き込みによる過剰負荷が発生しているため、データ使用領域の圧縮も出来ません。
  • WALの書き込みが極端に遅くなる: WAL書き込みが遅い場合、書き込みのレイテンシーが増加します。これがアドミッション・コントロールを生成する自然な流れとなります。
  • ディスクIOPSと帯域の制限: 多くのクラウド環境において、disk IOPSもしくはネットワーク帯域の利用率が制限される

適切に書き込みを抑えるためには、YugabyteDBは書き込みのトリガーを停止、もしくは書き込みのトリガーの抑制、のいずれかの手法を採用します。これらのトリガーがどのように有効化されるかにについて、以降でご説明いたします。

書き込みトリガーの停止

書き込みトリガーを停止するシナリオにおいては、YugabyteDBが書き込みリクエストを受け付けたときに、新たな書き込みリクエストの要求を拒否することになります。

この新たな書き込みリクエスト拒否については、tablet単位で算出されます。書き込みリクエストが既にデータベースにて処理されるのであれば(拒否されてなく、受付られている場合であれば)、その書き込みは処理されます。

しかしながら、その書き込み処理が、関連する書き込みをトリガーする必要があるとなった場合、(例えば、特定の書き込みにおいて、インデックスのアップデートが必要になる場合など)、この関連するリクエスト自体については失敗する可能性があります。

書き込みトリガーの停止に伴い、以下のいずれかのケースが想定されます。

  • SSTファイルの極端な増加: SST(Sorted Sequence Table)ファイルの数が、sst_files_hard_limitフラグで設定された値(デフォルトでは48)を超過することが想定されます。この場合、これ以上の書き込みはできず、全ての新しい書き込みリクエストは拒否されます。
  • Memstoreが頻繁にフラッシュ: この状況は大量の数のtabletが書き込まれている状態で起こり得ます。この際、memstoreは頻繁にフラッシュされるため、結果的に多くのSSTファイルを生成することになります。このような状況において、memstoreに割り当てられるサイズの合計値を調整することができます。このmemstoreのサイズの合計値については、以下の二つのフラグの最小値が適用されます。
  • global_memstore_size_mb_max (デフォルトは 2GB)
  • global_memstore_size_percentage (デフォルトはTServerのメモリの10%)

YB-TServerがメモリをどう割り当てるかについては、以下の二つの異なるオプションがあります。

  • default_memory_limit_to_ram_ratio を設定することで、プロセスが利用する合計のRAMの割合を制御することができます。
  • memory_limit_hard_bytesを指定して、相対的な値を指定することも可能です。例えば、32GBのRAMがYB-TServerにて保持されている場合、memory_limit_hard_bytes 34359738368 と指定します。
  • フラッシュ待ちのmemstoreが多い場合: 一つ以上のmemstoreがディスクへのフラッシュを待つキューにある場合です。この場合、このトリガーが有効化されているときには、このキューの値は2に設定されます(つまり、2あるいはそれ以上のフラッシュ待ちをするmemstoreのキューがある)。

書き込みトリガーの抑制

書き込みトリガーの抑制は、SSTファイルがsst_files_soft_limitで設定される値を超えた場合に発生します。しかし、これはsst_files_hard_limitで設定される値は超えてない場合です。

sst_files_soft_limit フラグのデフォルト値は24です。書き込みの抑制により、新たな書き込みリクエストのうち、Xの割合で拒否がされます。Xは以下のように算出されます。

X = (<num SST files> — soft_limit) / (hard_limit — soft_limit)

アプリケーションに配慮した動的なシャーディング

みなさんが大企業、もしくは急成長を遂げている企業に従事されている場合は、幅広い種類のトランザクションアプリケーションを扱っていると思われます。これらのアプリケーションは異なる要求レベルが求められ、同時に単一データベースで処理されているケースが見受けられます。これまでのYugabyteDBの機能に、新たな2.15でのQoSとマルチテナンシー機能拡張が加わったことで、リソースを必要以上に追加することなく、異なる種類とサイズのワークロードに対しても対応することが出来ます。

加えて、変化のある、衝突を起こすようなワークロードを、レスポンスタイムに応じた対応をせずに処理することも可能です。さらには、サービスレベルに応じたワークロードの処理をすることも可能です。

より拡張した柔軟性とアプリケーションのサポートは、様々なシナリオで望ましいものとなります。

  • 小さいデータセットで、HAもしくは地理分散が必要: アプリケーションが小さいデータセットを処理する場合は、細かなテーブル、インデックス、あるいはその他のリレーションが単一のデータベースの中に数多く必要とされるといったケースが想定されます。全体としてもデータセットの数は小さいものの、高可用性、あるいは地理的なデータ分散が必要とされます。この場合、データセットのスケールと、IOPSは喫緊の課題にはなっておりません。また、小さなデータセットが複数のノードに分散していることで、ネットワークのホップがパフォーマンスに影響する可能性も考えられます(例えばJoinなど)。
  • 大きいデータセットが、大量もしくは少量のテーブルで構成されている場合:
    別のアプリケーションが、いくつかのサイズの大きいテーブルと、大量のサイズの小さいテーブルを使っていて、大きなデータセットが、多くのテーブルとインデックスを必要とする場合が考えられます。アプリケーションが、より大きくなる可能性のある少数のテーブルを扱い、かつそれらが大規模にスケールするのに、その他のテーブルは小さいままである場合も想定されます。この場合においては、大きくなる可能性のある少数のテーブルのみが、シャードとスケールアウトを必要とします。
    それ以外のテーブルについては、colocation(共存)のメリットを享受します。というのも、大きくなる可能性のある少数のテーブルとは異なり、ネットワークホップを必要としなくなるからです。

さあ、はじめましょう、そしてより詳細を知るには

我々のフラグシップ製品である、エンタープライズ・グレードの機能を数多く実装した、YugabyteDBの最新バージョン2.15をリリースできることを大変光栄に思います。

より詳細を知りたい方、試しに使ってみたい方は、ぜひ以下の情報もチェックしてください。

  • YugabyteDB 2.15 はすぐ利用できます ダウンロードはこちら!
    インストールは数分で完了します
  • Slack に参加してください!より多くのコミュニティメンバーや、Yugabyteのエンジニアリングチームとのコミュニケーションとつながりましょう!

最後に、今年で4回目の開催となる年次イベントDistributed SQL Summitが9月に開催です。ぜひご登録ください!

本記事は、The Distributed SQL Blogsにて2022年6月29日に公開されたYugabyteDB 2.15: Support Any Workload with Dynamic Workload Optimizationを翻訳および一部訳注を追加しております。最新情報は英語版の記事を参照してください。

--

--