redis代理对比,redis架构对比,redis predixy安装和功能测试

【0】代理功能与性能对比

目前市面上主流的代理包含:predixy、twemproxy、codis、redis-cerberus四款,这四款各有各的优势,我们逐个对比进行对比分析。

 

 

如上图,我们发现 twemproxy / codis 都不支持 redis-cluster,所以我们放弃使用;(但业界 codis 用的挺多的)

性能测试报告 2017:https://blog.csdn.net/rebaic/article/details/76384028

性能测试测试报告 2020:https://github.com/netease-im/camellia/blob/master/docs/redis-proxy/performance-report-8.md

redis架构发展:https://www.cnblogs.com/crazymakercircle/p/14282108.html

【1】predixy的安装和配置

【1.1】基本介绍

predixy 是高性能的适用于 redis 集群和哨兵的代理。

predixy github 地址:https://github.com/joyieldInc/predixy

predixy 编译安装需要 C++11 版本的编译器,至少需要 CentOS 7及以上版本才能编译安装。

对于 CentOS 6或更低版本,可以直接使用在 github release 中的二进制版本。

【1.2】特性、优点

  • 同并轻量级
  • 支持多线程
  • 多平台支持:Linux、OSX、BSD、Windows( Cygwin )
  • 支持Redis Sentinel,可配置一组或者多组redis
  • 支持Redis集群
  • 支持redis多种类型的命令,包括blpop、brpop、brpoplpush
  • 支持扫描命令,无论是单个redis还是多个redis实例都支持
  • 多键命令支持:mset/msetnx/mget/del/unlink/touch/exists
  • 支持redis的多数据库,即可以使用select命令
  • 支持事务,当前验证于Redis Sentinel下组redis组可用
  • 支持脚本,包括命令:script load、eval、evalsha
  • 支持发布订阅机制,也即Pub/Sub系列命令
  • 多数据中心支持,删除支持
  • 扩展的AUTH命令,部分的读、写、管理权限控制机制,健空间限制机制
  • 日志可按级别输出,记录日志被io实时记录
  • 日志文件可以按时间、大小自动切分
  • 大量的统计信息,包括CPU、内存、请求、响应等信息
  • 延迟监控信息,可以看到整体延迟,分秒还原事件延迟

【2】安装

【2.1】下载解压

tar -xzf predixy-1.0.5-bin-amd64-linux.tar.gz

mv predixy-1.0.5 /data/redis/

cd /data/redis/predixy-1.0.5/conf/

 

【2.2】修改配置文件 cluster.conf

配置文件官方说明:https://github.com/joyieldInc/predixy/blob/master/doc/config_CN.md

predixy 支持多种架构,由于使用的是 redis cluster,只需配置 redis cluster 对应的配置文件cluster.conf 即可。

内容如下:

##ClusterServerPool {

## [Password xxx] #default no

## [MasterReadPriority [0-100]] #default 50

## [StaticSlaveReadPriority [0-100]] #default 0

## [DynamicSlaveReadPriority [0-100]] #default 0

## [RefreshInterval number[s|ms|us]] #default 1, means 1 second

## [ServerTimeout number[s|ms|us]] #default 0, server connection socket read/write timeout

## [ServerFailureLimit number] #default 10

## [ServerRetryTimeout number[s|ms|us]] #default 1

## [KeepAlive seconds] #default 0, server connection tcp keepalive

# Examples:

ClusterServerPool {

Password 123456

MasterReadPriority 60

StaticSlaveReadPriority 50

DynamicSlaveReadPriority 50

RefreshInterval 1

ServerTimeout 1

ServerFailureLimit 10

ServerRetryTimeout 1

KeepAlive 120

Servers {

+ 192.168.191.176:6381

+ 192.168.191.176:6382

+ 192.168.191.211:6383

+ 192.168.191.211:6384

+ 192.168.191.70:6385

+ 192.168.191.70:6386

}

}

参数说明:

MasterReadPriority,StaticSlaveReadPriority,DynamicSlaveReadPriority 三个参数和 redis 本身配置文件中的 slave-priority 没任何关系的。

如果是自动发现找到的节点,则 DynamicSlaveReadPriority 会起作用,如果是直接配置的节点,则 StaticSlaveReadPriority 会起作用。

 

Master/SlaveReadPriority

Master

Slave1

Slave2

Fail-over notes

60/50

all requests

0 requests

0 requests

Master dead, read requests deliver to slave until master(maybe new master) alive

60/0

all requests

0 requests

0 requests

Master dead, all requests fail

50/50

