重要
このページは英語版のページを機械翻訳しています。原文はこちらからご覧ください。

TiKVスレッドプールのパフォーマンスを調整する

このドキュメントでは、TiKV内部スレッドプールとそのパフォーマンスを調整する方法を紹介します。

スレッドプールの紹介

TiKVスレッドプールは、主にgRPC、Scheduler、UnifyReadPool、Raftstore、StoreWriter、Apply、RocksDB、およびCPUをあまり消費しないいくつかのスケジュールされたタスクと検出コンポーネントで構成されています。このドキュメントでは、主に、読み取りおよび書き込み要求のパフォーマンスに影響を与えるCPUを集中的に使用するスレッドプールをいくつか紹介します。

  • gRPCスレッドプール:すべてのネットワークリクエストを処理し、さまざまなタスクタイプのリクエストをさまざまなスレッドプールに転送します。

  • スケジューラスレッドプール:書き込みトランザクションの競合を検出し、2フェーズコミット、ペシミスティックロック、トランザクションロールバックなどの要求をキーと値のペアの配列に変換してから、RaftログレプリケーションのためにRaftstoreスレッドに送信します。

  • Raftstoreスレッドプール:

    • すべてのRaftメッセージと、新しいログを追加するための提案を処理します。
    • Raftログをディスクに書き込みます。 store-io-pool-sizeの値が0の場合、Raftstoreスレッドはログをディスクに書き込みます。値が0でない場合、RaftstoreスレッドはログをStoreWriterスレッドに送信します。
    • 大部分のレプリカのRaftログに一貫性がある場合、RaftstoreスレッドはログをApplyスレッドに送信します。
  • StoreWriterスレッドプール:すべてのRaftログをディスクに書き込み、結果をRaftstoreスレッドに返します。

  • スレッドプールの適用:Raftstoreスレッドプールから送信された送信済みログを受信し、それをキー値要求として解析してからRocksDBに書き込み、コールバック関数を呼び出して書き込み要求が完了したことをgRPCスレッドプールに通知します。結果をクライアントに返します。

  • RocksDBスレッドプール:これは、RocksDBがタスクを圧縮およびフラッシュするためのスレッドプールです。 RocksDBのアーキテクチャとCompactの操作については、 RocksDB:フラッシュおよびRAMストレージ用の永続的なKey-Valueストアを参照してください。

  • UnifyReadPoolスレッドプール:コプロセッサースレッドプールとストレージ読み取りプールの組み合わせです。 kv get、kv batch get、raw kv get、コプロセッサーなどのすべての読み取り要求は、このスレッドプールで実行されます。

TiKV読み取り専用リクエスト

TiKVの読み取り要求は、次のタイプに分けられます。

  • ストレージ読み取りプールで実行される、特定の行または複数の行を指定する単純なクエリ。
  • コプロセッサー読み取りプールで実行される、複雑な集計計算と範囲クエリ。

TiKV v5.0以降、すべての読み取り要求は、デフォルトでクエリに統合スレッドプールを使用します。 TiKVクラスタがTiKVv4.0からアップグレードされ、アップグレード前にreadpool.storageuse-unified-pool構成がfalseに設定されていた場合、すべての読み取り要求は、アップグレード後も異なるスレッドプールを使用し続けます。このシナリオでは、すべての読み取り要求でクエリに統合スレッドプールを使用するように、 readpool.storage.use-unified-poolの値を設定できtrue

