ProxySQL-別のmysql-proxy

SQLクエリをプロキシするためのこのツールはハブで複数回言及されましたが、残念ながら、その作業を説明する記事が1つも見つかりませんでした。さらに、ロシア語のドキュメントも見つかりませんでした。 それでは、このギャップを埋めてみましょう。 この記事では、ProxySQLの構造、構成、および使用例を見ていきます。


ProxySQLとは何ですか?
これは、MariaDBやPerconaなどのMySQLフォークのデータベースにSQLクエリをプロキシするためのアプリケーションです(将来、開発者は他のさまざまなデータベースのサポートを追加することを約束しています)。 別のデーモンとして機能し、プロキシする必要があるすべてのSQLクエリが処理されます。次に、事前定義されたルールに従って、デーモンは必要なMySQLサーバーに接続してクエリを実行し、その後結果をアプリケーションに返します。 ProxySQLは、パターンに従って着信クエリを変更することもできます。

ProxySQLのアーキテクチャ
ProxySQLはかなり複雑ですが、システムの構成が簡単です。


これは、3つの層に分割された多層構成システムを使用して実現されます。

画像

ランタイム層-この構成層はProxySQLデーモンによって直接使用され、クエリをプロキシするためのすべての構成情報が含まれています。

レイヤーメモリ-またはメインレイヤーは、メモリ内にあるSQLite3データベースであり、構成情報と構成自体を提供するために使用されます。 設定は、SQLコマンドを使用して標準のMySQLクライアントを介して行われます。

レイヤーディスク-これは通常のSQLite3ファイルで、メモリーレイヤーを介して入力された(ユーザーによる)データが保存されます

確認 file-ProxySQL構成ファイル(proxysql.cnf)は初期化時に使用され、SQLite3データベースの検索に関する情報、管理インターフェースに関する情報、およびデーモンの初期構成が含まれます。

レイヤー間で構成を移動するための管理コマンドがいくつかあります。

メモリ(レイヤー2)とランタイム間でユーザー構成(USERS)を移動するには:
MySQL [(none)]> LOAD MYSQL USERS FROM MEMORY MySQL [(none)]> LOAD MYSQL USERS TO RUNTIME 


ランタイムからメモリへ:
 MySQL [(none)]> SAVE MYSQL USERS TO MEMORY MySQL [(none)]> SAVE MYSQL USERS FROM RUNTIME 


ディスク(レイヤー3)からメモリへ
 MySQL [(none)]> LOAD MYSQL USERS TO MEMORY MySQL [(none)]> LOAD MYSQL USERS FROM DISK 


メモリ(レイヤー2)からディスク(レイヤー3)へ
 MySQL [(none)]> SAVE MYSQL USERS FROM MEMORY MySQL [(none)]> SAVE MYSQL USERS TO DISK 


ディスク(レイヤー3)からメモリ(レイヤー2)へ
 LOAD MYSQL USERS FROM CONFIG 


他のテーブル/変数についても同じ方法で移動できます。 利用可能なリスト:
クエリルール-プロキシのクエリ。
変数-MySQLサーバーの変数と管理設定。

設置
このアプリケーションは非常に新しく、開発中であるため、最良のオプションはソースコードから収集することです。これはgithub: github.com/sysown/proxysqlで入手できます。
RedHat(CentOS)およびDebian(Ubuntu)用にバイナリパッケージがコンパイルされました: github.com/sysown/proxysql/releases

CentOS 7のパッケージをインストールします。
 rpm -ihv https://github.com/sysown/proxysql/releases/download/v1.2.0i/proxysql-1.2.0-1-centos7.x86_64.rpm 


