Mysql

MaxScale schemarouter 的 ProxySQL 等價物

  • March 5, 2017

背景

我的雇主開發了一個 Web 應用程序,我們以軟體即服務條款向我們的客戶提供。為了允許將擁有大量數據的多個客戶儲存在數據庫中,我們選擇讓應用程序為每個租戶創建一個模式。因此,如果我們有 5 個客戶,我們就會有類似的東西

mysql> show schemas;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| tenant_1a          |
| tenant_d2          |
| tenant_yf          |
| tenant_ok          |
| tenant_8n          |
+--------------------+

編輯:數字和字母代表大約 32 個字元長的散列。

租戶模式名稱實際上不是數字,而是創建過程中某些事實的雜湊值。所以在創建之前並不是真正可預測的。這使我們無法提前準備查詢規則。

我們現在擁有/做什麼

現在我們對此很好,只在 maxscale readconnroute 平衡器後面執行三個節點的 mariadb galera 集群。但是我們最終會遇到一個障礙,在這個集群中添加節點是行不通的,因為整體數據大小不適合磁碟和/或表的數量會影響性能。

為了保持應用程序數據庫層的複雜性較低,我們的開發人員希望我們從應用程序的角度處理透明的路由:他們希望應用程序只與一個“伺服器”通信,而不關心哪個租戶位於何處身體上。

要將我們的應用程序集群擴展到多個 mariadb galera 集群,我們可以使用 maxscales schemarouter,它公開所有連接的子集群上的所有模式,就好像只有一台伺服器一樣。這完全符合我們開發人員的期望。

現在,幾個月前,ProxySQL 進入了數據庫代理領域,並聲稱具有更好的性能和更大的靈活性。

實際問題

我們可以根據硬編碼的模式名稱路由查詢,但不會這樣做,因為這意味著每次創建/刪除租戶時都要創建/更新它們。

如果有的話,我們如何使用 proxysql 查詢規則複製 maxscales schemarouter 的動態行為?

你可以在這裡找到答案:代理SQL可以有多個監聽器嗎?(Google組)。

簡而言之:ProxySQL 的查詢規則支持通過 schemaname 進行路由。

為簡單起見,假設您有 3 個不同的集群,我們將這 3 個集群稱為 HG11、HG21 和 HG31。伺服器是 10.10.XY 為了增加一些複雜性,我們還將啟用讀/寫拆分,其中讀取器是 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;

關於“沒有辦法讓 proxysql 自己處理哪個模式在哪個 hg 上的問題?” : 答案是否定的,這是故意的。每個 HG 可能具有相同的模式:除了經典的“mysql”、“information_schema”、“performance_schema”之外,您還可以擁有用於其他目的的其他模式(實際上是任何東西)。我們不能要求 ProxySQL 了解這些模式是什麼並自動創建規則。

此外,您可能在兩台不同的伺服器中創建了一個tenant_1 模式,但其中一台具有生產數據,而另一台具有測試數據:您不希望 ProxySQL 自動添加它們。

最後,因為 ProxySQL 可以使用在管理界面上執行的簡單 SQL 查詢輕鬆重新配置,如果您想自動載入新模式,您可以簡單地創建一個連接到每個 HG、列出模式並連接到 ProxySQL 的腳本來創建規則如果失去。該腳本可以非常簡單,但也應該具有排除不應包含的模式的邏輯。

或者,您可以使用 Chef、Ansible、Puppet、Consul 等配置管理工具創建推送到 ProxySQL 的配置。

引用自:https://dba.stackexchange.com/questions/165711