在之前的文章中介绍了Redis6的集群搭建和原理,我们可以使用dummy和smart客户端连接集群,本篇介绍Redis6新增的一个功能:集群代理。客户端不需要知道集群中的具体节点个数和主从身份,可以直接通过代理访问集群,对于客户端来说通过集群代理访问的集群就和单机的Redis一样,因此也能解决很多集群的使用限制。
目录
Redis6系列文章:
Redis系列(一)、CentOS7下安装Redis6.0.3稳定版
Redis系列(六)、数据类型之有序集合ZSet(sorted_set)
Redis系列(十)、详解Redis持久化方式AOF、RDB以及混合持久化
Redis系列(十一)、Redis6新特性之ACL安全策略(用户权限管理)
Redis系列(十二)、Redis6集群搭建及原理(主从、哨兵、集群)
Redis系列(十三)、pub/sub发布与订阅(对比List和Kafka)
Redis系列(十四)、Redis6新特性之RESP3与客户端缓存(Client side caching)
介绍
在Redis6的release note中可以看到新功能中的ACL,RESP3,客户端缓存我们在前面的文章中已经介绍过,本篇就看一下集群代理。集群代理与Redis在Github上是不同的项目,地址如下:
Github:https://github.com/RedisLabs/redis-cluster-proxy
集群代理(Redis Cluster Proxy): 将集群抽象为单实例,客户端不需要知道集群中的具体节点个数和主从身份,通过代理访问集群,就像访问单机Redis一样。同时集群代理也能解决在集群模式下multiple操作的限制及跨slot操作限制(如mget,mset...)。
Redis集群代理的特点:
- 自动化路由:每个查询被自动路由到集群的正确节点;
- 多线程:多路复用通信模型,每个线程都有自己的集群连接;
- 顺序性:在多路复用上下文中,保证查询的执行和应答顺序;
- 无感知更新集群信息:当请求/重定向错误时会自动更新集群信息,客户端提交的查询会在集群信息更新完成后重新执行,对于客户端来说这一切是无感的,客户端不会收到请求/重定向的错误信息,而是直接收到查询的结果;
- 跨槽/节点查询:支持跨slot或node的mutiple操作key,如mget,mset,del等。但由于mset,del会破坏原子性,因此该配置默认关闭;
- ACL:支持连接开启了ACL的Redis集群;
- DBSIZE:对于没有指定节点的命令,将会合并所有的信息的总和并返回;
安装
下载解压
从github上下载解压源码(2020-06-30:目前最新版是unstable版本)
- #git命令
- git clone https://github.com/artix75/redis-cluster-proxy
-
- #手动下载zip解压
- unzip redis-cluster-proxy-unstable.zip
安装gcc4.9+版本
在之前安装Redis6的文章中有介绍,此处略过安装gcc9.1:
- #开启gcc9.1
- scl enable devtoolset-9 bash
-
- #查看gcc版本
- gcc -v
编译
执行下面的命令编译源码,出现下图表示安装成功:
- #进入目录并编译
- cd redis-cluster-proxy-unstable
- make
-
- #如果编译出错之后再编译可以先执行命令删除之前的编译文件
- make distclean
如果遇到错误unknown type name ‘_Atomic’ ,请检查gcc版本重新安装;
安装
编译成功后使用下面的命令安装Redis集群代理服务,出现下图表示安装成功:
- #安装Redis集群代理,可指定安装目录
- make install PREFIX=/opt/app/redis-cluster-proxy
使用
配置启动
从源码中将配置文件copy到安装目录:
cp /home/wyk/redis-cluster-proxy-unstable/proxy.conf /opt/app/redis-cluster-proxy/
修改配置文件:
vim /opt/app/redis-cluster-proxy/proxy.conf
- #配置Redis集群,这里我使用前几篇文章中配置的Redis6集群,三主三从
- cluster 127.0.0.1:6381 #主1
- cluster 127.0.0.1:6382 #主2
- cluster 127.0.0.1:6383 #主3
- cluster 127.0.0.1:6391 #从1
- cluster 127.0.0.1:6392 #从2
- cluster 127.0.0.1:6393 #从3
-
- #默认端口
- port 7777
-
- #线程数
- threads 8
-
- #后台运行
- daemonize yes
-
- #日志文件
- logfile "/opt/app/redis-cluster-proxy/redis-cluster-proxy.log"
-
- #允许跨slot查询
- enable-cross-slot yes
-
- #最大客户端连接数
- max-clients 10000
-
- #ACL用户密码(也可以在启动服务时指定)
- auth-user myuser #ACL用户
- auth mypassw #ACL密码
-
- #连接池
- connections-pool-size 10
- connections-pool-min-size 10
- connections-pool-spawn-every 50
- connections-pool-spawn-rate 50
创建日志文件并使用下面的命令指定配置文件启动集群代理:
- #创建日志文件
- touch /opt/app/redis-cluster-proxy/redis-cluster-proxy.log
- #启动Redis集群代理服务
- /opt/app/redis-cluster-proxy/bin/redis-cluster-proxy -c /opt/app/redis-cluster-proxy/proxy.conf
连接集群代理客户端:
Redis集群代理服务监听7777端口,我们可以使用Redis命令行指定7777端口启动集群代理客户端:
- #连接Redis集群代理客户端
- /opt/app/redis6/bin/redis-cli -p 7777
跨节点slot操作
上面提到在集群代理中,会将集群抽象成一个Redis实例,对用户来说跨slot/node操作是无感的,而在默认集群中会重定向到对应slot所在的节点进行操作。
默认集群模式:
在之前的Redis集群文章中演示了在dummy客户端中操作集群内的key时会重定向到该key存储的slot所在的节点:
- #使用-c进入集群命令行模式
- redis-cli -c -p 6381
-
- #使用命令查看key所在的槽
- cluster keyslot key1
集群代理模式:
在集群代理模式下,可以跨slot甚至跨节点操作key,而在集群模式下链接客户端是做不到的。下图演示了如果在集群代理中使用mset和mget跨slot跨node设置或查询key,对于用户来说仿佛是在使用一个单实例的Redis:
故障转移
手动的使集群中一个主节点宕机,测试集群代理能否感知到集群的故障转移:
- #在6381主节点执行命令,手动的让其宕机
- #命令执行一个非法的内存访问从而让 Redis 崩溃,仅在开发时用于 BUG 调试,执行后需要重启服务
- debug segfault
情况一、主节点6381宕机,6391节点升级为主节点,集群恢复正常,但6381节点还没启动,此时集群代理无法使用,需要启动6381节点之后集群代理才能恢复使用:
情况二、手动将6381主节点宕机,当从节点6391升级为主节点后,重启6381节点作为6391的从节点,此时集群的主从机器全部正常启动,查询集群代理,不会收到影响:
尾巴
目前在Github上最新的版本仍是unstable版,毕竟是新功能,还是有很多BUG的,像集群的故障转移在集群代理中就没有做的很好,其次就是如果集群代理服务本身没有解决单点故障(可以尝试配合HAProxy等代理服务做负载均衡)。
官方最后声明中也提到【当前处于α版本,不推荐在生产环境使用]】:
This project is currently alpha code that is indented to be evaluated by the community in order to get suggestions and contributions. We discourage its usage in any production environment.
但不可否认的是集群代理给redis集群提供了轻量的代理层,也解决了很多在集群模式中的使用限制,未来的潜力还很大,让我们拭目以待吧!
希望本文对你有帮助,请点个赞鼓励一下作者吧~ 谢谢!
<div id="blogExtensionBox" style="width:400px;margin:auto;margin-top:12px" class="blog-extension-box"><div class="blog_extension night blog_extension_type1" id="blog_extension">
<div class="blog_extension_card" data-report-click="{"spm":"1001.2101.3001.6470"}">
<div class="blog_extension_card_left">
<img src="https://img-blog.csdnimg.cn/79228be242af4b7eb88d4bb5a4f7ac12.png" alt="">
</div>
<div class="blog_extension_card_cont">
<div class="blog_extension_card_cont_l">
<span class="text">爱玩大数据</span>
<div class="blog_extension_card_cont_r">
<img class="weixin" src="https://g.csdnimg.cn/extension-box/1.1.6/image/weixin.png" alt="">
<span>微信公众号</span>
<img class="go" src="https://g.csdnimg.cn/extension-box/1.1.6/image/ic_move.png" alt="">
</div>
</div>
<span class="style">每天一篇技术干货,助你get大厂offer!</span>
</div>
</div></div></div>
</article>