インストール後、conf。 ファイルは/etc/proxysql.cnfにあります
お気に入りのエディターで開きます。

 datadir="/var/lib/proxysql" admin_variables= { admin_credentials="admin:admin" #     mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock" #      refresh_interval=2000 #      debug=true admin-stats_credentials=stats:stats #    .   ( ) } mysql_variables= { threads=4 #      max_connections=2048 #  ,     . default_query_delay=0 default_query_timeout=36000000 have_compress=true #     poll_timeout=2000 interfaces="127.0.0.1:3306;/tmp/proxysql.sock" default_schema="information_schema" stacksize=1048576 #        backend-. server_version="5.1.30" connect_timeout_server=10000 monitor_history=60000 monitor_connect_interval=200000 monitor_ping_interval=200000 ping_interval_server=10000 ping_timeout_server=200 commands_stats=true sessions_sort=true } 


datadir-SQLite3データベースファイルの場所、デフォルト/ var / lib / proxysql
admin_variables-管理インターフェイスの設定
mysql_variables-着信mysqlクエリサーバーのグローバル変数が含まれます。

mysqlインターフェースを介してバックエンドサーバーとその他の設定を追加します。

最初の起動と初期化
設定を初期化します。

初期化は、confからサーバー設定を転送します。 ファイル(レイヤー3)をメモリ(レイヤー2)のSQLite3データベースに保存し、メモリー(レイヤー2)に保存されたすべての設定をリセットし、ファイルをディスク(レイヤー3)に名前変更します。
 proxysql --initial 


オンザフライでProxySQLを構成する(ランタイム)
その場でProxySQLを設定するには、標準のmysqlクライアントを使用します。

 mysql -h 127.0.0.1 -P6032 -uadmin -p Enter password: MySQL [(none)]> 


これで管理者になりました。 インターフェース。 どんなテーブルがあるのか​​見てみましょう:
 MySQL [(none)]> show tables; +--------------------------------------+ | tables | +--------------------------------------+ | global_variables | | mysql_collations | | mysql_query_rules | | mysql_replication_hostgroups | | mysql_servers | | mysql_users | | runtime_mysql_query_rules | | runtime_mysql_replication_hostgroups | | runtime_mysql_servers | | runtime_scheduler | | scheduler | +--------------------------------------+ 11 rows in set (0.00 sec) 


mysql_servers-バックエンドサーバーのリストを含む
mysql_users-ProxySQLおよびバックエンドサーバーにアクセスできるすべてのユーザーのリストが含まれます。
mysql_query_rules-プロキシを通過するSQlクエリをキャッシュ、リダイレクト、置換するためのすべてのルール。
global_variables-ProxySQL MySQLサーバーのグローバル変数(構成ファイルで構成した)と管理設定が含まれます。
mysql_replication_hostgroups-クエリルールが順番に適用されるバックエンドが接続されるホストグループのリスト。
mysql_query_rules-プロキシルールのクエリ。

バックエンドを追加しますが、最初に、mysql_servers、mysql_replication_hostgroups、およびmysql_query_rulesテーブルが空であることを確認してください。
 MySQL [(none)]> SELECT * FROM mysql_servers; Empty set (0.00 sec) MySQL [(none)]> SELECT * from mysql_replication_hostgroups; Empty set (0.00 sec) MySQL [(none)]> SELECT * from mysql_query_rules; Empty set (0.00 sec) 


実際、必要なテーブルは空です。 追加する前に、プロキシの対象と場所を決定する必要があります。2台のサーバーを追加し、1台は書き込み(INSERT、UPDATEなど)、2台目はデータの読み取り(SELECT)のみを行います。異なるサーバー間で読み取り/書き込みを分散するスレーブ。 これを行うには、2つのホストグループを作成します。

バックエンドサーバーを追加します。
データベースに書き込み、ホストグループ1にある最初のサーバー:
 MySQL [(none)]> INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (0,'192.168.100.2',3307); 


2番目のサーバーはスレーブ用に構成されており、読み取りのみを行い、グループ2に配置します。
 MySQL [(none)]> INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (1,'192.168.100.3',3307); Query OK, 1 row affected (0.01 sec) MySQL [(none)]> SELECT * FROM mysql_servers; +--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+ | hostgroup_id | hostname | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | +--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+ | 0 | 192.168.100.2 | 3307 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | 1 | 192.168.100.3 | 3307 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | +--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+ 2 rows in set (0.00 sec) 


mysql_replication_hostgroupsテーブルには2つのフィールドがあり、最初のフィールドはwriter_hostgroupです。これには、ホストが書き込まれるグループの番号が含まれます。 reader_hostgroupで-読み取り用。
2つのホストグループ(1,2)をmysql_replication_hostgroupsテーブルに追加します。
 MySQL [(none)]> INSERT INTO mysql_replication_hostgroups VALUES (1,2); Query OK, 1 row affected (0.00 sec) MySQL [(none)]> SELECT * FROM mysql_replication_hostgroups; +------------------+------------------+ | writer_hostgroup | reader_hostgroup | +------------------+------------------+ | 1 | 2 | +------------------+------------------+ 1 row in set (0.00 sec) 


次に、バックエンドサーバーとホストグループに関するデータをメモリからランタイムに転送して、それらがすぐに有効になるようにします。
 MySQL [(none)]> LOAD MYSQL SERVERS TO RUNTIME; Query OK, 0 rows affected (0.00 sec) 


データをディスク(レイヤー3)に保存します。
 MySQL [(none)]> SAVE MYSQL SERVERS TO DISK; Query OK, 0 rows affected (0.00 sec) 


クエリをプロキシするためのルールを追加します。これには、テーブルmysql_query_rulesがあります。
テーブルの構造は次のとおりです。
 CREATE TABLE mysql_query_rules ( rule_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 0, username VARCHAR, schemaname VARCHAR, flagIN INT NOT NULL DEFAULT 0, match_pattern VARCHAR, negate_match_pattern INT CHECK (negate_match_pattern IN (0,1)) NOT NULL DEFAULT 0, flagOUT INT, replace_pattern VARCHAR, destination_hostgroup INT DEFAULT NULL, cache_ttl INT CHECK(cache_ttl > 0), reconnect INT CHECK (reconnect IN (0,1)) DEFAULT NULL, timeout INT UNSIGNED, delay INT UNSIGNED, apply INT CHECK(apply IN (0,1)) NOT NULL DEFAULT 0 ) 

rule_id-ルール番号
アクティブ-ルールは有効、0-オフ
ユーザー名とスキーマ名-NULL以外の場合、ルールは、接続のユーザー名/スキーマ名の一致が正しい場合にのみ実行されます
flagIN、flagOUT、適用-これらのフラグにより​​、「ルールのチェーン」を作成できます。 実際には、私はまだそれらを使用する必要はありませんでしたので、今のところ公式文書から元のテキストを提供します。誰かが正しく明確に翻訳できる場合はお願いします。 これらにより、次々に適用される「ルールのチェーン」を作成できます。 入力フラグ値は0に設定され、flagIN = 0のルールのみが最初に考慮されます。 特定のクエリに一致するルールが見つかると、flagOUTが評価され、NOT NULLの場合、flagOUTで指定されたフラグでクエリにフラグが立てられます。 flagOUTがflagINと異なる場合、クエリは現在のチェーンを終了し、flagINを新しい入力フラグとして持つ新しいルールチェーンに入ります。 これは、一致するルールがなくなるか、applyが1に設定されるまで発生します(つまり、これが最後に適用されるルールです)
match_pattern-正規表現。その下にあるルールがプロキシされます。
replace_pattern-プロキシされたリクエストまたはその一部を置き換える正規表現。
destination_hostgroup-ルールが適用されるグループのホスト番号。
cache_ttl-リクエストがキャッシュされる秒数。
再接続-まだ使用されていません
timeout-match_patternまたはreplace_patternを実行するためのタイムアウト。リクエストにさらに時間がかかる場合、強制終了されます。
delay-バックエンド要求が実行されるまでの遅延。たとえば、SELECT要求がINSERT / UPDATEの直後に複製のための時間を与える場合に役立ちます。

mysql_query_rulesテーブルに3つのルールを追加します
 MySQL [(none)]> INSERT INTO mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) VALUES(1,1,'^SELECT .* FOR UPDATE$',1,1); MySQL [(none)]> INSERT INTO mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) VALUES(1,1,'^SELECT',2,1); MySQL [(none)]> INSERT INTO mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) VALUES(1,1,'.*',1,1); 