TiKVスレッドプールのパフォーマンスチューニング

  • gRPCスレッドプール。

    gRPCスレッドプールのデフォルトサイズ( server.grpc-concurrencyで構成)は5です。このスレッドプールにはコンピューティングのオーバーヘッドがほとんどなく、主にネットワークI / Oと逆シリアル化の要求を担当するため、通常、デフォルトの構成を調整する必要はありません。

    • TiKVを使用してデプロイされたマシンのCPUコアの数が少ない(8以下)場合は、 server.grpc-concurrency構成項目を2に設定することを検討してください。
    • TiKVでデプロイされたマシンの構成が非常に高い場合、TiKVは多数の読み取りおよび書き込み要求を実行し、GrafanaでスレッドCPUを監視するgRPC poll CPUの値がserver.grpc-concurrencyの80%を超える場合は、 server.grpc-concurrencyの値を増やしてスレッドを維持することを検討してください。プールの使用率が80%未満(つまり、Grafanaのメトリックが80% * server.grpc-concurrency未満)。
  • スケジューラスレッドプール。

    TiKVがマシンのCPUコアの数が16以上であることを検出すると、スケジューラスレッドプールのデフォルトサイズ( storage.scheduler-worker-pool-sizeで構成)は8になります。 TiKVがマシンのCPUコアの数が16未満であることを検出すると、デフォルトのサイズは4になります。

    このスレッドプールは主に、複雑なトランザクション要求を単純なKey-Value読み取りおよび書き込み要求に変換するために使用されます。ただし、スケジューラスレッドプール自体は書き込み操作を実行しません

    • トランザクションの競合が検出された場合、このスレッドプールは競合の結果を事前にクライアントに返します。
    • 競合が検出されない場合、このスレッドプールは、書き込み操作を実行するKey-ValueリクエストをRaftログにマージし、RaftログレプリケーションのためにRaftstoreスレッドに送信します。

    一般的に、過度のスレッドスイッチングを回避するには、スケジューラスレッドプールの使用率が50%から75%の間であることを確認するのが最善です。スレッドプールのサイズが8の場合、GrafanaでTiKV-Details.Thread CPU.scheduler worker CPUを400%から600%の間に保つことをお勧めします。

  • Raftstoreスレッドプール。

    Raftstoreスレッドプールは、TiKVで最も複雑なスレッドプールです。このスレッドプールのデフォルトサイズ( raftstore.store-pool-sizeで構成)は2です。 StoreWriterスレッドプールの場合、デフォルトのサイズ( raftstore.store-io-pool-sizeで構成)は0です。

    • StoreWriterスレッドプールのサイズが0の場合、すべての書き込み要求はRaftstoreスレッドによってfsyncの方法でRocksDBに書き込まれます。この場合、次のようにパフォーマンスを調整することをお勧めします。

      • Raftstoreスレッドの全体的なCPU使用率を60%未満に保ちます。 Raftstoreスレッドの数が2の場合、 TiKV-DetailsThread CPURaft store CPUをGrafanaで120%未満に保ちます。 I / O要求により、理論上、RaftstoreスレッドのCPU使用率は常に100%未満です。
      • 慎重に検討せずに書き込みパフォーマンスを向上させるためにRaftstoreスレッドプールのサイズを大きくしないでください。ディスクの負荷が増加し、パフォーマンスが低下する可能性があります。
    • StoreWriterスレッドプールのサイズが0でない場合、すべての書き込み要求は、StoreWriterスレッドによってfsyncの方法でRocksDBに書き込まれます。この場合、次のようにパフォーマンスを調整することをお勧めします。

      • 全体的なCPUリソースが十分な場合にのみ、StoreWriterスレッドプールを有効にします。 StoreWriterスレッドプールが有効になっている場合は、StoreWriterスレッドとRaftstoreスレッドのCPU使用率を80%未満に保ちます。

      書き込み要求がRaftstoreスレッドによって処理される場合と比較して、理論的には、書き込み要求がStoreWriterスレッドによって処理される場合、書き込みレイテンシとデータ読み取りのテールレイテンシが大幅に短縮されます。ただし、書き込み速度が速くなると、それに応じてRaftログの数が増えます。これにより、Raftstoreスレッド、Applyスレッド、およびgRPCスレッドのCPUオーバーヘッドが増加する可能性があります。この場合、CPUリソースが不足するとチューニング効果が相殺され、書き込み速度が以前より遅くなる可能性があります。したがって、CPUリソースが十分でない場合は、StoreWriterスレッドを有効にすることはお勧めしません。 RaftstoreスレッドはほとんどのI/O要求をStoreWriterスレッドに送信するため、RaftstoreスレッドのCPU使用率を80%未満に保つ必要があります。

    • ほとんどの場合、StoreWriterスレッドプールのサイズを1または2に設定します。これは、StoreWriterスレッドプールのサイズがRaftログの数に影響するため、スレッドプールサイズの値が大きすぎないようにする必要があるためです。 CPU使用率が80%を超える場合は、スレッドプールサイズを増やすことを検討してください。

    • Raftログの増加が他のスレッドプールのCPUオーバーヘッドに与える影響に注意してください。必要に応じて、Raftstoreスレッド、Applyスレッド、およびgRPCスレッドの数を増やす必要があります。

  • UnifyReadPoolスレッドプール。

    UnifyReadPoolは、すべての読み取り要求を処理する責任があります。デフォルトのサイズ( readpool.unified.max-thread-countで構成)は、マシンのCPUコアの数の80%です。たとえば、マシンのCPUに16コアがある場合、デフォルトのスレッドプールサイズは12です。アプリケーションのワークロードに応じてCPU使用率を調整し、スレッドプールサイズの60%から90%の間に保つことをお勧めします。

    GrafanaのTiKV-Details.Thread CPU.Unified read pool CPUのピーク値が800%を超えない場合は、 readpool.unified.max-thread-countから10に設定することをお勧めします。スレッドが多すぎると、スレッドの切り替えが頻繁になり、他のスレッドプールのリソースを消費する可能性があります。

  • RocksDBスレッドプール。

    RocksDBスレッドプールは、RocksDBがタスクを圧縮およびフラッシュするためのスレッドプールです。通常、設定する必要はありません。

    • マシンのCPUコアの数が少ない場合は、 rocksdb.max-background-jobsraftdb.max-background-jobsの両方を4に設定します。

    • 書き込みストールが発生した場合は、 GrafanaのRocksDB-kvの書き込みストール理由に移動し、 0以外のメトリックを確認してください。

      • 保留中の圧縮バイトに関連する理由が原因である場合は、 rocksdb.max-sub-compactions2または3に設定します。この構成項目は、単一の圧縮ジョブで許可されるサブスレッドの数を示します。デフォルト値は、TiKV 4.0では3 、TiKV3.0では1です。

      • 理由がmemtablecountに関連している場合は、すべての列のmax-write-buffer-numberを増やすことをお勧めします(デフォルトでは5 )。

      • 理由がレベル0のファイル制限に関連している場合は、次のパラメーターの値を64以上に増やすことをお勧めします。

        rocksdb.defaultcf.level0-slowdown-writes-trigger
        rocksdb.writecf.level0-slowdown-writes-trigger
        rocksdb.lockcf.level0-slowdown-writes-trigger
        rocksdb.defaultcf.level0-stop-writes-trigger
        rocksdb.writecf.level0-stop-writes-trigger
        rocksdb.lockcf.level0-stop-writes-trigger