all write requests, 33.33%read requests

33.33% read requests

33.33% read requests

-

0/50

all write requests, 0 read requests

50% read requests

50% read requests

all slaves dead, all read requests fail

10/50

all write requests, 0 read requests

50% read requests

50% read requests

all slaves dead, read requests deliver to master

 

 

RefreshInterval : predixy 获取节点信息和集群 hash slot 集群信息的间隔

ServerFailureLimit : predixy 停止路由到节点之前失败的次数

ServerTimeout : 单个命令执行的超时时间

Password: 指定连接redis实例默认的密码,不指定的情况下表示redis不需要密码

 

【2.3】集群自动发现

在 Servers 部分配置集群中任意一个节点即可,predixy 会自动发现整个集群的信息,即使配置的节点挂掉后,predixy 代理仍然可正常工作。

通过自动发现集群,可以减少 cluster.conf 配置文件的修改及对 predixy 的重启操作。

但 predixy 无法删除曾经自动发现的节点,如果某节点下掉,predixy 仍会看到之前的节点,虽然不影响正常使用,日志则会不断报出错误信息。需重启 predixy 解决。

 

【2.4】配置 predixy.conf

Name Predixy001

Bind 0.0.0.0:7617

WorkerThreads 4

ClientTimeout 300

Log /data/redis/predixy-1.0.5/predixy.log

LogRotate 1d

LogRotate 200M

Include cluster.conf

注意 Include 部分,只需包括 cluster.conf,其他的则注释掉,否则可能会影响到 predixy的使用。

 

基本配置文件说明:

  • predixy.conf,整体配置文件,会引用下面的配置文件
  • cluster.conf,用于Redis Cluster时,配置后端redis信息
  • sentinel.conf,用于Redis Sentinel时,配置后端redis信息
  • auth.conf,代理中心访问权限控制配置,可以定义多个验证密码,可每个密码指定读、写、管理权限,以及定义可访问的健空间
  • dc.conf,多数据中心支持,可以定义读写分离规则,读流量权重分配
  • latency.conf, 延迟监控规则定义,可以指定需要监控的命令以及延时时间间隔
  • command.conf,自定义命令扩展,用于命令扩展,支持redis 的插件以及自定义数据处理函数等
  • standalone.conf,使用单击模式的redis配置

 

【2.5】启动predixy

  cd /data/redis/predixy-1.0.5/bin/

  cp predixy /data/redis/bin/ #我的redis 启动命令在这里,已添加进环境比那里

启动

看情况任选一即可

nohup predixy /data/redis/predixy-1.0.5/conf/predixy.conf &

nohup predixy /data/redis/predixy-1.0.5/conf/predixy.conf >/data/redis/predixy-1.0.5/predixy.log 2>&1 &

查看日志

tail -f /data/redis/predixy-1.0.5/predixy.log

如上,我们可以看到,由于配置文件 predixy.conf 配置的确是启动了4个进程,所以我们4个线程都就绪连接到集群所有机器了;对应构建连接池

predixy 添加环境变量

在 /etc/profile 中添加,然后在 /etc/rc.local 中设置开机启动 ,任选一即可

echo 'nohup predixy /data/redis/predixy-1.0.5/conf/predixy.conf &' >> /etc/rc.local

nohup predixy /usr/local/predixy-1.0.5/conf/predixy.conf > /data/redis/predixy-1.0.5/predixy.log 2>&1 &

 

【3】连接核验

代理连接,直接连 7617 端口就行

redis-cli -p 7617 info

 

可以看到 mget mset 都是没有问题的

同时代理日志信息如下:

我们通过集群的方式连接,发现key 什么的确实过去了

【4】故障转移测试

【4.1】关闭一个主库

redis-cli -h 192.168.191.70 -p 6385 -a 123456 shutdown

tail -f /data/redis/predixy-1.0.5/predixy.log

我们可以发现,b2 之前是在 6385

故障转移之后,6382 从库,经过故障转移接替 6385 成为主库;

我们继续连接代理查询:

如上图,安稳查询那么,证明故障转移是可以的;程序连接的代理,不会感知到任何东西;

同时我们查看代理日志:

看这,和炸街了一样,一直报;

这就如同【2.3】说的

  在 Servers 部分配置集群中任意一个节点即可,predixy 会自动发现整个集群的信息,即使配置的节点挂掉后,predixy 代理仍然可正常工作。

  通过自动发现集群,可以减少 cluster.conf 配置文件的修改及对 predixy 的重启操作。

  但 predixy 无法删除曾经自动发现的节点,如果某节点下掉,predixy 仍会看到之前的节点,虽然不影响正常使用,日志则会不断报出错误信息。需重启 predixy 解决。

