先放两篇参考文章:
https://www.cnblogs.com/dodng/p/7744330.html
https://blog.csdn.net/lilizhou2008/article/details/109554713
问题集合:
1、哨兵集群中只要有一台宕了,整个集群的故障转移机制就失效了。
2、哨兵启动时候redis主库必需运行正常,否则故障转移机制也失效。
3、应用端需要先询问哨兵才能访问到redis主库,是否对效率也有明显的影响。
方案:
目标是实现redis集群的无感知弹性扩容
关键点
1.是无感知,即对redis集群的用户来说服务ip和port保持不变
2.弹性扩容,指的是在需要时刻可以按照业务扩大redis存储容量。
1.业务场景
- 1.redis集群某个业务容量不足,需要扩容
- 2.redis集群需要一个为一个新业务分配存储容量
- 3.redis集群在扩容的时候服务不是停止的,而是服务中,即无感知
最好的解决方式
对客户端无感知,即客户端不需要任何操作就实现了redis集群的扩容
2.最朴素的twemproxy+redis集群架构
其中twemproxy-A代理后面接了3个redis实例,作为集群使用,如果1个redis示例有10G存储能力,
那么目前这个架构具有10G*3=30G的存储能力,其中根据twemproxy的配置来实现负载均衡。
3.最直接的扩容方案:
这个方案扩容是最直接的,即在代理后面直接新加一个redis-4,来扩充这个redis集群的容量。
这种方式最直接,但是问题也比较大,主要有2个:
- 1.后端新增一个redis实例之后,虽然有一致性hash保证大部分数据还会走原先的路由,
- 但仍有小部分旧的数据会被路由到新的redis-4中,即丢失一小部分旧的数据
- 2.扩容效果不理想,一开始时,redis-4的已用存储是0,理想最好的方式是旧的数据还走之前的路由
- ,新的数据路由到redis-4中
为了解决上述方案的不足,本文提出了一个新的方案如下
4.一个twemproxy二级代理的方案:
这个方案有1个关键点,即怎么实现旧的数据走之前的路由,新的数据走redis-4的路由,这就用到了
hash_tag的预分配(即提前占坑的思想)技术,使用hash_tag作为二级twemproxy的路由标示,具体操作如下:
- 1.twemproxy-C的hash_tag 设置为(),twemproxy-A和twemproxy-B的hash_tag设置为{}
- 2.插入形如key_(0){1},key(1){1}的2个key,假设key(0){1}路由到了twemproxy-A,key(1)_{1}路由到了twemproxy-B
- 3.那么旧的服务插入数据的标示就是key_(0){xxxx},新的数据插入的标示就是key(1)_{xxxx}
注意点如下:
- 1.一开始可以预先分配多一些二级代理,以备不时只需
- 2.一开始需要测试清楚,哪些()标示走哪些对应的二级代理。
好处:
- 1.自动的完成了旧的数据走旧路由,新的数据走新路由
- 2.新的数据也可以如图与之前的业务数据存储完全隔离
- 3.新的路由还可以复用之前的存储,即redis-1到redis-3的存储
5.最终真正实现无感知弹性扩容方案
如图4所示:
最终的方案新增了一个VIP,用这个VIP来解决无感知的问题,即扩容对客户端来说是无感知的。
无感知的解决类似”双buffer交换“的思路,即上图的twemproxy-C和twemproxy-D,当需要重启twemproxy代理时,
可以进行如下操作:
- 1.现假设vip只访问到twemproxy-C
- 2.更改twemproxy-D使用最新的配置,重启
- 3.vip切换服务到只访问twemproxy-D
问题
Redis内存爆了
场景:不停地写入内存。
Redis在高并发系统中是不可或缺的中间件,由于它本身的高性能特性可以帮助我们解决很多业务场景。同时Redis也是运维工程师重点关注的。生产环境的Redis内存使用情况是必要的监控指标,Redis的稳定运行在一定程度上保证了生产环境的安全稳定运行。
今天生产环境爆出了大量的 timeOut 502错误。去监控上查看一下,是Redis内存爆掉了,当时我慌的一批。
经过我半个多小时的百度,总算是找到了解决问题的办法。然后我一顿操作猛如虎,可算是解决问题了,下面我来回顾一下。
Redis提供了一个配置参数maxmemory来限制内存超出期望大小。当实际内存超出 maxmemory 时,Redis 提供了几种可选策略 (maxmemory-policy) 来让 用户自己决定该如何腾出新的空间以继续提供读写服务。
名词解释:
LRU:表示最近最少使用
LFU:表示使用频率最低
我们可以在redis.conf这个redis默认的配置文件中查看详细说明。
我们可以通过 Redis 的命令 CONFIG GET parameter 来查看当前Redis 运行的配置参数
127.0.0.1:6379> CONFIG GET *memory*
1) "maxmemory"
2) "0"
3) "maxmemory-samples"
4) "5"
5) "maxmemory-policy"
6) "noeviction"
通过 * 号通配符,我们看到 maxmemory-policy 的值为:noeviction,是不允许淘汰的。这个配置会导致当Redis内存满的时候拒绝写的请求,当Redis开始使用swap交换区的时候,你的读请求会超乎想象的慢。
下面我使用 CONFIG SET 命令修改 Redis 的 maxmemory-policy 参数。使用此命令时不需要重启Redis,这也太友好了吧
定修改为 volatile-lru,只要简单的执行一条命令就好了
127.0.0.1:6379> CONFIG SET maxmemory-policy volatile-lru
OK
127.0.0.1:6379>
#再次确认下是否修改成功
127.0.0.1:6379> CONFIG GET *memory*
1) "maxmemory"
2) "0"
3) "maxmemory-samples"
4) "5"
5) "maxmemory-policy"
6) "volatile-lru"
未完待续……