読者です 読者をやめる 読者になる 読者になる

MySQL Thread Pool

  • MySQLサーバはスレッドモデルで動作しており、クライアントからの接続と1:1になるようにスレッドが生成される
  • サーバ上のCPU数を超える同時接続が発生すると、コンテキストスイッチングによってCPUキャッシュのヒット率が下がり、これがパフォーマンスに影響を与える
  • またメモリを多く消費してしまうことにより、スワッピングが発生し、サーバの実行パフォーマンスが大きく下がる
  • InnoDB--innodb-thread-concurrencyというパラメータがあり、0以外に設定することで並行実行数を制限することが可能だが、並行実行のスケーラビリティが下がってしまうため、これもパフォーマンスに影響がある

In MySQL Server Enterprise Edition

Mikael Ronstrom: MySQL Thread Pool: Summary

  • こういった問題を解決するために、MySQL Server Enterprise EditionにはThread Poolという機能が実装されている
    • Thread pool groupを準備して、Round Robinにより接続を各Thread Pool Groupに割り振る
    • Thread Pool Groupで実行されるクエリを最大1つに制限する
      • ただし制限時間を超えてもクエリの実行が完了しない場合には、他のクエリを実行可能とする
      • これによりデッドロックを回避することもできる
    • Thread Pool Groupは低優先度キュー(Low-Queue)と高優先度キュー(High-Queue)を持っており、あるトランザクションのクエリが実行されている場合には、そのトランザクションの後続のクエリは高優先度キューに入れられる
  • Connection Poolというクライアント側の機能と混同しない

Twitter's equivalent patch to Enterprise Edition

MySQL Thread Pool Improvements @ Twitter | My Blog

  • TwitterMySQL Serverに対する独自パッチを作成し適用することによって、Enterprise EditionのThread Poolと同等の機能を実装しているらしい
  • 並行性制御の粒度として、Thread Pool GroupはRead/Writeに対してLow/Highの4つのQueueを持ち、それぞれにキューサイズが設定される
  • どのGroup/Queueが使われるかは、クライアント側の接続要求に応じて決定される
  • 実行中のACTIVEなクエリは、長いIOやLockなどによってWAITに状態遷移して実行権を渡す場合があるが、ACTIVEなクエリに対するPreemption(実行権の奪取)は行わない
  • 長い時間Low-Queueに入れられていたクエリはHigh-Queueにkickupされる