我们连接代理,在 info 中可以发现:

  该配置信息依然在,但其状态 CurrentIsFail:1

 

总结:

代理可用,集群正常故障转移,程序无感;

运维问题:日志会一直报错;forget 也没用

【4.2】下掉一个从节点

我们下一个从节点看看;

我们下掉6383吧;

redis-cli -h 192.168.191.211 -p 6383 -a 123456 shutdown

查看代理日志:

会一直报错,连不上6383,直到去掉配置文件中的这个实例,重启代理

总结:

代理可用,集群正常故障转移,程序无感;

运维问题:日志会一直报错;forget 也没用

【4.3】关闭没有从库的主库(彻底关闭一对主从)

 

我们关闭 6386和6383这对主从吧,看看代理这时候会发生什么;

redis-cli -h 192.168.191.211 -p 6383 -a 123456 shutdown

redis-cli -h 192.168.191.70 -p 6386 -a 123456 shutdown

我们可以看到,现在redis-cluster 已经有问题了;

我们看看代理操作是什么情况;

我们发现是不能访问的!

集群参数:

集群参数也是没一个开的;

【4.4】代理下的集群参数测试,非全slot 可用性

我们这里就不测那么多了,测一个即可,节点先启动回去

 

然后我们测试 cluster-allow-reads-when-down yes 这个参数吧

redis-cli -h 192.168.191.176 -p 6381 -a 123456 config set cluster-allow-reads-when-down yes

redis-cli -h 192.168.191.176 -p 6382 -a 123456 config set cluster-allow-reads-when-down yes

redis-cli -h 192.168.191.211 -p 6383 -a 123456 config set cluster-allow-reads-when-down yes

redis-cli -h 192.168.191.211 -p 6384 -a 123456 config set cluster-allow-reads-when-down yes

redis-cli -h 192.168.191.70 -p 6385 -a 123456 config set cluster-allow-reads-when-down yes

redis-cli -h 192.168.191.70 -p 6386 -a 123456 config set cluster-allow-reads-when-down yes

然后继续关闭 6383 6386 一对主从的实例

redis-cli -h 192.168.191.211 -p 6383 -a 123456 shutdown

redis-cli -h 192.168.191.70 -p 6386 -a 123456 shutdown

然后我们看看代理,是否可以如之前测试那样,对现有key 是可以访问的;

我们发现,确实是这样; 直连集群也是如此;

我们上主库实例上去把开关打开;仅剩的 2个 主库 全都开启这个参数;

直接连redis-cluster集群上稳稳的是可以set 了; 如下图:

 

代理上也可以了 对现有 存在的 slot 的操作、不存在的key 也可以创建了;如下图:

代理日志,一直报,这是常态了,如下图

 

【5】集群水平扩展、收缩测试

【5.1】新增主节点

(1)新增 6387 主节点

redis-cli --cluster add-node 192.168.191.82:6387 192.168.191.176:6381 -a 123456

(2)自动平衡分配slot 给新空主节点 6387

redis-cli --cluster rebalance --cluster-use-empty-masters 192.168.191.176:6381 -a 123456

 

(3)check 一下看看现在的集群信息

 

(4)检查代理日志

如下图:

我们可以发现,新加入的主节点已经被自动发现且识别出来了;

 

(5)使用代理操作、查阅验证

我们用代理 mset 一下

 

如下图,我们连接redis-cluster 查阅验证,可以发现新的 key 的get set 已经完成,并且新的key 也分配到了 新加的主库 6387

如下图,我们连接代理,使用Info 查看也可以看到该主库了,由于代理开了4个线程,所以现在的连接数是4,且如果线程不挂,一般会一直保持 connections为4的;

(6)结论

没有任何问题啊,就真如redis-cluster 一样

【5.2】新增从节点

redis-cli --cluster add-node 192.168.191.82:6388 192.168.191.176:6381 --cluster-slave -a 123456

如下图:加入成功

 

如下图:我们可以看到,代理自动识别出来了新的,木有问题啊

要是挂掉它,我们可以发现,代理的日志依然是会一直报,这表示只要有节点加入进来了,不管你是forget 还是 del-node,也不管你是否是 cluster.conf 文件中配置的集群ip;

反正只要是集群自动发现加入过的,它都会报;如果要去掉,只能重启代理

 

【5.3】删除一主一从,缩容

 

先删除从库:

