MySQL 8.0.19 支持 DNS SRV


MySQL Router 是 InnoDB Cluster 架構的訪問入口,在架構部署上,官方給出的建議是 router 與應用端綁定部署,避免 router 單點問題。

之前還有客戶諮詢,能否 router 不與應用端綁定部署,不便於部署,在此之前都需要在 router 前面加 VIP 或者一層負載均衡。

我還在想這事兒就應該由 MySQL Connector 來實現訪問鏈路的 Failover 和 Loadbalance, 現在有了 DNS SRV 的支持,router 不必和應用端綁定部署,也可以省了 VIP 和負載均衡,MySQL InnoDB Cluster 方案更加完善,配合 consul 等服務發現組件,更容易適配 service mesh 架構。

DNS SRV 是 DNS 記錄的一種,用來指定服務地址。SRV 記錄不僅有服務目標地址,還有服務的端口,並且可以設置每個服務地址的優先級和權重。


新特性解讀 | MySQL 8.0.19 支持 DNS SRV

MySQL Connector 8.0.19 覆蓋多種語言支持 DNS SRV,包括經典協議和 X 協議。遵循 RFC 2782 實現,支持 Priority 和 Weight 客戶端必須連接優先級值最低的可達地址,若優先級相同,權重值越大的訪問概率越高。

  • Connector/NET
  • Connector/ODBC
  • Connector/J
  • Connector/Node.js
  • Connector/Python
  • Connector/C++


我們來演示下應用是如何使用 DNS SRV 的,這裡使用 consul 做服務發現。


新特性解讀 | MySQL 8.0.19 支持 DNS SRV

1. consul agent 與 MySQL Router 部署在相同節點,檢查服務活性,並向 consul server 註冊服務信息。

2. 應用端的 Connector 配置了服務地址,訪問 DB 時先向 consul server 發起 DNS SRV 服務請求。

3. consul server 回覆應用端 MySQL Router 的服務地址和端口,應用端再去訪問 MySQL Router。


我在本機做了測試。

1. 首先使用 mysql shell 創建一組 InnoDB Cluster 集群

<code>for i in `seq 4000 4002`; do    echo "Deploy mysql  sandbox $i"    mysqlsh -- dba deploy-sandbox-instance $i --password=rootdoneecho "Create innodb cluster..."mysqlsh root@localhost:4000 -- dba create-cluster cluster01mysqlsh root@localhost:4000 -- cluster add-instance --recoveryMethod=clone --password=root root@localhost:4001mysqlsh root@localhost:4000 -- cluster add-instance --recoveryMethod=clone --password=root root@localhost:4002/<code>

2. 部署兩個 mysql router 作為訪問代理

<code>for i in 6446 6556; do    echo "Bootstrap router $i"    mysqlrouter --bootstrap root@localhost:4000 --conf-use-gr-notifications -d router_$i --conf-base-port $i --name router_$i    sed -i 's/level = INFO/level = DEBUG/g router_$i/mysqlrouter.conf    sh router_$i/stop.sh    sh router_$i/start.shdone/<code>

3. 安裝 consul 用作服務註冊和 DNS 解析,在測試環境我們使用開發模式,只部署一個 consul 節點,若用在生產環境需要部署多個 agent 和 server

<code>echo "Install consul..."brew install consulconsul agent -dev &/<code>

4. 在 consul 中註冊兩個 router 代理服務

<code>echo "Services register..."consul services register -name router -id router1 -port 6446 -tag rwconsul services register -name router -id router2 -port 6556 -tag rw/<code>

5. 測試下 DNS SRV 是否能正常解析,SRV 記錄的應答返回服務端口和服務地址,服務地址有對應的 A 記錄,是 127.0.0.1 地址。

<code>echo "Test dns srv..."dig router.service.consul SRV -p 8600;; QUESTION SECTION:;router.service.consul.        IN    SRV;; ANSWER SECTION:router.service.consul.    0    IN    SRV    1 1 6556 MBP.node.dc1.consul.router.service.consul.    0    IN    SRV    1 1 6446 MBP.node.dc1.consul.;; ADDITIONAL SECTION:MBP.node.dc1.consul.    0    IN    A    127.0.0.1MBP.node.dc1.consul.    0    IN    TXT    "consul-network-segment="MBP.node.dc1.consul.    0    IN    A    127.0.0.1MBP.node.dc1.consul.    0    IN    TXT    "consul-network-segment="/<code>

6. consul 的 DNS 服務端口是 8600,需要在本機設置 DNS 轉發,將應用對 consul 服務的 DNS 請求轉發到 consul 的端口,這裡我使用 dnsmasq 做本地轉發,對於生產環境可使用 BIND 服務。

<code>echo "Install dnsmasq..."brew install dnsmasqecho 'server=/consul/127.0.0.1#8600' > /usr/local/etc/dnsmasq.d/consulsudo brew services restart dnsmasq/<code>

7. DNS 轉發設置完成後,不指定 DNS 端口,測試轉發是否依然正常解析 SRV 記錄。

<code>echo "Test dns forwarding..."dig router.service.consul SRV/<code>

8. 安裝 python connector

<code>pip install mysql-connector-python/<code>

9. 在設置 connector 連接參數是注意 host 填寫在 consul 註冊的服務地址,並加上 dns_srv 參數,不需要指定端口。

<code>import mysql.connectorcnx = mysql.connector.connect(user='root', password='root', database='mysql_innodb_cluster_metadata', host='router.service.consul', dns_srv=True)cursor = cnx.cursor()query = ("select instance_id from v2_this_instance")cursor.execute(query)for (instance_id) in cursor:    print("instance id: {}".format(instance_id))cursor.close()cnx.close()/<code>

從 MySQL Router 日誌中可以看到請求以負載均衡方式發送到兩邊。


新特性解讀 | MySQL 8.0.19 支持 DNS SRV


分享到:


相關文章: