分布式架构MySQL读写分离技术

你可以一无所有,但绝不能一无是处。

mysql读写分离

MySQL读写分离原理

MySQL的主从复制和MySQL的读写分离两者有着紧密联系,首先部署主从复制,只有主从复制完了,才能在此基础上进行数据的读写分离。

简单来说,读写分离就是只在主服务器上写,只在从服务器上读,基本的原理是让主数据库处理事务性查询,而从数据库处理select查询,数据库复制被用来把事务性查询导致的改变更新同步到集群中的从数据库。

一月

人生就是这样,

带着笑去面对所有事,

上帝才会给你好运。

这就是典型的并发问题,单机数据库承担了太多的请求,导致作者无法提交编辑的内容。一个直觉的想法是,多加几台服务器,把压力分担到多台服务器上,但是这样会带来一个问题,多台数据库之间的数据同步,这是一个很复杂的问题,一个简化的方案是主从结构 - 一台主库负责写,多台从库负责读,这样数据同步方案就会变得简单,让所有的从库及时从主库同步数据即可。而这正是前面介绍的 - MySQL主从复制(BinaryLog)。

在实现上有两种方式:

应用层实现 在应用层,比如使用SpringJDBC/myBatis/Hibernate访问数据库时配置多数据源,这些组件会通过算法把请求分流到不同的数据源。

代理实现 这种方式是在应用层和数据库集群之间添加一个代理服务,应用层访问代理,代理根据请求类型(读/写)自动分流到不同的数据库服务器。

下面简单的介绍这两种方案:

应用层实现

基于应用层实现的读写分离拓扑结构如下图,这种方式在Web层已经决定了读写的方向,所有的写操作写到Master,所有的读操作按一定算法分流到不同的Slave服务器。

基于这种方案的实现,由于应用框架的不同实现方式各不相同,在基于SpringJDBC的框架一种简单的方式,就是定义多个数据库连接,一个MasterDataSource和一个SlaveDataSource。更新数据时我们读取MasterDataSource,查询数据时我们读取SlaveDataSource。

这种做法在只有一个从库(Slave)的情况下还好说,但是有多个从库的时候就不好办了。解决的办法也很多,比如集成 AbstractRoutingDataSource 自己实现算法。

下面给出一些链接,包含其他组件的配置:

Spring 实现数据库读写分离

Spring多数据源的配置和使用

Spring加Mybatis实现MySQL数据库主从读写分离

Read/Write splitting Hibernate

在应用层实现读写分离不需要做底层复杂的配置,而且性能比较好,但是对应用的侵入性比较强,不利于扩展。而代理实现完全屏蔽了读写分离的细节,从工程上讲,这是比较好的一种实现方式。

代理实现

代理实现的拓扑结构大概如下图,Web请求集中到单一的数据源(代理),但是代理会重新根据读/写不同,把请求分流到不同的数据服务器。

MySQL-Proxy MySQL官方提供的一个基于代理的负载均衡,可以理解SQL语言,在接收到SQL请求后,会根据请求类型自动把请求分流到Master和Slaves。

注:MySQL-Proxy现在是Alpha版本,不建议在生产环境使用

安装

MySQL-Proxy提供多种安装方式,比较推荐的还是通过官方提供的二进制文件安装(在不支持的平台上,再考虑自己通过源码编译安装)。

shell> cd /usr/local

shell> tar zxf mysql-proxy-0.8.5-platform.tar.gz

安装后可以把 $MYSQL-PROXY-DIR/bin 目录添加到环境变量,方便使用。主要使用 mysql-proxy 命令,这个命令可以用来启动SQL代理,比如:

> mysql-proxy --proxy-backend-addresses 192.168.0.1:3306 --proxy-backend-addresses 192.168.0.2:3306

同时设定了主库和从库的地址,这个命令可以使用多次,从而设置多个从库地址(mysql-proxy有好多参数没有仔细研究)。

也可以这样使用:

> mysql-proxy --proxy-backend-addresses=MySQL.example.com:3306

仅仅把SQL代理作为一个普通的代理服务使用。

MySQL-Proxy的工作模式其实并不仅仅这样,它可以通过lua脚本实现更多复杂的逻辑,这样可以更精确的控制代理服务的行为。关于如何利用lua脚本来控制代理行为,最好是参见文档,

这里面提供了一些基础的系统方法,通过这些方法可以组合出复杂的路由分发逻辑。

MySQL-Proxy目前还在Alpha阶段,官方并不建议在生产环境使用,并且网络上普遍评论不够稳定,并且性能也不高。所以不太想做太详细的介绍。目前用的比较多的是HAProxy ,它工作在传输层(TCP/IP),不会直接解释SQL语言,所以在性能上会比MySQL-Proxy高很多,而且在真实环境中用的比较多。

HAProxy在使用方式上和MySQL-Proxy略有区别,它要求在应用层做读写分离,并需要给HAProxy分别配置读/写端口,一个用来做写操作,一个用来做读操作。然后在应用层还需要做一点修改,这又回到了最开始的的应用层做读写分离的情况,唯一的区别是这里把情况由原来的一写多读变成了一写一读。

那么再考虑我们最开始的解决方案 - 复杂的负载均衡处理。这种方案的缺点是所有的数据库节点都是同等的,多个节点之间的同步是比较复杂的,但是庆幸的是,这些问题已经有了很多好的解决方案,比如 MySQL CLUSTER 或者 GALERA CLUSTER,这些集群方案完全屏蔽了复杂的读写分离设计,对外的开发接口是简单统一的。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180129G0RKG100?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券