relay fetch解决MySQL主从复制延迟

来源:互联网 发布:snh48真百合成员知乎 编辑:程序博客网 时间:2024/05/20 14:17
 
Mysql复制单线程的本质意味着从服务器效率的降低,即使从服务器有很多磁盘、cpu、和内存,也很容易落后于主服务器,因为从服务器的单线程只能有效的使用一个cpu和磁盘。
 
从服务器上的锁定也是一个问题,运行在从服务器上的另外的查询也会加锁并阻塞复制线程。复制是单线程,复制线程(sql_thread)除了等待也不能做别的事情。
 
为了解决这个问题,业界开发了一些补丁解决这类问题,一个思路是由复制单线程改进为多线程。另外一种是在从服务器上通过并行IO把数据预先提取到内存中,这里我们着重介绍第二种。
 
这个主意的想法是通过程序,让他比从服务器的sql线程稍微提前一点在中继日志中读取到查询语句,并将其作为select语句来执行,这导致服务器把一些数据从磁盘读取到内存,因此当从服务器的sql线程从中继日志中执行命令的时候,它就不需要等待从磁盘读取数据。Select并行处理从服务器必须串行处理的I/O。
 
程序应该在sql线程前多久执行这个是要确定的问题。提前太多,提取到缓存到的数据会被清空。可以尝试几秒钟,或者中继日志中相同的字节数
 
IO密集型从服务器利用这个方案将取得明显效果。
 
广泛分布的单行update命令和delete命令操作,数据预热效果明显,大批量的insert命令可能不会有太大明显提高。
 
 
基本原理 
 
在备库sql线程执行更新之前,预先将相应的数据加载到内存中,并不能提高sql_thread线程执行sql的能力,也不能加快io_thread线程读取日志的速度。
 
 
限制
 
  1 目前仅支持主库binlog ROW模式
 
  2 表需要有主键或唯一索引
 
  3 忽略test和mysql数据库
 
  4 如果数据库中存在类似tbname_1、tbname_2这样命名的多个表,但其表模式却不相同时,请加上-t选项,例如:tb_1 tb_2 tb_3这样命名的三个表,默认情况下,被认为是同样模式的表,这个特点是淘宝为了适应他们自己的数据库环境
 
  5 默认最多支持10000个用户表,如果学员支持更多表,可以通过修改宏MAX_TABLE_NUM来进行调整。
 
 
使用方法
 
运行: ./relayfetch -h来获取选项
 
主要选项包括:
-d debug
-D 后台运行
-p 密码
-u 用户名,请以root用户运行
-P mysqld端口号
-s 整数,单位为M,当read线程超过sql线程position这么多字节数时,会等待sql线程,默认为1M
-S mysql sock文件路径
-n worker线程数目。默认为5
-a 当seconds_behind_master大于这个值时,会唤醒relayfetch,默认为1s
-t 当使用该选项时,表明不使用分表规则(例如,表name_1 和表name_2会被视为同一类表)
 
我们可以通过端口号来运行
 
./relayfetch-uroot -t -P3306
 
或者通过sock来运行
 
./relayfetch-S /u01/mysql/run/mysql.sock -uroot
 
与该工具类似的还有Maatkit的mk-slave-prefetch,功能类似
 
原创粉丝点击