`
uule
  • 浏览: 6358469 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

Redis 集群分片原理

 
阅读更多

Redis的分片机制

Redis集群分片原理

Redis集群方案总结

 

Redis Cluster搭建高可用Redis服务器集群

Redis Cluster 搭建高可用Redis服务器集群2

 

为什么Redis集群有16384个槽 

CRC16算法产生的hash值有16bit,该算法可以产生2^16-=65536个值。换句话说,值是分布在0~65535之间。那作者在做mod运算的时候,为什么不mod65536,而选择mod16384?

 

redis集群内节点,每秒都在发ping消息。规律如下

(1)每秒会随机选取5个节点,找出最久没有通信的节点发送ping消息

(2)每100毫秒(1秒10次)都会扫描本地节点列表,如果发现节点最近一次接受pong消息的时间大于cluster-node-timeout/2 则立刻发送ping消息

因此,每秒单节点发出ping消息数量为数量=1+10*num(node.pong_received>cluster_node_timeout/2)

 

(1)如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大。如上所述,在消息头中,最占空间的是myslots[CLUSTER_SLOTS/8]。当槽位为65536时,这块的大小是:65536÷8÷1024=8kb

因为每秒钟,redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65536,这个ping消息的消息头太大了,浪费带宽

 

(2)redis的集群主节点数量基本不可能超过1000个。如上所述,集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。因此redis作者,不建议redis cluster节点数量超过1000个。那么,对于节点数在1000以内的redis cluster集群,16384个槽位够用了。没有必要拓展到65536个。

 

(3)槽位越小,节点少的情况下,压缩比高Redis主节点的配置信息中,它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中,会对bitmap进行压缩,但是如果bitmap的填充率slots / N很高的话(N表示节点数),bitmap的压缩率就很低。如果节点数很少,而哈希槽数量很多的话,bitmap的压缩率就很低。

ps:文件压缩率指的是,文件压缩前后的大小比。

 

综上所述,作者决定取16384个槽,不多不少,刚刚好!

 

 ===========================================================================

是否使用过Redis集群,集群的原理是什么?

Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。

Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储

 

集群要实现的目的是要将不同的 key 分散放置到不同的 redis 节点,这里我们需要一个规则或者算法,

通常的做法是获取 key 的哈希值,然后根据节点数来求模但这种做法有其明显的弊端,当我们需要增加或减少一个节点时,会造成大量的 key 无法命中,这种比例是相当高的,所以就有人提出了一致性哈希的概念。

 

一致性哈希有四个重要特征:

 

均衡性:也有人把它定义为平衡性,是指哈希的结果能够尽可能分布到所有的节点中去,这样可以有效的利用每个节点上的资源。

单调性:当节点数量变化时哈希的结果应尽可能的保护已分配的内容不会被重新分派到新的节点。

分散性和负载:这两个其实是差不多的意思,就是要求一致性哈希算法对 key 哈希应尽可能的避免重复

 

 

但是:

Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。

 

Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽(Slot),集群的每个节点负责一部分hash槽。

这种结构很容易添加或者删除节点,并且无论是添加删除或者修改某一个节点,都不会造成集群不可用的状态。

 

使用哈希槽的好处就在于可以方便的添加或移除节点。

 

当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;

当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了;

 

在这一点上,我们以后新增或移除节点的时候不用先停掉所有的 redis 服务。

 

举个例子,比如当前集群有3个节点,那么:

节点 A 包含 0 到 5500号哈希槽.

节点 B 包含5501 到 11000 号哈希槽.

节点 C 包含11001 到 16384号哈希槽.

 

这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上。如果我想移除节点A,需要将A中得槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可.

由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.

 

 

Redis集群中内置了16384个哈希槽,当需要在Redis集群中放置一个key-value时,redis先对key使用crc16算法算出一个结果,然后把结果对16384求余数,这样每个key都会对应一个编号在0-16383之间的哈希槽,redis会根据节点数量大致均等的将哈希槽映射到不同的节点

 

这个是redis集群模式示意图,将16384个槽slot分到不同的服务器上去



 

Key:a

计算a的hash值,例如值为100,100这个槽在server1上,所以a应该放到server1.

Key:hello

Hash值:10032,此槽在server2上。Hell可以应该存在server2.

===============================================================

Redis-Cluster

 

redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在【这种模式下每台redis服务器都存储相同的数据】,很浪费内存,所以在【redis3.0上加入了cluster模式,实现的redis的分布式存储】,【也就是说每台redis节点上存储不同的内容】。

 

Redis-Cluster采用无中心结构,它的特点如下:

 

1. 【所有的redis节点彼此互联(PING-PONG机制)】,内部使用二进制协议优化传输速度和带宽。

2. 节点的fail是通过集群中【超过半数的节点检测失效】时才生效。

3. 客户端与redis节点直连,不需要中间代理层。客户端不需要连接集群所有节点,【客户端连接集群中任何一个可用节点即可】。

 

redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster负责维护node<->slot<->value。

Redis集群预分好16384个桶,当需要在Redis集群中放置一个key-value 时,【根据CRC16(key) mod 16384的值,决定将一个key放到哪个桶中】。

 

要让集群正常工作至少需要3个主节点,一共就需要6个节点,其中3个为主节点,3个为从节点

 

 

工作方式:

 

在redis的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383。还有一个就是cluster,可以理解为是一个集群管理的插件。

当我们的存取的key到达的时候,redis会根据crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,【通过这个值,去找到对应的插槽所对应的节点】【然后直接自动跳转到这个对应的节点上进行存取操作】。

 

Cluster集群采用了P2P的模式,完全去中心化,Redis把所有的Key分成了16384个slot,【每个Redis实例负责其中一部分slot】,集群中的所有信息(节点、端口、slot等),都通过节点之间定期的数据交换而更新,Redis客户端可以在任意一个Redis实例发出请求,如果所需数据不在该实例中,通过重定向命令引导客户端访问所需的实例。

 

【为了保证高可用,redis-cluster集群引入了主从模式】,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。当其它主节点ping一个主节点A时,如果半数以上的主节点与A通信超时,那么认为主节点A宕机了。如果主节点A和它的从节点A1都宕机了,那么该集群就无法再提供服务了。

 

 

选举容错

 

(1) 领导选举过程是集群中所有master参与,如果半数以上master节点与故障节点通信超过(cluster-node-timeout),认为该节点故障,自动触发故障转移操作.

 

(2) 什么时候整个集群不可用(cluster_state:fail)

 

a:【如果集群任意master挂掉,且当前master没有slave.集群进入fail状态】,也可以理解成集群的slot映射[0-16383]不完成时进入fail态.

redis-3.0.0.rc1加入cluster-require-full-coverage参数,默认关闭,打开集群兼容部分失败.

 

b:如果集群【超过半数以上master挂掉,无论是否有slave集群进入fail状态】.

 

ps:当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误 

 

===============================================================

Redis集群的目的是实现数据的横向伸缩,把一块数据分片保存到多个机器,可以横向扩展数据库大小,扩展带宽,计算能力等。 

 

实现数据分片(集群)方式大致有三种: 

 

1)客户端实现数据分片

 

客户端自己计算数据的key应该在哪个机器上存储和查找。

此方法的好处是降低了服务器集群的复杂度,客户端实现数据分片时,服务器是独立的,服务器之前没有任何关联。多数redis客户端库实现了此功能,也叫sharding。

这种方式的缺点是客户端需要实时知道当前集群节点的联系信息,同时,当添加一个新的节点时,客户端要支持动态sharding.,多数客户端实现不支持此功能,需要重启redis。另一个弊端是redis的HA需要额外考虑。

 

2)服务器实现数据分片

 

其理论是,客户端随意与集群中的任何节点通信,服务器端负责计算某个key在哪个机器上,当客户端访问某台机器时,服务器计算对应的key应该存储在哪个机器,然后把结果返回给客户端,客户端再去对应的节点操作key,是一个重定向的过程,此方式是redis3.0正在实现,目前处于beta版本, Redis 3.0的集群同时支持HA功能,某个master节点挂了后,其slave会自动接管。

 

服务器端实现集群需要客户端语言实现服务器集群的协议,目前java,php,ruby语言多数有redis-cluster客户端实现版本。 

 

Redis Cluster原理http://www.cnblogs.com/foxmailed/p/3630875.html

 

Redis Cluster 是Redis的集群实现,内置数据自动分片机制,集群内部将所有的key映射到16384个Slot中,集群中的每个Redis Instance负责其中的一部分的Slot的读写。集群客户端连接集群中任一Redis Instance即可发送命令,当Redis Instance收到自己不负责的Slot的请求时,会将负责请求Key所在Slot的Redis Instance地址返回给客户端,客户端收到后自动将原请求重新发往这个地址,对外部透明。一个Key到底属于哪个Slot由crc16(key) % 16384 决定。

 

关于负载均衡,集群的Redis Instance之间可以迁移数据,以Slot为单位,但不是自动的,需要外部命令触发。 

 

关于集群成员管理,集群的节点(Redis Instance)和节点之间两两定期交换集群内节点信息并且更新,从发送节点的角度看,这些信息包括:集群内有哪些节点,IP和PORT是什么,节点名字是什么,节点的状态(比如OK,PFAIL,FAIL,后面详述)是什么,包括节点角色(master 或者 slave)等。 

 

关于可用性,集群由N组主从Redis Instance组成。主可以没有从,但是没有从 意味着主宕机后主负责的Slot读写服务不可用。 

 

一个主可以有多个从,主宕机时,某个从会被提升为主,具体哪个从被提升为主,协议类似于Raft,参见这里。如何检测主宕机?Redis Cluster采用quorum+心跳的机制。从节点的角度看,节点会定期给其他所有的节点发送Ping,cluster-node-timeout(可配置,秒级)时间内没有收到对方的回复,则单方面认为对端节点宕机,将该节点标为PFAIL状态。通过节点之间交换信息收集到quorum个节点都认为这个节点为PFAIL,则将该节点标记为FAIL,并且将其发送给其他所有节点,其他所有节点收到后立即认为该节点宕机。从这里可以看出,主宕机后,至少cluster-node-timeout时间内该主所负责的Slot的读写服务不可用。 

 

Redis Cluster Slots是什么?http://www.zhizhihu.com/html/y2014/4590.html

 

 

 

 

3)通过代理服务器实现数据分片

 

此方式是借助一个代理服务器实现数据分片,客户端直接与proxy联系,proxy计算集群节点信息,并把请求发送到对应的集群节点。降低了客户端的复杂度,需要proxy收集集群节点信息。Twemproxy是twitter开源的,实现这一功能的proxy。这个实现方式在客户端和服务器之间加了一个proxy,但这是在redis 3.0稳定版本出来之前官方推荐的方式。结合redis-sentinel的HA方案,是个不错的组合。

 

 

  • 大小: 65.3 KB
分享到:
评论

相关推荐

    springcloud部署redis集群

    Redis集群通过数据分片(Sharding)技术,将数据分散存储在多个节点上,每个节点只负责一部分数据,从而实现数据的水平扩展。每个节点都是独立的Redis实例,可以处理读写请求。集群中的节点之间通过Gossip协议进行...

    redis集群连接及工具类DEMO

    Redis集群采用分片(Sharding)策略来分布数据,将键空间划分为多个槽(Slots),每个节点负责一部分槽。当客户端对某个键进行操作时,会根据槽的映射规则确定操作的目标节点,从而实现负载均衡。 2. **Spring集成...

    redis集群 三主三从模式

    Redis集群通过分片(Sharding)技术将数据分割成多个部分,并将这些部分分配到不同的节点上。每个节点负责一部分数据的读写操作。在这种三主三从的配置中,每个主节点都有一个对应的从节点,用于数据备份和故障转移...

    redis集群批处理一键搭建

    Redis集群是Redis提供的分布式解决方案,它将数据分散存储在多个节点上,通过一致性哈希算法实现数据的分片和负载均衡。每个节点都存储部分数据,同时负责处理一部分客户端请求。当需要扩展存储能力或处理能力时,...

    Redis Cluster集群数据分片机制原理

    在 Redis Cluster 中,数据分片是核心机制,它将数据分散到多个节点上,以实现负载均衡和存储容量的扩展。 Redis 集群通常由至少六个节点组成,其中包括三个主节点和三个从节点。主节点负责处理读写请求,从节点则...

    redis集群槽点.zip

    这些图片有助于直观地理解集群的工作原理和操作流程,对于学习和部署Redis集群非常有帮助。 为了更深入地掌握Redis集群,你需要了解以下知识点: 1. 集群搭建:包括初始化节点、配置集群、添加节点、槽点分配等...

    redis集群,使用ruby脚本搭建集群

    Redis 集群是通过数据分片(Sharding)实现的,即将数据分散存储在多个节点上,每个节点负责一部分数据。这种方式能够确保系统的高可用性和可伸缩性。Redis 集群不支持主从复制模式下的写入操作,而是采用槽(Slot)...

    redis集群第三方库

    而当 Redis 部署为集群模式时,数据会自动分片到多个节点,以实现水平扩展和高可用性。这时,客户端库的角色就显得尤为重要,它们负责正确地路由命令到对应的节点,处理槽移动(slot migration)以及处理节点间的...

    redis集群部署包.rar

    Redis 集群采用了分片(Sharding)策略,数据被分散到多个节点上,每个节点负责一部分数据。通过一致性哈希算法,确保数据与节点的映射关系相对稳定,当新节点加入或节点离开时,数据迁移的影响最小化。 2. **节点...

    Redis集群的相关详解

    Redis集群在3.0版本之后引入,它采用哈希槽(Hash Slot)的方式进行数据分片,以实现数据的分散和均衡。 1. Redis简介 Redis是一个基于键值对的NoSQL数据库,由C语言编写,具有高性能和丰富的数据结构,如字符串、...

    redis集群搭建相关文件

    Redis集群是通过分片(Sharding)技术将数据分散到多个节点上,每个节点负责一部分数据的存储和读写操作。它采用无中心结构,所有节点间相互通信,共同维护整个集群的状态。在Redis集群中,数据被分为16384个槽...

    redis-trib.rb redis集群搭建使用

    Redis 集群采用分片(Sharding)策略,将数据分散存储在多个节点上,每个节点负责一部分数据。集群由多个主节点(Master)和对应的从节点(Slave)组成,主节点负责读写操作,从节点负责备份数据并提供读服务。当主...

    redis一键部署集群脚本

    Redis集群(Redis Cluster)是Redis提供的分布式解决方案,通过数据分片(Sharding)实现水平扩展。在集群中,数据被分割成多个槽(Slots),每个节点负责一部分槽,所有节点共同存储整个数据集。集群支持读写操作的...

    第6章 Redis集群环境部署.pptx

    ### 第6章 Redis集群环境部署 #### 一、主从复制 **概念与特点:** 主从复制是Redis实现高可用性的一种基础架构模式。它允许数据从一个服务器(称为Master)复制到一个或多个其他服务器(称为Slaves)。这种复制...

    Redis安装包和集群配置包

    4. **数据分布**:Redis集群使用一致性哈希算法将键分片到不同的节点,每个槽对应一个节点。默认情况下,集群有16384个槽。 5. **监控和故障转移**:Redis集群会自动监控节点状态,并在主节点故障时触发故障转移,...

    大规模redis集群的服务治理之路

    ##### 分片原理 - **数据分片**: 每个节点负责一部分槽的数据存储,并且每个节点都会维护整个集群的槽到节点的映射关系。 - **初始化**: 在集群初始化时确定槽与节点之间的映射关系。 - **扩容与缩容**: 通过槽迁移...

    redis集群所需文件

    2. **数据分片**:Redis集群将数据集分为16384个槽(slots),每个槽对应一部分数据。当添加新键时,根据CRC16校验和对键名进行哈希,然后分配到相应的槽上,确保数据均匀分布。 3. **槽迁移**:在集群中添加或移除...

    Redis 集群搭建手册

    Redis 集群是Redis的一种高可用性和可扩展性解决方案,允许数据分散在多个节点上,以实现数据的冗余和故障转移。...通过理解集群的工作原理和配置过程,你可以根据具体需求设计出适合自己应用场景的Redis集群架构。

    liunx下redis3.0.0集群负载均衡文档完整部署带所有安装包(redis集群)

    - Redis集群通过分片(Sharding)将数据分散到多个节点上,每个节点负责一部分数据,实现数据的水平扩展。 - 集群中的每个节点都有一个槽(Slot),总共16384个槽,用于均匀分配数据。 - 主从复制(Replication)...

Global site tag (gtag.js) - Google Analytics