redis集群的多种模式
what:
常用的模式:
1、Redis 单副本
2、Redis 多副本(主从)
3、Redis Sentinel(哨兵)
4、Redis Cluster
5、Redis 自研
Redis 单副本:
采用单个Redis 节点部署架构,没有备用节点实时同步数据,不提供数据持久化和备份策略,适用于数据可靠性要求不高的纯缓存业务场景。
缺点:1、不保证数据的可靠性;
2、在缓存使用,进程重启后,数据丢失;
3、高性能受限于单核 CPU 的处理能力(Redis 是单线程机制),CPU 为主要瓶颈,所以适合操作命令简单,排序、计算较少的场景。也可以考虑用 Memcached 替代;
Redis 多副本(主从):
为了避免单点故障 和 读写不分离,Redis 提供了复制(replication)功能实现master数据库中的数据更新后,会自动将更新的数据同步到其他slave数据库上。
Redis 多副本,采用主从(replication)部署结构,相较于单副本而言最大的特点就是主从实例间数据实时同步,并且提供数据持久化和备份策略。主从实例部署在不同的物理服务器上,根据公司的基础环境配置,可以实现同时对外提供服务和读写分离策略。
在同步中,如果master的slave过多,会影响master的性能。采用的解决方式是:master-slave-slave模式,即:一个master可以有多个salve节点;salve节点可以有slave节点,从节点是级联结构,如下:
缺点:如果没有 RedisHA 系统(需要开发),当主库节点出现故障时,需要手动将一个从节点晋升为主节点,同时需要通知业务方变更配置,并且需要让其它从库节点去复制新主库节点,整个过程需要人为干预,比较繁琐。
具体操作:
a、在从数据库中使用SLAVE NO ONE命令将从数据库提升成主数据继续服务。
b、启动之前崩溃的主数据库,然后使用SLAVEOF命令将其设置成新的主数据库的从数据库,即可同步数据。
哨兵模式:
该模式部署架构主要包括两部分:Redis Sentinel 集群和 Redis 数据集群。
其中 Redis Sentinel 集群是由若干 Sentinel 节点组成的分布式集群,可以实现故障发现、故障自动转移、配置中心和客户端通知。Redis Sentinel 的节点数量要满足 2n+1(n>=1)的奇数个。
第一种主从同步/复制的模式,当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用,这时候就需要哨兵模式登场了。哨兵模式是从Redis的2.6版本开始提供的,但是当时这个版本的模式是不稳定的,直到Redis的2.8版本以后,这个哨兵模式才稳定下来。
哨兵模式核心还是主从复制,只不过在相对于主从模式在主节点宕机导致不可写的情况下,多了一个竞选机制:从所有的从节点竞选出新的主节点。竞选机制的实现,是依赖于在系统中启动一个sentinel进程。
在一个一主多从的Redis系统中,可以使用多个哨兵进行监控,哨兵不仅会监控主数据库和从数据库,哨兵之间也会相互监控。每一个哨兵都是一个独立的进程,作为进程,它会独立运行。
一主二从三哨兵的具体模式:
client里面有哨兵的ip和port,哨兵通过选举,告诉client,redis的服务器ip和port,这样client就能连接服务器。主redis出现宕机,那么哨兵也会通过同样的方式告诉client应该连接哪个redis服务器。
哨兵原理:
主观下线:sentinel 会以每秒一次的频率向所有节点(其他sentinel、主节点、以及从节点)发送 ping 消息,然后通过接收返回判断该节点是否下线;如果在配置指定 down-after-milliseconds 时间内,sentinel收到的都是无效回复, 则被判断为主观下线;
客观下线:当一个 sentinel 节点将一个主节点判断为主观下线之后,为了确认这个主节点是否真的下线,它会向其他sentinel 节点进行询问(发松(SENTINEL is-master-down-by-addr)询问其他哨兵节点是否认为该主节点是主观下线),如果收到一定数量的已下线回复(当达到指定数量(quorum)时),sentinel 会将主节点判定为客观下线,并通过领头 sentinel 节点对主节点执行故障转移();
故障转移:主节点被判定为客观下线后,开始领头 sentinel 选举,需要一半以上的 sentinel 支持,选举领头sentinel后,开始执行对主节点故障转移;
a、从从节点中选举一个从节点作为新的主节点
>领头哨兵所有的slave选出优先级最高的从数据库。优先级可以通过slave-priority选项设置。
>如果优先级相同,则从复制的命令偏移量越大(即复制同步数据越多,数据越新),越优先。
>如果以上条件都一样,则选择run ID较小的从数据库。
b、通知其他从节点复制连接新的主节点
c、若故障主节点重新连接,将作为新的主节点的从节点
哨兵模式依赖步骤:
1、每隔10s向master和 slave发送info命令。作用是获取当前数据库信息,比如发现新增从节点时,会建立连接,并加入到监控列表中,当主从数据库的角色发生变化进行信息更新。
2、每隔2s向主数据里和从数据库的_sentinel_:hello频道发送自己的信息。作用是将自己的监控数据和哨兵分享。每个哨兵会订阅数据库的_sentinel:hello频道,当其他哨兵收到消息后,会判断该哨兵是不是新的哨兵,如果是则将其加入哨兵列表,并建立连接。
3、每隔1s向所有主从节点和所有哨兵节点发送ping命令,作用是监控节点是否存活。
Redis Cluster:
Redis Cluster 是社区版推出的 Redis 分布式集群解决方案,主要解决 Redis 分布式方面的需求,比如,当遇到单机内存,并发和流量等瓶颈的时候,Redis Cluster 能起到很好的负载均衡的目的。
Redis Cluster 集群节点最小配置 6 个节点以上(3 主 3 从),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。
Redis Cluster 采用虚拟槽分区,所有的键根据哈希函数映射到 0~16383 个(2的14次幂)整数槽内,每个节点负责维护一部分槽以及槽所印映射的键值数据。
redis在3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的数据。cluster模式为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性。Redis Cluster是一种服务器Sharding技术(分片和路由都是在服务端实现),采用多主多从,每一个分区都是由一个Redis主机和多个从机组成,片区和片区之间是相互平行的。Redis Cluster集群采用了P2P的模式,完全去中心化。
redis cluster主要是针对海量数据+高并发+高可用的场景,海量数据,如果你的数据量很大,那么建议就用redis cluster,数据量不是很大时,使用sentinel就够了。redis cluster的性能和高可用性均优于哨兵模式。
缺点:1、结构复杂;2、Key 事务操作支持有限,只支持多 key 在同一节点上的事务操作;3、Key 作为数据分区的最小粒度,不能将一个很大的键值对象如 hash、list 等映射到不同的节点;
自研型:
1、客户端分片:
把分片的逻辑放在Redis客户端实现,(比如:jedis已支持Redis Sharding功能,即ShardedJedis),通过Redis客户端预先定义好的路由规则(使用一致性哈希),把对Key的访问转发到不同的Redis实例中,查询数据时把返回结果汇集。这种方案的模式如图所示。
特点:1、可控(好):客户端sharding技术使用hash一致性算法分片的好处是所有的逻辑都是可控的,不依赖于第三方分布式中间件;
2、运维成本高(缺);
2、代理分片:
redis代理分片用得最多的就是Twemproxy,由Twitter开源的Redis代理,其基本原理是:通过中间件的形式,Redis客户端把请求发送到Twemproxy,Twemproxy根据路由规则发送到正确的Redis实例,最后Twemproxy把结果汇集返回给客户端。
Twemproxy通过引入一个代理层,将多个Redis实例进行统一管理,使Redis客户端只需要在Twemproxy上进行操作,而不需要关心后面有多少个Redis实例,从而实现了Redis集群。
Twemproxy作为最被广泛使用、最久经考验、稳定性最高的Redis代理,在业界被广泛使用。
特点:
优点:1、客户端像连接Redis实例一样连接Twemproxy,不需要改任何的代码逻辑;2、支持无效Redis实例的自动删除;3、Twemproxy与Redis实例保持连接,减少了客户端与Redis实例的连接数;
缺点:无法平滑地扩容/缩容;
3、codis
豌豆荚自主研发了Codis,一个支持平滑增加Redis实例的Redis代理软件。
在Codis的架构图中,Codis引入了Redis Server Group,其通过指定一个主CodisRedis和一个或多个从CodisRedis,实现了Redis集群的高可用。
Codis中采用预分片的形式,启动的时候就创建了1024个slot,1个slot相当于1个箱子,每个箱子有固定的编号,范围是1~1024。slot这个箱子用作存放Key,至于Key存放到哪个箱子,可以通过算法“crc32(key)%1024”获得一个数字,这个数字的范围一定是1~1024之间,Key就放到这个数字对应的slot。例如,如果某个Key通过算法“crc32(key)%1024”得到的数字是5,就放到编码为5的slot(箱子)。1个slot只能放1个Redis Server Group,不能把1个slot放到多个Redis Server Group中。1个Redis Server Group最少可以存放1个slot,最大可以存放1024个slot。因此,Codis中最多可以指定1024个Redis Server Group。
优势:在于支持平滑增加(减少)Redis Server Group(Redis实例),能安全、透明地迁移数据,这也是Codis 有别于Twemproxy等静态分布式 Redis 解决方案的地方。Codis增加了Redis Server Group后,就牵涉到slot的迁移问题(如下:)。