• 如何设计一个良好的Redis架构?Redis架构设计指南
  • 发布于 2个月前
  • 176 热度
    0 评论
  • 火凤凰
  • 0 粉丝 34 篇博客
  •   
架构的目标
在如何设计一个良好的Redis架构上,我们给自己定了个小目标——实现财务自由,对此,在这个过程应该做到以下几点:
1.快:因为在业务快速发展中,我们每天都可能上线N个系统、搭建N套集群以及业务扩容。一个良好的架构,需要能够让业务在使用方面更加快捷与友好!
2.稳:随着集群数量与机器数量上涨,运维的过程中,几乎每天都会遇到扩容、机器搬迁、维护等需求。那么底层Redis集群的节点发生变化时,应该做到保证业务不受影响。
3.准:由于宕机、误操作以及其他原因,Redis都会发生切换,如何减少误切换带来的影响,这就需要一个良好的自动化切换的机制!

架构的选型
小目标定好,架构选型就该着手了。以下我们考虑到的一些点:

1、Redis主从or Redis Cluster? 
Redis主从:稳定、维护简单,但扩容成本高,有可能在牵引的过程中业务受到影响。
Redis Cluster:维护成本高、扩容简单,相对来说较为复杂,卡死时需要研究源码,加节点操作也更困难。
所以在使用时我们选择一个Redis的主从,以及选用比较简单且稳定的版本,当然目前仍然使用2.8等,只要性能OK即可。
2、Proxy或者类似Proxy
可以隔离业务与底层Redis集群的关系,便于运维人员管理后台集群;
可以管理连接池;
可以控制HASH规则。
3、高可用
我们提供了一个Sentinel,当主机出现问题时,就可以自动地把从机提升上来。
4、元数据管理
包括前面提到的元数据,会考虑是用MySQL还是ZooKeeper来做,用ZooKeeper的好处是当节点发生变化时可以通知所有的业务端。
而对我们来说,用MySQL首先是更简单维护,也可以更清晰地看到哪个业务对应哪个节点信息。结果是,我们最初只用了ZooKeeper,随着后期的发展变成MySQL+ZooKeeper同时使用。

架构设计

这是我们Redis架构访问实例的流程图,也是去哪儿近几年在使用的架构,中间有升级过。

一开始客户端通过Proxy集群,并根据Redis节点信息来访问Redis集群,比如一个Key过来之后是通过某些一致性的Hash来进行访问的,而Redis节点信息可以理解为是由Proxy集群或访问客户端打包到它们的业务客户端里。

架构拓展——Proxy


1、变更
因为我们给每一个业务定了一个Namespace,里面存了相关信息(一些主节点信息或连接池的大小都可在这里设置)。当客户端进来后,它首先从ZK里读取Redis的信息,并根据从Namespace处拿到这个信息,如果是拿到三个节点信息就可根据上面配置的连接池大小直接建立对应多少的连接,于是这时我们业务过来的时候就已经拿到这几个节点了。

如果这时业务又来了一个Key该怎么访问?这个Key首先在Proxy或者访问客户端中通过一致性算法来进行计算,就可以把某个Key分配到集群中的一个节点上。我们都可以拿到这个节点并操作里面的数据,但会存在一个问题:节点挂了怎么办?这里就需要启动我们的一组哨兵。

哨兵可以部署在多个机房,针对每一个实例分配一组哨兵(有可能每个实例有5个哨兵进行监控)。如果主节点挂了,我们可通过哨兵选举机制将Redis的从实例提升为主实例,老的实例起来之后可自动变更为从实例。但此时业务方并不清楚他们拿到的还是以前的老实例,只是发现现在连不进去了。

这时我们通过哨兵来进行ZK信息的修改,因为哨兵切换之后就能知道哪个是新主实例,我们修改对应的信息即可,修改完之后再触发客户端,我们就能让客户端知道知道现在的新主节点是谁,知晓了之后就会把连接进行重接,进而发现客户端连到新的地方了。这就是一个简单的Redis架构。

但这个Redis架构存在一个问题:如果是集群开始为三个节点,那如何从三个节点扩容到五个节点?因为所有的数据要重新做Hash规则,我可以先搭建五个实例起来,再按照我们自己写的同步工具和新的Hash规则来分析这三个实例的AOF文件,通过不停地分析AOF文件把这三组实例数据通过新的Hash规则Hash到五个节点上去,最后通过人工修改ZK信息,告知它现在已扩容到五个节点。

如果我们同步工具运行速度跟不上Redis的写入速度,就可能导致永远无法同步完成。因此,为了不影响业务运行,我们可以对这一块进行改造。

最初我们用了一个简单的一致性Hash,接着在这上面做了二层Hash,所以第一层Hash就是这个节点,第二层Hash就是可以为简单的取余,对我们而言,这样扩容就非常简单了,可以用主从搭建的模式。

2、自定义Hash规则
我们可以自定义Hash规则,如果一层Hash解决不了问题,就搭建二层Hash,再扩容某一个节点。与之前只能扩容三个节点相比,此时可以扩容五个节点,但在做二层Hash时就可针对每一个节点进行扩容,这对于运维来说非常简单,只需要搭建两个从库即可。

