A-A+

TenDB slave拉取binlog限速功能

2015年10月14日 TenDB 暂无评论

在主从架构的mysql环境中,由slave拉取master生成的binlog并写入自己的relaylog,然后执行重放relaylog。这个流程想必大家已经很熟悉了,但是在特定的情况下,比如一主多从时,在这种构架下如果重建热备时,多个slave同时拉取binlog势必会对master的网络,磁盘带来比较大的负担,对外即表现为master的响应时间增加。

鉴于一主多从的架构还算比较常用,而重建热备也是不可避免的,那么如何在这种情况下降低对master的负担呢?限制slave拉取binlog的速度无疑是最简单也是最容易实现的一种方案了。而成熟的限流算法一共有2种,一个是漏桶算法,一个是令牌桶算法,这两个算法的主要区别在于是否允许突发流量。因为我们只想限制传送binlog的速度,因此只能在应用层而不能在网络层限速,那么传送的最小单位就只能是事件了(event),由于event的大小并不受控制,所以令牌桶算法更加合适。

令牌桶算法的原理比较简单,实现起来也不复杂:

  1. 假设有一个桶,它的容量为n
  2. 每秒会加入a个令牌
  3. 当一个数据包到来时它必须从桶中拿到与数据包大小相同的令牌数才能放行

这个算法的速率由a的大小来决定,能通过的最大数据包大小由n决定,原始的令牌桶算法存在丢弃数据包的行为,但是这在我们的场景下是不可接受的。因此将该算法稍作改动,让其可以通过大于n的数据包,具体改动是:如果一个event已经到达,那么即使桶满了也不丢弃溢出的令牌,这样无论多大的数据包都能获得足够的令牌数然后被放行。

除此以外,令牌桶算法要求的每秒加入固定数量的令牌入桶在单线程的模型中也不易实现,因此将其修改成每次写relaylog之前加入令牌,最终的实现伪代码如下:

 

last_add_time = now()

tokens = speed_limit

while(true){

  event = read_event()

  if (tokents > TOKEN_MAX) {

    tokens = TOKEN_MAX

    last_add_time = now()

  }

  do{

    tokens = tokens + (now()-last_add_time)*speed_limit

    last_add_time = now()

    if(tokens < event.len)

      sleep()

  }

  write_event(event)

}

我们加了一个参数“read_binlog_speed_limit”来控制限制的速度,单位是KB/s,如果这个值为0,那么意味着没有限制,这个参数的默认值为0。它可以随时动态配置,配置后即生效。

原创文章,转载请注明: 转载自腾讯游戏DBA团队

本文链接地址: TenDB slave拉取binlog限速功能

文章的脚注信息由WordPress的wp-posturl插件自动生成

Copyright © 腾讯游戏DBA团队 保留所有权利.  

用户登录

分享到: