page contents

redis主从复制数据延迟解决方案

在 redis 主从复制模式下可能会出现 slave 延迟导致读写不一致的问题。 解决办法有2种


attachments-2020-08-8MaXnYOt5f2a68fd65c19.png


在 redis 主从复制模式下可能会出现 slave 延迟导致读写不一致的问题。 解决办法有2种


1. 修改从几点参数配置


从节点的 slave-serve-stale-data 参数也与此有关,它控制这种情况下从节点的表现 当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:

  1. 如果slave-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的请求。

  2. 如果slave-serve-stale-data设置为no,除去INFO和SLAVOF命令之外的任何请求都会返回一个错误”SYNC with master in progress”。


2. 编写外部监控程序


将主从模式更换为哨兵模式则无需自己去做监控

对于无法容忍大量延迟场景,可以编写外部监控程序监听主从节点的复制偏移量,当延迟较大时触发报警或者通知客户端避免读取延迟过高的从节点。

编写监控程序,然后定时执行

<?php
/**
 * [监控 redis 主从复制偏移量:当监控到延迟高的节点时,移除延迟高的从节点, 即动态修改读写分离配置信息。(可以添加触发报警机制)]
 *      [在做主从复制时推荐使用 redis 的哨兵模式,则无需自己去监控,哨兵模式能自己监控并切换主从]
 *
 * @Author  leeprince:2020-05-05 10:29
 */

define('IS_DEBUG', false);
define('MAX_OFFSET', 10);
$redis = new Redis();
$redis->connect("127.0.0.1", 63790);
$redis->auth("leeprince");

$info         = $redis->info('replication');
$slaveNum     = $info['connected_slaves'];
$masterOffest = $info['master_repl_offset'];

echo "+++++++++++++++++++++++定时开始+++++++++++++++++++++++\r\n";

$invalidSlave = []; // 要移除的从节点
for ($i = 0; $i < $slaveNum; $i++) {
    $slaveKey    = "slave{$i}";
    $slaveInfo   = $info[$slaveKey];
    $slaveInfo   = explode(',', $slaveInfo);

    $slaveHost   = explode('=', $slaveInfo[0])[1];
    $slavePort   = explode('=', $slaveInfo[1])[1];
    $slaveState  = explode('=', $slaveInfo[2])[1];
    $slaveOffset = explode('=', $slaveInfo[3])[1];

    $offset = $masterOffest - $slaveOffset;
    if ($offset > MAX_OFFSET || $slaveState != 'online') {
        $readHostMap = include_once "./hostMap.php";
        $slaveString = "tcp://{$slaveHost}:{$slavePort}";
        $invalidSlave[] = $readHostMap[$slaveString];
        var_dump("当前从节点为高延迟--{$slaveString}");
    }
}

if (empty($invalidSlave)) {
    if (IS_DEBUG) {
        echo "========================================\r\n";
        var_dump($info);
        echo "========================================\r\n";
    }
    var_dump('不存在需要移除的从节点');
    exit(0);
}

// redis 动态配置文件
$confPath = './config.php';
include $confPath;


if (IS_DEBUG) {
    echo "========================================\r\n";
    var_dump($info);
    var_dump($replication);
    echo "========================================\r\n";
}

$isHaveChange = false; // 是否需要修改配置。考虑上一次可能已经移除了该从节点
foreach ($replication as $key => &$value) {
    if (in_array($value, $invalidSlave)) {
        $isHaveChange = true;
        var_dump("需要移除的从节点存在当前配置中--{$value}");
        unset($replication[$key]);
    }
}

if ($isHaveChange) {
    $content = "<?php \n\$replication = ".var_export($replication, true).";";
    file_put_contents($confPath, $content);
    var_dump('已修改配置文件--', $content);
} else {
    var_dump('无需修改配置文件');
}
exit(0);

完整的代码:包含 linux 定时器与 swoole 毫秒级定时器版本
https://github.com/leeprince/docker/tree/master/redis/monitor

在从节点种模拟网络延迟步骤

$ apt update

$ apt install -y iproute2

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000
    link/tunnel6 :: brd ::
15: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc netem state UP group default qlen 1000
    link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.4/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

# 设置模拟网络延迟 5 秒。 删除设置:tc qdisc del dev eth0 root netem delay 5000ms
$ tc qdisc add dev eth0 root netem delay 5000ms

运行结果:

attachments-2020-08-3n3EIqe25f2a69871f5ef.png


attachments-2020-08-5aBPG0yY5f2a699062591.jpg

  • 发表于 2020-08-05 16:11
  • 阅读 ( 1098 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章