3、安全
安全方面表现为对客户端进行危险命令的屏蔽,不允许一来就是危险的DEL操作,包括更危险的FLUSH操作和一些新操作。
这些操作容易导致Redis发生卡顿,因此我们要对危险的命令进行过滤。所以在做DBA运维的过程中,当节点信息发生变化时,客户端能够自动更新,包括集群信息和连接池信息等。

4、连接池

基于连接池的规则,有可能某一个节点连接数过大,可能达到8至9千甚至上万个连接,而一个客户可能不需要那么多连接,并且里面很多连接是废弃的,所以就需要我们在MySQL里修改数据池的数量,让其能在监控异常时快速响应,并通过ZK来通知,这便不会对我们的业务产生影响。

架构拓展——Sentinel


1、一对一:一组哨兵就一个节点,维修成本低一些。
2、多机房分布式:更加灵敏和准确。
3、自动切换:前提是从库一般不提供服务,在主库发生宕机时,它会进行自动切换,将新的主节点信息通过ZK和配置中心推送到业务端,让从库提升为主库。
4、通知:包括ZK业务端自动的感应,包括在业务上线时需要人工做一次哨兵的切换,同时要检测高可用、机器是否可用、架构是否有问题等,这时就可以通过哨兵修改ZK,Proxy也将自动感知。
5、DBA入场:入场之后需要查看监控信息和报警信息,确认哨兵是否做到真正切换或者ZK信息有没有更新到,包括更新后业务端有没有收到等,若没有收到,需要人工再次检测,但这种机制对我们来说稍微简单一些,因为很多东西都可以通过工具来完成的。

架构拓展——ZooKeeper
ZooKeeper主要负责两件事:记录配置信息和订阅通知。首先,它会针对每一个业务制定一个Namespace的概念,这样业务对应的多个信息都可以在这里设置。

此外,当集群节点信息发生变化后,会通过ZooKeeper来通知客户端或者Proxy,以进行快速的响应。但这有一个问题就是会在通知时有可能发生失败。

使用流程与规则

当我们设计了一个Redis架构之后可以如何使用呢?

1、描述业务需求与沟通。我们要确认业务的使用场景、容量、QPS等一系列信息。
2、制定集群模式。要设置一个良好的集群,有可能需要十到二十个节点,需要在前期制定一个模式判断是否为缓存,如果不是,报警信息是不一样的,设置信息监控点也不一样。
3、自动化搭建集群。可通过自己的工具自把一些集群快速、自动化地搭建起来。
4、部署高可用与Failover。高可用部署一定要做好Failover机制,因为有可能布上去了但没有做到真正的精细化,这样人工上线时就会出现问题。

这里我们做了一个简单的工具,即我们搭建了一套集群(里面有一百个实例),但不可能把每个实例都做检测,所以我们可以对集群进行一个级别的界定,如果是核心集群,我挑90%自动做一次Failover,如果是非核心集群,则选择60%自动做一次Failover。
5、初始化配置中心,把信息都填进去。
6、最后通知业务集群已搭建好。
自动化扩容

前文刚说了一下我们第一、二个版本的扩容方案与流程,这里再仔细梳理下。

首先我们拿到一个业务,或许是压力扛不住、反应慢了、容量不够了或运维方触发,使得运维方检测到的实际内容一开始是10G,但我们监控出来时已达到15G,这时我们也许需要扩容了。

随着日益的发展,我们一开始只定义了10个G,但慢慢地超过了10个G、20个G,因为当Redis一个节点的存储量越来越大时,运维的成本也会越来越大。此外,10G以内做主从实例搭建是非常简单的,但如果是20G或30G,做一次的恢复时间很长,所以运维方也会触发一次需求。

如何做业务扩容,事实上业务并不关心,但对运维来说就很困难了,即刚说的第一种方案:自己写同步工具去扩第一层Hash。

当我们有两层Hash时扩容很简单,搭两个从库、三个从库就行了。但这里搭完后会有一个问题:数据存在多余的数据。

也就是说,当我们做环境整理、搭建主从,只需把数据迁移过去就OK了,接着更新配置,通知业务集群好了,让他们查看一下。可这里有可能一个集群由三个节点变为五个节点了,因为每个节点在扩容后存在一部分数据是垃圾数据,而这部分数据在做Hash时是不需要的,所以我们需要根据新的Hash数据,把老的信息清理掉,人工慢慢删除就不会影响业务,这样我们的容量也扩容完成了。

优点&缺点
1、优点:
便于扩容:直接搭建从库即可。
便于调整:包括节点调整的信息、连接池的信息也可以控制,业务能做到自动感知。
维护简单。
稳定:利用有哨兵机制来进行保障。
2、缺点:
缩容复杂。三个节点怎么缩到两个节点,目前还没有想到好招,可以把最大内存调一调,比如把10个G调成5个G,当然实例个数保持不变。
客户端升级困难。因为需要把所有业务都升级一遍,所有我们目前使用的原则就是老的业务有可能还在使用第一个版本的Hash规则,新的业务则上第二个版本。
用户评论