redis-cli --cluster del-node 192.168.191.176:6381 45a9ea5062479aaad68b6a9c4b5cc1942639dcb4 -a 123456

 

再删主库:

(1)迁移被删除主库上的 slot

把槽位平均非给其他主节点

redis-cli -a 123456 --cluster rebalance --cluster-weight \

11ac5cf5004f22a55ee0afa2b221d120ad768f7d=1 f5dc23c602b57f6b09b4909d01289ff4d80220ed=1 \

4ba0958a0c9aa944962182673058fbc4c27952eb=1 4dfde05a131e9b8900553ef03ef41703737e449f=0 \

192.168.191.176:6381

 

(2)把节点从群集中移除,删除主节点

redis-cli -a 123456 --cluster del-node 192.168.191.176:6381 4dfde05a131e9b8900553ef03ef41703737e449f

 

(3)查看代理:

查看代理日志,如下图:

发现,居然没有报错(删除节点,但节点实例未关闭,所以它并没有报错,依然会连接该实例)

代理查看:

发现这2个都还在,这证明了,代理不会自动更新集群状态的删除信息,它只会自动更新新增的集群节点信息;

关闭这 6387 6388 实例;

 

我们发现,连不上又报错了;

【5.4】代理因为删除节点报错问题解决:重启代理

关闭:kill 进程

自动:predixy /data/redis/predixy-1.0.5/conf/predixy.conf &

 

重启后,报错信息没了;

登录代理:info 中的信息也更新了

 

6387 和 6388 实例就不见了;恢复正常;

【6】读写分离与读负载均衡的测试

 

Master/SlaveReadPriority

Master

Slave1

Slave2

Fail-over notes

60/50

all requests

0 requests

0 requests

Master dead, read requests deliver to slave until master(maybe new master) alive

60/0

all requests

0 requests

0 requests

Master dead, all requests fail

50/50

all write requests, 33.33%read requests

33.33% read requests

33.33% read requests

Master dead,read requests deliver to slave

0/50

all write requests, 0 read requests

50% read requests

50% read requests

all slaves dead, all read requests fail

10/50

all write requests, 0 read requests

50% read requests

50% read requests

all slaves dead, read requests deliver to master

 

 

如下:我们现在的架构是

6382=>6385 ,6384=>6381 ,6386=>6383

【6.1】60/50 Master/SlaveReadPriority

现在的架构是:

6382=>6385 ,6384=>6381 ,6386=>6383

 

6350中,只有Ping

 

 

如上图,我们发现,发送了5次 a,5次 a 全在主库 6382;所以证明我们之前 60/50 的结论是正确的;

那么我们之前全是这种模式,就不做故障转移测试了,可以直接得出结论了;

结论:

所有的请求,都会发送给主库;

当主库宕机,故障转移期间,读操作会发送给从库;(也会尝试连接主库,连几次无果到阈值后读请求发送到从库)

新主库产生后,所有的请求发给新主库;

【6.2】60/0 Master/SlaveReadPriority

修改 cluster.conf 参数

MasterReadPriority 60

StaticSlaveReadPriority 0

DynamicSlaveReadPriority 0

重启:

现在的架构是:

6382=>6385 ,6384=>6381 ,6386=>6383

 

关闭 6382主库:

redis-cli -h 192.168.191.176 -p 6382 -a 123456 shutdown

如下:

我们发现故障转移期间,无法访问 a;等故障转移完毕,从库变成主库,就可以访问了;

 

结论:

所有的请求,都会发送给主库;

当主库宕机,故障转移期间,所有请求都会失败;

新主库产生后,所有的请求发给新主库;

【6.3】50/50

现在的架构是:

6382=>6385 ,6384=>6381 ,6386=>6383

如上面3个图,我们发现真的 50 50 读负载均衡了;

关闭 6382主库:

redis-cli -h 192.168.191.176 -p 6382 -a 123456 shutdown

如上图,我们可以发现,关闭 6382 主库之后,没有任何影响,之前在故障转移切换瞬间失败了一次;

如下图,关闭 6382 ,命令一发起它就收不到任何请求了;

如下图:6385实例的监控,我们发现主库挂了,从库还没有故障转移切换成主库时,read操作依然请求过来了;

 

结论:

读请求平均分发给所有的主从;

当主库宕机,故障转移期间,读请求都会平均分配到剩余存活的slave;

新主库产生后,读请求平均分发给所有的主从;

后面2个就不测了,知道它有效就行,先这样;

posted @ 2021-08-31 15:25  郭大侠1  阅读(1525)  评论(0编辑  收藏  举报