您好,登录后才能下订单哦!
本篇文章为大家展示了如何开发一个高性能的redis cluster proxy,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
背 景
redis cluster简介
Redis cluster是redis官方提供集群方案,设计上采用非中心化的架构,节点之间通过gossip协议交换互相的状态,redis cluster使用数据分片的方式来构建集群,集群内置了16384个哈希槽,每个key都属于这16384这个哈希槽中的一个,通过crc16算法计算哈希值,再取余可得每个key归属的哈希槽;redis cluster支持动态加入新节点,动态迁移slot,自动的故障转移等。
Redis cluster的架构要求客户端需要直接与redis集群中的每个节点建立连接,并且当出现新增节点加入、节点宕机failover、slot迁移等事件时,客户端需要能够通过redis cluster协议去更新本地的slot映射表,并且能处理ASK/MOVE语义,因此,我们一般称实现了redis cluster协议的客户端为smart redis client。
Redis cluster最多可以构建超过100个主节点的集群(超过之后gossip协议开销过大,且可能引起集群不稳定),按照单节点10G容量(单实例内存过大可能导致性能下降),单集群最多可以支撑1T左右的容量。
问 题
Redis cluster有很多优点(比如可以构建大容量集群,性能好,扩缩容灵活),但是当一些项目工程期望从redis迁移到redis cluster时,客户端却面临着大量的改造工作,与此同时带来的是需要大量的测试工作以及引入的新风险,这对于一些稳定运行的线上工程代价无疑是巨大的。
需 求
为了更方便的将业务迁移到redis cluster,最期望的是客户端SDK的API完全兼容redis/redis-cluster,spring提供的RedisTemplate是一个很好实现,但是对于没有使用SpringRedisTemplate的项目,很多客户端实现的redis和redis-cluster访问API是不一致的(比如Java中流行的Jedis),这无形中提高了迁移工作的工作量和复杂性,此时redis cluster proxy是不错的选择,有了proxy,就可以像操作单实例redis一样操作redis cluster,客户端程序就不需要做任何的修改。
当然,增加一层proxy,必然会导致性能有一定程度的下降,但是proxy作为无状态的服务,理论上可以水平扩展,并且由于proxy层的存在减少了后端redis server的连接数,在某些极限场景下甚至能提高redis集群整体的吞吐量。此外,基于proxy,我们还可以做很多额外的事情:
比如可以在proxy层做分片逻辑,这样当单集群的redis cluster不满足需求(内存/QPS)时,就可以通过proxy层实现透明的同时访问多个redis cluster集群。
再比如可以在proxy层做双写逻辑,这样在迁移或者拆分缓存类型的redis时,就不需要使用redis-migrate-tool之类的工具进行全量迁移,而只需要按需双写,即可完成迁移。
此外因为proxy实现了redis协议,因此可以在proxy层利用其它存储介质实现redis相关命令,从而可以模拟成redis对外服务。一个典型的场景就是冷热分离存储。
功 能
介于上述各种原因和需求,我们基于netty开发了camellia-redis-proxy这样一个中间件,支持如下特性:
支持设置密码
支持代理到普通redis,也支持代理到redis cluster
支持配置自定义的分片逻辑(可以代理到多个redis/redis-cluster集群)
支持配置自定义的双写逻辑(服务器会识别命令的读写属性,配置双写之后写命令会同时发往多个后端)
支持外部插件,从而可以复用协议解析模块(当前包括camellia-redis-proxy-hbase插件,实现了zset命令的冷热分离存储)
支持在线变更配置(需引入camellia-dashboard)
支持多个业务逻辑共享一套proxy集群,如:A业务配置转发规则1,B业务配置转发规则2(需要在建立redis连接时通过client命令设置业务类型)
对外提供了一个spring-boot-starter,3行代码即可快速搭建一个proxy集群
当然,还有另外一个方案,可以将proxy节点注册到zk/Eureka/Consul等注册中心,客户端通过拉取和监听proxy的列表,然后再向访问单节点redis一样访问每个proxy即可。以Jedis为例,仅需将JedisPool替换为封装了注册发现逻辑的RedisProxyJedisPool,即可像访问普通redis一样使用proxy了,此时,部署架构图如下:
应用场景
需要从redis迁移到redis-cluster,但是客户端代码不方便修改
客户端直连redis-cluster,导致cluster服务器连接过多,导致服务器性能下降
单个redis/redis-cluster集群容量/QPS不满足业务需求,使用camellia-redis-proxy的分片功能
缓存类redis/redis-cluster集群拆分迁移,使用camellia-redis-proxy的双写功能
使用双写功能进行redis/redis-cluster的灾备
混合使用分片和双写功能的一些业务场景
基于camellia-redis-proxy的插件功能,开发自定义插件
Redis cluster作为官方推荐的集群方案,越来越多的项目已经或正在迁移到redis cluster,camellia-redis-proxy正是在这样的背景下诞生的;特别的,如果你是一个Java开发者,camellia还提供了CamelliaRedisTemplate这样的方案,CamelliaRedisTemplate拥有和普通Jedis一致的API,提供了mget/mset/pipeline等原生JedisCluster不支持的特性,且提供了和camellia-redis-proxy功能一致的分片/双写等特性。
上述内容就是如何开发一个高性能的redis cluster proxy,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。