MySQL 读写分离和负载均衡

作者:禅与计算机程序设计艺术

1.简介

随着互联网网站流量的日益增长,越来越多的网站面临着数据库压力的挑战。单台服务器承载不了如此大的访问量,因此需要通过将数据库进行水平拆分,使得服务器能够同时处理更多的请求。一般情况下,MySQL主从复制就是一种实现读写分离的方法,即主服务器负责写入并同步到从服务器,从服务器只负责读取。但是由于主从复制存在延迟、异步复制等问题,导致在高并发场景下,性能较差。 为了解决MySQL主从复制的问题,提升数据库的处理能力,MySQL官方团队推出了一款名为mysql-proxy的开源软件作为中间件。它可以实现读写分离功能,从而达到减少数据库压力,提升数据库的处理能力的目的。本文将对mysql-proxy进行详细介绍,介绍其工作原理、配置方式及其具体优化方法。

2.读写分离

读写分离(Read Write Splitting)是数据库集群中常用的一种数据库优化策略,用来提高数据库服务器的处理能力。一般情况下,对于一个主库(Master),多个从库(Slave)之间按照某种策略分配负载,当某个查询语句需要访问主库时,就只发送给主库执行;而对于更新或插入语句,则会同时通知所有从库执行。这样做的好处主要有以下几个方面:

  1. 提高数据库服务器的处理能力:由于负载均衡,数据库的请求可以被分担到不同的数据库服务器上,从而提高整个数据库集群的处理能力。

  2. 提升数据库服务的可用性:当某个数据库服务器发生故障时,只影响到该服务器上的从库,其他的服务器依然可以提供正常服务。

  3. 增加容灾能力:当某个区域的数据库出现故障时,只需要关停该区域的服务器,其他的服务器仍可以提供正常服务。

  4. 降低主库的压力:由于所有的查询都只发送到主库,主库的压力就会减轻,数据库的响应速度也会更快。

MySQL读写分离的优点:

  1. 分担主库压力:读写分离后,主库的写入操作压力将减半,同时由于所有数据操作都通过从库执行,主库的压力大幅下降。

  2. 提升数据库处理能力:读写分离后,数据库的处理能力得到明显提高。

  3. 提升数据备份容灾能力:通过将主库的数据备份到从库,可以有效避免主库发生灾难性故障后丢失数据的风险。

3.mysql-proxy简介

mysql-proxy是由阿里巴巴集团开源的数据库中间件,具有以下特征:

  1. 支持读写分离:mysql-proxy能够实现数据库的读写分离功能,即可以把部分查询请求导向特定的从库,减轻主库的负载。

  2. 负载均衡:mysql-proxy支持基于连接和SQL解析两种负载均衡策略,能够自动识别负载不均衡的情况,并自动调整后端的连接池信息。

  3. 支持热切换:mysql-proxy可以在不停止服务的情况下动态地添加或者删除从库节点,实现读写分离的动态切换。

  4. 数据完整性保证:mysql-proxy采用binlog dump协议,将主库的数据变化实时同步到从库,保证数据的一致性。

  5. 协议兼容性强:mysql-proxy与原生MySQL客户端保持良好的兼容性,可以通过修改客户端的连接参数,直接连接mysql-proxy。

  6. 配置灵活:mysql-proxy支持配置文件热加载,允许在运行过程中动态修改配置信息,实现无缝切换。

4.mysql-proxy安装部署

4.1 安装编译环境

如果你的系统没有安装gcc或make工具,请先安装,然后再安装mysql-proxy源码包。

yum install -y gcc make

4.2 下载源代码

mysql-proxy的最新版本是1.9,我们也可以选择其它版本进行下载,然后进行编译安装:

wget https://github.com/mysql-net/MySqlConnector/releases/download/v1.3.14/mysql-connector-net_1.3.14.tar.gz
tar zxvf mysql-connector-net_1.3.14.tar.gz && cd mysql-connector-net_1.3.14/
./build.sh
cp MySqlConnector.dll /usr/local/lib/

4.3 配置文件说明

安装完成后,进入/etc/myproyx/目录下,查看my.ini文件。其中的关键信息如下:

[server]
# server_id is used to identify this proxy instance among a set of proxies
server_id = 1

[mysql]
host=127.0.0.1 # 连接到的MySQL主机地址,通常设置为master节点的IP地址
port=3306 # MySQL端口号
user=root # 登录用户名
password=<PASSWORD> # 登录密码
schema=test # 设置默认的数据库名

[readconnroute]
# readconnroute specifies the destination of SELECT queries
rule1=slave|localhost:3306|test

[writeconnroute]
# writeconnroute specifies the destination of INSERT, UPDATE and DELETE queries
rule1=master|localhost:3306|test

[app]
enable_heartbeat=true # 是否开启心跳检测功能

其中,host字段指定的是连接到哪个MySQL节点,通常设置为主节点的IP地址,port字段指定的是MySQL的端口号,userpassword分别用于登录MySQL的用户名和密码,schema用于设置默认的数据库名。readconnroutewriteconnroute两个子项分别定义了SELECT和INSERT/UPDATE/DELETE语句的目标节点,格式为:{类型}|{IP}:{端口}|{数据库名称}。这里我们需要关注的是rule1,表示匹配规则的第1条。它的前面部分slave表示类型,表示该条规则应用于SELECT请求;后面的localhost:3306表示目标节点,即将发往master节点的请求转发至这个地址;第三个参数test表示将请求发送到哪个数据库(我们设置的默认数据库)。其他子项包括:

  • charset: 指定字符编码格式。
  • sqlblacklist: 可以指定某些SQL语句禁止发送到从库。
  • tls: 配置TLS加密传输。

4.4 启动mysql-proxy

启动mysql-proxy:

/usr/local/mysql-proxy/bin/myproyx --defaults-file=/etc/myproyx/my.ini

若出现异常日志,可根据提示排查错误原因。启动成功后,可以在命令行窗口看到相关信息,代表已经正常运行。

4.5 测试

4.5.1 查看主从状态

首先我们通过mysql命令行工具查看主从状态:

mysql -h 127.0.0.1 -P 3306 -u root -p123456 -e "show slave status\G"

若返回结果中Seconds_Behind_Master的值不是NULL,则表明当前的主从复制状态正常。

4.5.2 查询数据

接下来我们测试读写分离的效果是否正确。首先打开另一个窗口,连接到mysql-proxy所在机器:

mysql -h 127.0.0.1 -P 4040 -u root -p123456 -D test

注意要指定连接到4040端口,而不是3306端口。然后尝试运行一些简单的查询和插入语句:

-- 查询数据
select * from users where id=1;

-- 插入数据
insert into users (name, age) values ('Tom', 25);

可以看到,所有的查询都只会发送到主库执行,而所有插入语句都会同时发送到主库和从库执行。我们可以重复这个过程,验证读写分离的效果。

猜你喜欢

转载自blog.csdn.net/universsky2015/article/details/133504780