您好,欢迎访问一九零五行业门户网

使用MySQL Proxy解决MySQL主从同步延迟

mysql的主从同步机制非常方便的解决了高并发读的应用需求,给web方 面开发带来了极大的便利。但这种方式有个比较大的缺陷在于mysql的同步机制是依赖slave主动向master发请求来获取数据的,而且由于服务器负 载、网络拥堵等方面的原因,master与slave之间的数
mysql的主从同步机制非常方便的解决了高并发读的应用需求,给web方 面开发带来了极大的便利。但这种方式有个比较大的缺陷在于mysql的同步机制是依赖slave主动向master发请求来获取数据的,而且由于服务器负 载、网络拥堵等方面的原因,master与slave之间的数据同步延迟是完全没有保证的。短在1秒内,长则几秒、几十秒甚至更长都有可能。
由于数据延迟问题的存在,当应用程序在master上进行数据更新,然后又立刻需要从数据库中读取数据时,这时候如果应用程序从slave上取数据(这也是当前web开发的常规做法),就可能出现读取不到期望的数据,造成程序运行异常。
解决这个问题有多种方式,比如最简单的在所有的insert和update之后,强制sleep几秒钟。这是非常粗鲁的方式,对于更新操作不是很高的中小型系统,此方式基本能解决问题。
另外一种方式是应用程序把被更新的数据保存在本机的内存(或者集中式缓存)中,如果在写入数据完成后需要直接读取数据,则从本机内存中读取。这种方式的缺点是极大的增加了应用程序的复杂度,而且可靠性并不能完全得到保障。
使用mysql proxy可以很方便的解决这个问题。mysql proxy是基于mysql client 和 mysql server之间的代理程序,能够完成对client所发请求的监控、修改。从client角度看,通过proxy访问server和直接访问server没有任何区别。对于既有的程序而言,只要把直接被访问的server的ip地址和端口号换成proxy的ip地址和端口号就可以。
mysql proxy的工作原理也较简单。在proxy启动时可以指定proxy所需要使用的lua脚本,在lua脚本中预先实现6个方法:
connect_server() // 接收到client的连接请求时调用
read_handshake() //
read_auth() // 读取client的认证信息时调用
read_auth_result() // 读取认证结果时调用
read_query() // 读取client的query请求时调用
read_query_result() //读取query结果时调用
当proxy接收到client请求时,在请求的不同的阶段会调用上面的不同方法。这样proxy使用者就可以根据自己的业务需求,自由的实现这6个方法达到目的。
通过在read_query()中加入代码,我们可以截取出当前的请求是insert、update还是select,然后把insert和update请求发送到master中,把select请求发送到slave中,这样就解决了读写分离的问题。
在解决了读写分离后,如何解决同步延迟呢?
方法是在master上增加一个自增表,这个表仅含有1个的字段。当master接收到任何数据更新的请求时,均会触发这个触发器,该触发器更新自增表中的记录。如下图所示:
由于count_table也参与mysq的主从同步,因此在master上作的update更新也会同步到slave上。当client通过proxy进行数据读取时,proxy可以先向master和slave的count_table表发送查询请求,,当二者的数据相同时,proxy可以认定master和slave的数据状态是一致的,然后把select请求发送到slave服务器上,否则就发送到master上。如下图所示:
通 过这种方式,就可以比较完美的结果mysql的同步延迟不可控问题。之所以所“比较完美”,是因为这种方案double了查询请求,对master和 slave构成了额外的压力。不过由于proxy与真实的mysql server采用连接池的方式连接,因此额外的压力还是可以接受的。
其它类似信息

推荐信息