私の雇用主は、サービスとしてのソフトウェア条件でお客様に提供するWebアプリケーションを開発しました。大量のデータを持つ複数の顧客をデータベースに格納できるようにするために、アプリケーションでテナントごとにスキーマを作成することを選択しました。したがって、5人の顧客がいる場合、
mysql> show schemas;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| tenant_1a |
| tenant_d2 |
| tenant_yf |
| tenant_ok |
| tenant_8n |
+--------------------+
編集:数字と文字は、長さが約32文字のハッシュを表します。
テナントスキーマ名は実際には数値ではなく、作成中の特定の事実のハッシュです。したがって、作成されるまで実際には予測できません。これにより、クエリルールを事前に準備できなくなります。
現時点ではこれで問題はなく、maxscale readconnrouteバランサーの背後にある3つのノードのmariadb galeraクラスターのみを実行します。しかし、全体的にデータサイズがディスクに収まらない、またはテーブルの量がパフォーマンスを低下させるため、最終的にはこのクラスターにノードを追加することができないという障壁にぶつかります。
アプリケーションデータベースレイヤーの複雑さを低く保つために、開発者は、アプリケーションの観点から透過的なルーティングを処理することを望んでいます。アプリケーションがtalkに1つの「サーバー」だけでなく、どのテナントが物理的に配置されているかに注意してください。
アプリケーションクラスターを複数のmariadb galeraクラスターに拡張するには、maxscales schemarouterを使用して、接続されているすべてのサブクラスターのすべてのスキーマを、サーバーが1つしかないかのように公開できます。これは、開発者の期待に完全に適合します。
さて、数か月前、ProxySQLはデータベースプロキシの世界に入り、パフォーマンスの向上と他のものの間での柔軟性の向上を主張しています。
ハードコードされたスキーマ名に基づいてクエリをルーティングできますが、これはテナントが作成/削除されるたびにクエリを作成/更新することになるため、そうすることは控えます。
Maxscales schemarouterの動的な動作を、proxysqlクエリルールでどのように再現できますか?
あなたはここで答えを見つけることができます: proxysqlは複数のリスナーを持つことができますか? (Googleグループ)。
つまり、ProxySQLのクエリルールは、スキーマ名によるルーティングをサポートしています。
簡単にするために、3つの異なるクラスターがあり、HG11、HG21、HG31の3つのクラスターを呼び出すと仮定します。サーバーは10.10.X.Yです。いくつかの複雑さを追加するために、リーダーがHG12、HG22、HG32である読み取り/書き込みスプリットも有効にします。
INSERT INTO mysql_servers (hostgroup_id,hostname) VALUES
(11,"10.10.10.1"),
(12,"10.10.10.1"), (12,"10.10.10.2"), (12,"10.10.10.3"),
(21,"10.10.20.1"),
(22,"10.10.20.1"), (22,"10.10.20.2"), (22,"10.10.20.3"),
(31,"10.10.30.1"),
(32,"10.10.30.1"), (32,"10.10.30.2"), (32,"10.10.30.3");
レプリケーションホストグループを有効にする
INSERT INTO mysql_replication_hostgroups (writer_hostgroup,reader_hostgroup) VALUES
(11,12),(21,22),(31,32);
読み取り/書き込み分割のルールを作成する
INSERT INTO mysql_query_rules (rule_id, active, match_digest, flagOUT) VALUES
(1,1,'^SELECT.*FOR UPDATE',100),
(2,1,'^SELECT',200),
(3,1,'.*',100);
シャーディング、マスターへのトラフィックの送信
INSERT INTO mysql_query_rules (active, flagIN, schemaname, destination_hostgroup, apply) VALUES
(1,100, "shard001", 11, 1),
(1,100, "shard002", 11, 1),
(1,100, "shard003", 11, 1),
(1,100, "shard004", 11, 1),
...
(1,100, "shard050", 21, 1),
(1,100, "shard051", 21, 1),
(1,100, "shard052", 21, 1),
(1,100, "shard053", 21, 1),
(1,100, "shard054", 21, 1),
...
(1,100, "shard100", 21, 1),
(1,100, "shard101", 31, 1),
...
(1,100, "shard150", 31, 1);
シャーディング、トラフィックをスレーブに送信
INSERT INTO mysql_query_rules (active, flagIN, schemaname, destination_hostgroup, apply)
SELECT 1, 200, schemaname, destination_hostgroup+1 , 1 FROM mysql_query_rules WHERE flagIN=100;
すべてをランタイムにロードします。
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;
最終的に、すべてをディスクに保存します。
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL QUERY RULES TO DISK;
「どのスキーマがどのhg上にあるかという問題にproxysqlが対処する方法はありませんか?」について:答えはノーで、これは意図的なものです。各HGは同一のスキーマを持つ場合があります。従来の「mysql」、「information_schema」、「performance_schema」のほかに、他の目的(実際には何でも)に使用される他のスキーマを持つことができます。これらのスキーマを理解し、ルールを自動的に作成するようProxySQLに要求することはできません。
また、2つの異なるサーバーにtenant_1スキーマを作成した可能性がありますが、一方には本番データがあり、もう一方にはテストデータがあります。ProxySQLが両方を自動的に追加しないようにする必要があります。
最後に、ProxySQLは管理インターフェイスで実行される単純なSQLクエリを使用して簡単に再構成できるため、新しいスキーマのロードを自動化する場合は、各HGに接続し、スキーマをリストし、ProxySQLに接続してルールを作成するスクリプトを簡単に作成できます。欠落している場合。スクリプトは非常に単純にすることができますが、含める必要のないスキーマを除外するロジックも必要です。
または、Chef、Ansible、Puppet、Consulなどの構成管理ツールを使用して、ProxySQLにプッシュされる構成を作成することもできます。