redis由单机升级为集群

背景

由于用户不断增加,业务功能不断积累,redis的使用也变的越多,单机扩展内存已不是最优解,采用了升级redis集群的方案。

官方地址

redis集群兼容说明

兼容改动

1.keys 命令不再允许使用,可改用基于游标的迭代器来完成 scan,最后我会列举使用示例。
2.exists 命令也不再允许使用,可通过ttl判断时间来替代,时间复杂度为O(1),或者根据hash,set等类型长度来替代。
3.multi事务中,需要增加watch。这也暗藏着一个bug。
主要修改的是这三个命令。

scan示例

class pro
{
    public function output($str = '') {
        echo $str . PHP_EOL;
        return true;
    }

    public function formatList($data) {
        $data = explode(PHP_EOL, $data);
        $list = [];
        $cursor = 0;
        foreach ($data as $item) {
            if (empty($item)) continue;
            if (!$cursor) {
                $cursor = $item; //没有值,第一个是游标值
            } else {
                $list[] = $item;
            }
        }
        return [$cursor, $list];
    }

    public function main() {
        $config = config::get('redis_api'); //获取配置
        $host = $config[0]['host'];
        $pwd = $config[0]['pwd'];
        $port = $config[0]['port'];

        sleep(2);
        $redis = new Redis(); //实例化redis
        $cursor = 0; //游标值,为0表示结束
        $size = 100;
        try {
            do {
                //命令行方式执行redis scan
                $shell = "redis-cli -h $host -a $pwd -p $port scan $cursor match " . $this->redisKey . "* count $size";
                $result = shell_exec($shell);
                //格式化游标和内容
                list($cursor, $list) = $this->formatList($result);
                foreach ($list as $key) {
                    //进行对结果的操作,如下删除key
                    $redis->del($key);
                }
            } while ($cursor != 0);
        } catch (Exception $e) {
            $this->output('error:' . $e->getMessage());
        }
    }
}

$pro = new pro();
$pro->main();

redis事务中的坑

       $redis = new redis();
            $key = 'test_zp';
            //升级集群增加的watch
            $redis->watch($key);
            //实例化事务
            $multi = $redis->multi(Redis::PIPELINE);
            //批量执行插入操作
            foreach ($list as $item) {
                $redis->ZADD($key, time(), $item . random_int(100, 500));
            }
            $multi->exec();
            // 重点,因为集群升级所加的watch必须用unwatch配合使用
            // unwatch必须加
            $redis->unwatch($key);

Redis::PIPELINE是为了管道方式执行为了避免多次链接,一次请求完成多个操作。
由于使用了管道,导致了必须使用unwatch,不然会导致exec后面的redis操作失败。

上一篇:10.python-5.3.2数据库的连接


下一篇:CentOS操作系统的安装