自动读写分离
目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压力,可以创建一个或多个只读实例,利用只读实例满足大量的数据库读取需求。但此类解决方案需要业务侧支持读写分离改造,其代码的健壮性决定了业务读写分离的质量,对用户的技术要求较高,而且灵活性和可扩展性较差。 故创建只读实例后,可以通过开通数据库代理,配置访问地址策略,然后在应用程序中配置数据库代理地址,使写请求自动转发到主实例,读请求自动转发到各个只读实例。数据库代理除了具备自动读写分离功能,也能为其他业务痛点提供更好的解决方案。
使用数据库代理MySQL-Proxy,用户可以构建可透明容忍数据库故障转移(主动/被动)的应用程序,而无需编写复杂的故障处理代码。数据库代理自动将读流量路由到新的数据库实例,同时保留应用程序连接。
功能优势
1、自助读写分离,统一访问地址。
2、原生链路支持,提升性能,减少维护成本。
3、可设权重和阈值,可供用户灵活选择。
4、具备故障转移能力,即使数据库代理故障请求也能正常访问主库。
5、主实例发生切换、变配、只读实例增减等情况,数据库代理可动态热加载配置,不会出现网络中断或重启。
数据库代理实现读写分离架构
一、Mysql-Proxy原理
github 地址:
https://github.com/mysql/mysql-proxy
Mysql-Proxy是一个处于client端和Mysql Server端之间的一个简单程序,它可以监测、分析和改变他们的通信。它使用灵活没有限制,常见的用途包括:负载平衡,故障、查询分析,查询过滤和修改等等。
Mysql -Proxy就是这么一个中间层代理,简单的说,Mysql-Proxy就是一个连接池,负责将前台应用的请求转发给后台数据库,并且通过使用lua脚本,可以实现复杂的连接控制和过滤,从而实现读写分离和负载平衡。对于应用来说,MySQL Proxy是完全透明的,应用则只需要连接到MySQL Proxy的监听端口即可。当然,这样proxy机器可能成为单点失效,但完全可以使用多个proxy机器做为冗余,在应用服务器的连接池配置中配置到多个proxy的连接参数即可。
读写分离路由规则
发送到主实例
1、CREATE、ALTER、DROP、RENAME 等 DDL 语句。
2、INSERT、UPDATE、DELETE 等 DML 语句。
3、SELECT FOR UPDATE 语句。
4、临时表相关语句。
5、部分系统函数调用(如 last_insert_id())以及所有自定义函数调用。
6、LOCK 相关语句。
7、开启事务后的语句(包括 set autocommit=0)。
8、存储过程。
9、用“;”连接的多语句。
10、KILL(SQL 语句中的 KILL,非命令 KILL)。
11、所有对用户变量的查询和更改。
发送到只读实例
1、事务外的读(SELECT)语句。
发送到所有实例
1、show processlist 语句。
2、所有系统变量的更改(SET 命令)。
3、USE 命令。
栗子
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
dynamic:
primary: user
strict: false
datasource:
user:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.12:3306/user?zeroDateTimeBehavior=convertToNull&autoReconnect=true&generateSimpleParameterMetadata=true
username: **********
password: **********
druid:
# 初始化大小,最小,最大
initial-size: 10
min-idle: 10
max-active: 64
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存时间
min-evictable-idle-time-millis: 300000
validation-query: select 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
# 配置获取连接等待超时的时间
max-wait: 60000
地址
jdbc:mysql://127.0.0.12:3306/user?zeroDateTimeBehavior=convertToNull&autoReconnect=true&
generateSimpleParameterMetadata=true为连接代理服务器,对程序端是透明的,和连接正常MySQL服务器是一样的。