【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】特性、优点 【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.confName 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,自定义命令扩展,用于命令扩展,欧博allbet支持redis 的插件以及自定义数据处理函数等 standalone.conf,使用单击模式的redis配置 【2.5】启动predixycd /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个就不测了,知道它有效就行,先这样; (责任编辑:) |