地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【ProxySQL】入門する

概要

ProxySQLを触る機会があったので入門してみた記事。2.1が最新見たいだが仕事で使うのが1.4なのでなるべくそのバージョンに合わせた内容で調べていく。(最新だとこうだね〜みたいなのは書いておくつもり)

proxysql.com

目次

ProxySQLとは

ProxySQLは、ハイパフォーマンスなMySQLSQLプロキシでクエリールールによるルーティングなど柔軟な設定変更が可能だったり変更もgracefulに行えるという特徴を持つ。memcacehdのproxyツールのtwitter/twemproxyあたりをイメージするとわかりやすそうと感じた。ちなみにProxySQLはMysQL以外のDBでも使えるみたいです。

proxysql.com

ここからは主に公式を参考に書いてます。仕事で使うのが1.4とかなので新しすぎる部分はなるべく除いて記載(最新は2.1)。実装はC++がメインみたいで他も結構使われてるみたいでした。(リポジトリ見た感じなので具体的にはわからない。)

主な機能

  • クエリーキャッシュ
    • クエリ分散機能に TTL を設定することで実現可能。selectでも特的のクエリではキャッシュしないみたいな柔軟な設定を書ける
    • キーは「ユーザー名、スキーマ名、およびクエリのハッシュ」になるとのこと
  • クエリールーティング
    • この辺の設定はProxySQLプロセスの再起動を必要とせずに、できるだけ多くの設定を動的に変更可能
  • フェイルオーバー連携
  • ファイアーウォール
  • 自動オフラインバックエンド
    • 死活監視的なものでpingの遅延の値などをみて自動でDBをオフラインにして接続を行わないような設定が可能です。

アーキテクチャ

f:id:ryuichi1208:20210918100023p:plain

  • RUNTIME
    • 起動しているproxysqlプロセスが実際に従うコンフィグデータ。データはメモリ上にあるので設定変更してプロセス再起動すると設定は消えます
  • MEMORY
    • 構成変更するときに主に利用するコンフィグデータ。ここも再起動するとデータは消えます。
  • DISK
    • MEMORYでの設定を永続的に保存するコンフィグデータ。SQLiteのdbに保存される。デフォルトは/var/lib/proxysql/proxysql.db
  • CONFIG FILE
    • テキスト形式で設定を記述する(proxysqlからは参照のみ)。デフォルトは/etc/proxysql.cnf。再起動してもデータは残る

注意点がいくつかあってオンラインで設定した内容はサービス再起動時に消えます。サーバをスケールアウトする際に稼働中のサーバにオンラインで設定した状態だと設定差異が入った状態でサービスインする可能性がありそうという感じですね。ありそうなのはProxySQLの突死とかで意図せずサービス再起動したケースとかも起こりますね。

ログイン

OFFLINE_SOFT/OFFLINE_HARDとは

OFFLINE_HARDに対してOFFLINE_SOFTというステータスがあります。 これは、アクティブなトランザクションとコネクションはそのままで、新しいトラフィックは新しい別のバックエンドに送信するというものらしいです。gracefulに切り替えることでユーザ影響なしで特定のDBを切り離すことが可能になります。ただconnect(2)中とかアプリ管轄外の状態のコネクションに関してはOFFLINE_SOFTしても新規接続は行くのでその辺は念頭に入れておく必要がありそうです。

ちなみにOFFLINE_HARDではサーバーへの新しい接続は作成されず、既存の接続はすぐに削除されます。

監視

github.com

色々プラグインはありそうでどの監視ツールでもおそらく問題なく取れそうな感じがした。知りたいのはスレッド数だったりコネクション数とクエリ発行数とかでその辺あれば概ねことは足りそうでほぼほぼ公式で提供してくれているメトリクスで大丈夫そうでした。あとはスレッドごとのメモリとかTCPレベルでの話は自分で書く必要がありそう。

proxysql.com

負荷分散

weight – the bigger the weight of a server relative to other weights, the higher the probability of the server to be chosen from a hostgroup. ProxySQL default load-balancing algorithm is random-weighted

分散アルゴリズムはデフォルトでWeighted Random Selectionになるらしいです。以下のように書けば3306:3307のクエリ発行割合は1:2になります。

mysql_servers =
(
    {
        address = "127.0.0.1"
        port = 3306
        weight = 1
        hostgroup = 0
        max_connections = 5
    },
    {
        address = "127.0.0.1"
        port = 3307
        weight = 2
        hostgroup = 0
        max_connections = 1
    },
)

設定確認

listenしているportに接続すればProxySQLの設定情報にアクセスすることができる。デフォルトだと6032とかになる模様

ProxySQL administration console prompt
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.30 (ProxySQL Admin Module)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

ProxySQLAdmin>

# サーバ一覧
Admin> select * from mysql_servers;

# 設定一覧
Admin> select * from global_variables where variable_name like '%monitor%';

# 各サーバの情報とか
Admin > SELECT hostgroup_id, hostname, status FROM runtime_mysql_servers;

Docker

hub.docker.com

proxysql/proxysqlで用意されていたのでサクッと触る分にはこれで良さそう。

気になったconfigとか

proxysql.com

この辺からピックアップ

設定値 説明
mysql-connect_retries_delay バックエンドMySQLサーバーへの試行が失敗した後、再接続を試行するまでの遅延
mysql-connect_retries_on_failure 接続の失敗につながるその他のイベントが発生した場合に再接続を試行する必要がある回数
mysql-connect_timeout_server バックエンドサーバーへの接続を1回試行した場合のタイムアウト
mysql-connect_timeout_server_max バックエンドに接続するための最大タイムアウト
mysql-default_max_latency_ms 待ち時間が長すぎる場合にバックエンドサーバーを自動的に無視する際のms