最初のルールは、すべてのSELECT UPDATEクエリをマスターサーバーにリダイレクトします
2番目のルールは、すべてのSELECTスレーブサーバーリクエストをリダイレクトします
最後に、3番目のルールは他のすべての要求をマスターサーバーにリダイレクトします。

ユーザー
次に、mysql_usersテーブルにユーザーを追加します。 ProxySQLには、接続されているすべてのサーバーに存在するすべてのユーザーが必要です。 両方のホストグループのルートユーザーを追加する要求:
 MySQL [(none)]> INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('root','password',1); Query OK, 1 row affected (0.00 sec) MySQL [(none)]> INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('root','password',0); Query OK, 1 row affected (0.00 sec) 


変更をランタイムに転送し、ディスクに保存します。
 MySQL [(none)]> LOAD MYSQL USERS FROM MEMORY MySQL [(none)]> LOAD MYSQL USERS TO RUNTIME MySQL [(none)]> SAVE MYSQL USERS FROM MEMORY MySQL [(none)]> SAVE MYSQL USERS TO DISK MySQL [(none)]> LOAD MYSQL QUERY RULES FROM MEMORY MySQL [(none)]> LOAD MYSQL QUERY RULES TO RUNTIME MySQL [(none)]> SAVE MYSQL QUERY RULES FROM MEMORY MySQL [(none)]> SAVE MYSQL QUERY RULES TO DISK 


おわりに
上記の手順の後、Master-Slaveレプリケーション用にProxySQLを構成しました。 もちろん、これはProxySQLのすべての機能ではありません。とりわけ、すべてのバックエンド、そしてもちろんそれ自体の優れた監視を実行できます。

参照:
オフサイト: http : //www.proxysql.com/
オフ。 ドキュメント: https : //github.com/sysown/proxysql/tree/master/doc
ProxySQLを使用してマスタースレーブレプリケーションを構成し、構成ファイルから構成する: http ://unix-admin.su/scalable-mysql-cluster/

Source: https://habr.com/ru/post/J303612/


All Articles