共计 2309 个字符,预计需要花费 6 分钟才能阅读完成。
作者:王悦
Copyright (C) 2021 wingYue
本文起源:原创投稿
* 爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。
redis 作为一个高性能的内存数据库被广泛应用于各类零碎中,比方排行榜、评分服务等等。咱们在抉择 redis 时除了思考其提供的数据类型和性能是否满足业务需要之外,十分重要的一点是思考高可用性。redis 提供了 redis sentinel 来实现高可用机制,sentinel 会监控 redis 主从实例,提供主动故障切换性能。
然而随之而来一个问题是 client 在故障切换后如何得悉以后的 master 实例地址?
主从架构办法一: 应用 redis sentinel 的服务发现
redis sentinel 提供了一个服务发现机制,连贯 sentinel 执行“SENTINEL get-master-addr-by-name”,会返回以后 master 实例地址,故障切换后,返回后果也会更新为新的 master 实例地址:
有很多“聪慧”的 redis client 库都实现了基于该服务发现机制的主动连贯,只有将 sentinel 的地址列表传入,clinet 会通过 sentinel 获取以后最新的 master 地址,而后应用获取的地址连贯。比方 jedis:
sentinels.add(new HostAndPort("192.168.0.31",26379).toString());
sentinels.add(new HostAndPort("192.168.0.32",26379).toString());
sentinels.add(new HostAndPort("192.168.0.33",26379).toString());
pool = new JedisSentinelPool(masterName, sentinels, config, TIMEOUT,password);
...
// 获取连贯:Jedis jedis = pool.getResource();
try {jedis.set("hello", "jedis");
} finally {jedis.close();
}
jedis 作为一个优良的 redis 客户端,其应用的订阅 sentinel 的形式是时刻在内存中保护最新的 master 地址。而一些其余的 client 则是在每次获取连贯时,先询问 sentinel 最新 master 地址,而后再执行 redis 连贯,这样每次操作都须要发送两次申请,并不是十分高效。另一种形式是应用 VIP:
主从架构办法二:绑定 VIP
咱们保护一个 VIP,使其始终绑定在 master 节点上,这样 client 连贯时就能够无脑地连贯 VIP 地址。VIP 的保护能够通过 sentinel 的 client-reconfig-scrip t 脚本实现,每次 sentinel 监控的主从实例产生故障切换后,sentinel 都会调用该脚本并传入最新的 master 地址,咱们能够在脚本内实现 VIP 的绑定和解绑操作。
绑定 VIP 不依赖于 client 的“聪慧”,通过自定义脚本实现,比拟灵便可控,然而 VIP 对于一些外网拜访场景无奈反对。当然因为脚本是自定义的,比方有 DNS 零碎,则能够将绑定 VIP 换成绑定 DNS,去提供外网的拜访能力。
主从架构办法三: 应用 keepalived VRRP
办法三与办法二相似,都是通过 VIP 提供服务入口,办法三应用 keepalived 的 VRRP 来实现 VIP 绑定,不依赖于 sentinel 的 reconfig 脚本。
主从架构办法四:中间件代理
一些私有云的 redis 服务都提供了一个 Proxy 地址用于 client 的拜访,该地址前面理论就对应了一个中间件代理。实现一个中间件除了须要开发成本,还须要在运行时保护中间件自身的高可用,当然花了老本就会带来收益。中间件除了实现根底的连贯转发以外,还能提供更多的高阶性能,比方阿里云的 redis Proxy 提供了:
1、proxy 将写命令发送到 master 节点,将读命令依据权重发送到 master 或 slave 节点
2、proxy 会下线异样的只读节点,待节点复原后再从新启用
以上咱们是针对 redis 主从架构,探讨了故障切换后 client 如何可能连贯上正确的 master 节点。
上面咱们针对 redis 集群架构下,探讨 client 如何正确连贯上本次操作波及的 slot 须要拜访的节点?
集群架构办法一:申请重定向
重定向指的是 client 会随机筛选一个 redis 实例进行申请操作,redis 实例收到申请后会计算 key 对应的 slot,如果在本地则间接解决,否则会返回一个 MOVED 给 client,指明正确的实例地址,让 client 进行重定向。比方 redis-cli 工具就是应用的重定向形式:
redis-cli 在收到 MOVED 响应后会主动重定向到指定的地址,这样做的一个问题是可能一次操作会须要两次申请,比拟影响性能。
集群架构办法二:本地缓存 slots 列表
“聪慧”的 client (比方 JedisCluster) 会在启动时通过拜访集群中任意节点,获取 slots 信息,在本地缓存一份所有 slots 所对应的节点列表。这样当 slots 没有产生迁徙时,可能保障操作申请被间接发送到正确的节点上。而当集群中产生了 slots 迁徙之后,某些申请会返回谬误,此时 client 会从新更新缓存中的 slots 列表,而后再次申请。因为 slots 迁徙并不是一个高频操作,这样的做法对总体性能影响不大。
集群架构办法三:中间件代理
万能的中间件,和主从架构相似,这里就不具体探讨了,如果 client 不够”聪慧“,能够把锅丢给中间件。当然实现中间件的老本和收益成正比,须要依据理论状况抉择。