点击蓝字关注我们
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 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做服务发现。
consul agent与MySQL Router部署在相同节点,检查服务活性,并向consul server 注册服务信息。
应用端的Connector配置了服务地址,访问DB时先向consul server发起DNS SRV服务请求。
consul server回复应用端 MySQL Router的服务地址和端口,应用端再去访问MySQL Router。
我在本机做了测试。
1. 首先使用mysql shell创建一组InnoDB Cluster集群
for i in `seq 4000 4002`; do
echo "Deploy mysql sandbox $i"
mysqlsh -- dba deploy-sandbox-instance $i --password=root
done
echo "Create innodb cluster..."
mysqlsh root@localhost:4000 -- dba create-cluster cluster01
mysqlsh root@localhost:4000 -- cluster add-instance --recoveryMethod=clone --password=root root@localhost:4001
mysqlsh root@localhost:4000 -- cluster add-instance --recoveryMethod=clone --password=root root@localhost:4002
2. 部署两个mysql router作为访问代理
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.sh
done
3. 安装 consul用作服务注册和DNS解析,在测试环境我们使用开发模式,只部署一个consul节点,若用在生产环境需要部署多个agent和server
echo "Install consul..."
brew install consul
consul agent -dev &
4. 在consul中注册两个router代理服务
echo "Services register..."
consul services register -name router -id router1 -port 6446 -tag rw
consul services register -name router -id router2 -port 6556 -tag rw
5. 测试下DNS SRV是否能正常解析,SRV记录的应答返回服务端口和服务地址,服务地址有对应的A记录,是127.0.0.1地址。
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.1
MBP.node.dc1.consul. 0 IN TXT "consul-network-segment="
MBP.node.dc1.consul. 0 IN A 127.0.0.1
MBP.node.dc1.consul. 0 IN TXT "consul-network-segment="
6. consul的DNS服务端口是8600 ,需要在本机设置DNS 转发,将应用对consul服务的DNS请求转发到consul的端口,这里我使用dnsmasq做本地转发,对于生产环境可使用BIND服务。
echo "Install dnsmasq..."
brew install dnsmasq
echo 'server=/consul/127.0.0.1#8600' > /usr/local/etc/dnsmasq.d/consul
sudo brew services restart dnsmasq
7. DNS转发设置完成后,不指定DNS端口,测试转发是否依然正常解析SRV记录。
echo "Test dns forwarding..."
dig router.service.consul SRV
8. 安装 python connector
pip install mysql-connector-python
9. 在设置connector连接参数是注意host填写在consul注册的服务地址,并加上dns_srv参数,不需要指定端口。
import mysql.connector
cnx = 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()
从MySQL Router 日志中可以看到请求以负载均衡方式发送到两边。
叶老师新课程《MySQL性能优化》已经在腾讯课堂发布,本课程讲解读几个MySQL性能优化的核心要素:合理利用索引,降低锁影响,提高事务并发度。下面是报名小程序码,厚着脸皮请求大家推荐给需要的小伙伴们。
下面是本课程内容目录
扫码加入MySQL技术Q群
(群号:650149401)
点“在看”给我一朵小黄花