HammerDB 4.0がリリースされていた - 複数インスタンスへの接続・負荷試験 その1
HammerDB 4.0がリリースされていた - リリースノートチェック - なからなLife
HammerDB 4.0がリリースされていた - 環境構築 - なからなLife
HammerDB 4.0がリリースされていた - 設定まわりの変化 - なからなLife
HammerDB 4.0がリリースされていた - ワークロードの実行 - なからなLife
の続きです。
新機能へのトライ
割と大きな新機能のはずなのに、リリースノートに出てこない、「クラスター構成における複数インスタンスへの接続・負荷試験」の機能に挑戦します。
手がかりは、ドキュメントの
https://hammerdb.com/docs4.0/ch04s05.htmlとhttps://hammerdb.com/docs4.0/ch04s06.html#d0e1777
、公式ブログの
https://www.hammerdb.com/blog/uncategorized/hammerdb-v4-0-new-features-pt4-connect-pooling-for-clusters/
くらいですね。
DB側の構成
マルチライター構成にも、ライター/リーダー構成にも対応しているらしいので、今回は以下の2つに対して試してみます。
(1)AWS RDS/MySQL 8.0.21 ソース/リードレプリカ構成。各1台、計2台
(2)AWS Aurora MySQL 5.7 Compatibirity マルチマスター/リードレプリカ構成。計3台。
マルチライター構成は、OracleRACを念頭に置いているんじゃないかと思っていたりはしますが、環境作るのめんどくさいので。。。
HammerDB側の設定
コネクションプールの有効化
dictの設定で、通常と異なる必須設定は以下の2つです
mysql_prepared = true mysql_connect_pool = true
mysql_connect_poolを「true」設定ファイルを読み込んで、DBクラスターを構成する各インスタンスにコネクションプールを作成、設定内容に基づいてワークロードをどのセッションからリクエストするかを制御するモードにシフトします。
なので、先に、設定ファイルを編集しておく必要があります。
HammerDB GUIを使用する場合も、GUI側でこの設定を編集することはできないので、設定ファイルを編集した上で、GUI上の「Driver Options」から「XML Connect Pool」のチェックボックスをONにします。
mysql_preparedについては、ドキュメント上、非常にわかりにくいところに
7.2. MySQL Prepare Statements
With MySQL there is the option to use server side prepared statements. This option is mandatory if using the XML connect pool feature.
(Google翻訳)
MySQLには、サーバー側のプリペアドステートメントを使用するオプションがあります。 XML接続プール機能を使用する場合、このオプションは必須です。
https://hammerdb.com/docs4.0/ch04s07.html
とあるので、この試験を実施する上ではtureにするのですが、全シナリオ、trueにしようがfalseにしようが、見た目の挙動は一緒でした。
なんだこれ、と思ってソースをちょっと覗き込んでみたら、
mysql_connect_pool = true
の場合、内部で強制的に
mysql_prepared = true
なモードに変えていました。
ので、特に意識して設定する必要はなさそうです。。。
設定ファイルの解説
DBクラスターを構成するインスタンスに関する設定は、以下の場所にDBMS種別ごとにxmlファイルで存在しています。
$ ll /home/ec2-user/HammerDB-4.0/config/connectpool total 20 -rwxr-xr-x 1 ec2-user ec2-user 977 Jul 8 2020 db2cpool.xml -rwxr-xr-x 1 ec2-user ec2-user 2459 Jul 8 2020 mssqlscpool.xml -rwxr-xr-x 1 ec2-user ec2-user 1343 Jul 8 2020 mysqlcpool.xml -rwxr-xr-x 1 ec2-user ec2-user 956 Jul 8 2020 oracpool.xml -rwxr-xr-x 1 ec2-user ec2-user 1091 Jul 8 2020 pgcpool.xml
ec2-userのホームディレクトリにHammerDBをインストールしたので、この場所にDBMS種別ごとの設定ファイルがあります。
今回は、MySQLの試験なので、「mysqlcpool.xml」を使います。
まずはデフォルト状態の中身を確認。
$ cat mysqlcpool.xml <connpool> <connections> <c1> <mysql_host>host1</mysql_host> <mysql_port>5432</mysql_port> <mysql_socket>/tmp/mysql.sock</mysql_socket> <mysql_user>root</mysql_user> <mysql_pass>mysql</mysql_pass> <mysql_dbase>tpcc</mysql_dbase> </c1> <c2> <mysql_host>host2</mysql_host> <mysql_port>5432</mysql_port> <mysql_socket>/tmp/mysql.sock</mysql_socket> <mysql_user>root</mysql_user> <mysql_pass>mysql</mysql_pass> <mysql_dbase>tpcc</mysql_dbase> </c2> <c3> <mysql_host>host3</mysql_host> <mysql_port>5432</mysql_port> <mysql_socket>/tmp/mysql.sock</mysql_socket> <mysql_user>root</mysql_user> <mysql_pass>mysql</mysql_pass> <mysql_dbase>tpcc</mysql_dbase> </c3> </connections> <sprocs> <neworder> <connections>c1 c2 c3</connections> <policy>round_robin</policy> </neworder> <payment> <connections>c1 c2 c3</connections> <policy>round_robin</policy> </payment> <delivery> <connections>c1 c2 c3</connections> <policy>round_robin</policy> </delivery> <stocklevel> <connections>c1 c2 c3</connections> <policy>round_robin</policy> </stocklevel> <orderstatus> <connections>c1 c2 c3</connections> <policy>round_robin</policy> </orderstatus> </sprocs> </connpool>
「connections」ブロックと、「sprocs」ブロックに分かれています。
「connections」は、各インスタンスへの接続情報の定義です。
公式ブログによると、接続数に上限はない、とのことです。
※定義名(c1とかc2)の方は、勝手に変えられるんだろうか。。。
にしても、MySQL用のテンプレートファイルなのに、portが3306じゃなくて5432になっているとか、どうなのよ。。。
「sprocs」には、TPC-Cワークロードの実装となっているストアドプロシージャの名前が列挙されていて、それらをどのConnection経由で実行するかを紐付けます。
各ストアドプロシージャの中身は、
- 更新あり
- neworder
- payment
- delivery
- 参照のみ
- stocklevel
- orderstatus
となっていますので、クラスター構成/接続情報に応じて、紐付けを行います。
リードレプリカへのセッションから「更新あり」のストアドプロシージャを呼び出さないようにするのがポイントですね。
「マルチマスタでリードレプリカ無し」とか「Oracle RAC」なら区別不要ですね。
あるいは、「Active Data Guard DML Redirect」なんかだと、あえてWriterじゃないインスタンスにも更新リクエスト投げてもいいかも。※Redisどうなるんだろ。
policy要素は、リクエスト先として指定されているconnectionsに対して、どのようなルールでリクエストを分散するかのルールです。
- first_named
- last_named
- random
- round_robin
下2つはそのまんまです。
実際に試験する
以下の試験を試してみます。
「mysqlcpool.xml」
のうち、connections部は、それぞれ固定で、sprocs部を微調整していきます。
(1)MySQL ソース1:レプリカ1構成
(1-1)すべてソース側に振る構成(レプリカへの接続設定は入れつつ、リクエストを投げない)
(1-2)参照のみはすべてリードレプリカ、更新ありはソース側に振る構成
(1-3)参照のみは2台に、更新ありはソース側に振る構成
(1-4)更新も双方に(エラーになるはず)
を試します。
Aurora MySQL マルチマスター(2台)構成
(2-1)更新も参照も全台に
を試します。
それ以外は、上記で済んでるはずなので。
また、コネクションプールを使うので、Auroraのクラスターエンドポイントやリーダーエンドポイントではなく、インスタンスエンドポイントを使うことにします。
今回はリーダー1台ですが、クラスター/リーダーエンドポイントはそれ自体がラウンドロビンのロードバランスを行うエンドポイントなので、コネクションプールセッションを確立する時点で宛先が確定します。
設定一覧
設定項目a | 設定項目b | 設定項目c | 試験1-1 | 試験1-2 | 試験1-3 | 試験1-4 | 試験2-1 |
---|---|---|---|---|---|---|---|
connections | c1 | mysql_host | ソースインスタンスのエンドポイント | 同左 | 同左 | 同左 | ライターインスタンス1のエンドポイント |
mysql_port | 3306 | 同左 | 同左 | 同左 | 同左 | ||
mysql_socket | /tmp/mysql.sock(不要) | 同左 | 同左 | 同左 | 同左 | ||
mysql_user | tpcc | 同左 | 同左 | 同左 | 同左 | ||
mysql_pass | tpcc | 同左 | 同左 | 同左 | 同左 | ||
mysql_dbase | tpcc | 同左 | 同左 | 同左 | 同左 | ||
connections | c2 | mysql_host | レプリカインスタンスのエンドポイント | 同左 | 同左 | 同左 | ライターインスタンス2のエンドポイント |
mysql_port | 3306 | 同左 | 同左 | 同左 | 同左 | ||
mysql_socket | /tmp/mysql.sock(不要) | 同左 | 同左 | 同左 | 同左 | ||
mysql_user | tpcc | 同左 | 同左 | 同左 | 同左 | ||
mysql_pass | tpcc | 同左 | 同左 | 同左 | 同左 | ||
mysql_dbase | tpcc | 同左 | 同左 | 同左 | 同左 | ||
connections | c3 | mysql_host | なし | 同左 | 同左 | 同左 | レプリカインスタンスのエンドポイント |
mysql_port | なし | 同左 | 同左 | 同左 | 3306 | ||
mysql_socket | なし | 同左 | 同左 | 同左 | /tmp/mysql.sock(不要) | ||
mysql_user | なし | 同左 | 同左 | 同左 | tpcc | ||
mysql_pass | なし | 同左 | 同左 | 同左 | tpcc | ||
mysql_dbase | なし | 同左 | 同左 | 同左 | tpcc | ||
sprocs | neworder | connections | c1 | c1 | c1 | c1 c2 | c1 c2 |
policy | round_robin | 同左 | 同左 | 同左 | 同左 | ||
payment | connections | c1 | c1 | c1 | c1 c2 | c1 c2 | |
policy | round_robin | 同左 | 同左 | 同左 | 同左 | ||
delivery | connections | c1 | c1 | c1 | c1 c2 | c1 c2 | |
policy | round_robin | 同左 | 同左 | 同左 | 同左 | ||
stocklevel | connections | c1 | c2 | c1 c2 | c1 c2 | c1 c2 | |
policy | round_robin | 同左 | 同左 | 同左 | 同左 | ||
orderstatus | connections | c1 | c2 | c1 c2 | c1 c2 | c1 c2 | |
policy | round_robin | 同左 | 同左 | 同左 | 同左 |
sprocsのconnectionsだけは、同左を使わず、違いを見やすいようにしています。
結果
ConnetionPoolによる負荷分散を有効にし、リーダーに負荷をかけるような設定で走らせたら、以下のようなエラーが大量出力されて、まともに計測ができませんでした。
Vuser 5:mysqlexec/db server: Unknown prepared statement handler (ostat_st) given to EXECUTE Vuser 5:mysqlexec/db server: Unknown prepared statement handler (delivery_st) given to EXECUTE
AuroraのWriter 1:Reader 1構成のものに対して実行しても一緒でした。。。
なお、PostgreSQLだと動きます。。。
GitHubにIssue上げてみた!
バグでした!
Google翻訳さんとDeepLさんに頑張ってもらって2時間くらい?かけて久々の英作文してIssue登録したら、あっさりバグ認定されて翌朝には修正版のプルリクが上がってました。
暫定対処法も書いてありました。ありがたい!
PostgreSQLにもやってみた
詳細省略しますが、期待通りに動きます!(雑
パラメータの名前がちょっと違うだけで、MySQLとやることは同じです。
Aurora PostgreSQLにはマルチマスターはないけどね。