最近 Aurora の検証をしているので,今後は Aurora 関連の記事を書く機会が増えそう.
前提
- RDS (Aurora MySQL)
- インスタンスタイプ :
db.t2.medium
DBInstanceClassMemory
とは
RDS のパラメータグループでは,特定の変数と演算子を使った動的な値設定ができる.今回は変数 DBInstanceClassMemory
に関して調べたことと,計算が合わずに困ったことを書いておこうと思う.
DBInstanceClassMemory
は,名前だけを見るとインスタンスタイプごとに搭載されたメモリサイズのように思えるけど,実際には違っていて,RDS プロセスに割り当てられたメモリサイズのことを意味する.よって,搭載されたメモリサイズよりは確実に小さい値となる.その点はドキュメントにも書いてある.
DBInstanceClassMemory
現在の DB インスタンスに関連付けられている DB インスタンスクラスに割り当てられたメモリのバイト数を返します。このメモリは、インスタンスを管理する Amazon RDS プロセスによって使用されるメモリよりも小さくなります。 docs.aws.amazon.com
DBInstanceClassMemory
を参照しているパラメータ
デフォルトのパラメータグループ "default.aurora5.6" で,以下の4パラメータが DBInstanceClassMemory
を参照している.特に innodb_buffer_pool_size
や max_connections
などは,ワークロードに応じてチューニングが必要なので,Aurora クラスタのデフォルト値を理解しておくことは重要だと考えている.
innodb_buffer_pool_size
max_connections
query_cache_size
thread_cache_size
逆算して DBInstanceClassMemory
を知る
まず,デフォルトのパラメータグループのまま起動したクラスターの Aurora Writer で,上記のパラメータの値を確認してみた.
mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | innodb_buffer_pool_size | 1610612736 | +-------------------------+------------+ 1 row in set (0.00 sec) mysql> SHOW VARIABLES LIKE 'max_connections'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 90 | +-----------------+-------+ 1 row in set (0.01 sec) mysql> SHOW VARIABLES LIKE 'query_cache_size'; +------------------+----------+ | Variable_name | Value | +------------------+----------+ | query_cache_size | 89498624 | +------------------+----------+ 1 row in set (0.01 sec) mysql> SHOW VARIABLES LIKE 'thread_cache_size'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | thread_cache_size | 2 | +-------------------+-------+ 1 row in set (0.00 sec)
まず最初に innodb_buffer_pool_size
の値から逆算して DBInstanceClassMemory
を調べてみた.db.t2.medium
のメモリサイズは 4GB なので,以下の式に当てはめて逆算すると,DBInstanceClassMemory
は 2GB だとわかった.よって db.t2.medium
においては,メモリサイズの 50% が DBInstanceClassMemory
に割り当てられていることがわかった.
innodb_buffer_pool_size = {DBInstanceClassMemory*3/4} = 2147483648 * 3 / 4 = 1610612736
ちなみに,この割合は固定値ではなく,インスタンスタイプが良くなればなるほど,上がっていく.以下の記事を見ると,最高スペックの db.r3.8xlarge
だと 96.4% が DBInstanceClassMemory
に割り当たっていることがわかる.
query_cache_size
と thread_cache_size
も同様に逆算する
同様に query_cache_size
と thread_cache_size
も値から逆算すると,DBInstanceClassMemory
は 2GB だとわかった.よって,db.t2.medium
だと DBInstanceClassMemory
は 2GB だとほぼ断定できそう.
query_cache_size = {DBInstanceClassMemory/24} = 2147483648 / 24 = 89478485.3333333 thread_cache_size = {DBInstanceClassMemory/1005785088} = 2147483648 / 1005785088 = 2.135131723
あれれ max_connections
の計算が合わないぞ?
やっと今回の本題に入る.max_connections
の式は以下のようになっていて,GREATEST 関数に含まれてる値の中で,一番大きい値が割り当たるようになっている.
GREATEST({log(DBInstanceClassMemory/1073741824)*45},{log(DBInstanceClassMemory/8187281408)*1000})
よって DBInstanceClassMemory
を 2GB だとすると,以下の計算となり,値は 45 だと推測できる.
{log(DBInstanceClassMemory/1073741824)*45} = log(2147483648/1073741824) * 45 = 45 {log(DBInstanceClassMemory/8187281408)*1000} = log(2147483648/8187281408) * 1000 = -1930
でも実際には 90 だった.計算が合わない.
mysql> SHOW VARIABLES LIKE 'max_connections'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 90 | +-----------------+-------+ 1 row in set (0.01 sec)
デフォルトの式で max_connections
を 90 にするには DBInstanceClassMemory
が 4GB である必要があって,そうすると db.t2.medium
に搭載されたメモリサイズと一致してしまう.となると,パラメータによって DBInstanceClassMemory
の値が違う?そんなはずは無いだろう.うーん謎だ.
{log(DBInstanceClassMemory/1073741824)*45} = log(4294967296/1073741824) * 45 = 90
AWS サポートに問い合わせた
AWS サポートに問い合わせたところ,原因が判明した.
- まず
db.t2.medium
のDBInstanceClassMemory
は 2GB ではなく 2.0004 GB "程度" であることinnodb_buffer_pool_size
の値から逆算すると気付けなかった
- 2.0004 GB の前提で log 計算をすると
log(2147913144.7296/1073741824) = 1.00028
となる - 1.00028 を 2.0 に "切り上げ" てから 45 を乗算するため
2 * 45 = 90
となる
結論として,ドキュメントに書かれていないロジックになっていて,逆算することは難しかった.今後 max_connections
の計算式をもっと簡単にする予定があるらしく,今後に期待!(まぁ実際の運用を考えると max_connections
をデフォルト値で運用することは無さそうなんだけど...)
Black Belt
www.slideshare.net