导读
前面文章【一、深入理解redis之需要掌握的知识点 】中,我们对redis需要学习的内容框架进行了一个梳理。
【二、redis中String和List两种数据类型和应用场景 】、【二、redis中Hash、Set、SortedSet应用场景 】两篇文章我们对redis中String、List、Hash、Set、SortedSet五种数据类型做了一下讲解,并且对他们各自的应用场景进行了介绍。
【三、redis数据存储之跳跃表(SKIP LIST) 】深入学习了支撑SortedSet排序背后的数据结构,跳跃表;
【四、redis持久化之RDB与AOF 】学习了redis中的两种持久化策略:RDB(快照)和AOF(追加日志); 【五、redis集群进化过程 】文章中我们学习了redis集群的进化过程,包括解决单点故障问题和性能瓶颈问题等。 【六、redis中AKF问题解决方案 】讲解了Redis使用及集群进化过程中AKF问题的解决方案。 【七、redis中CAP问题解决方案-Paxos理论过半通过 】我们讲解了Redis使用过程中出现CAP问题的解决方案,以及初步认识Paxos分布式一致性协议。 【八、redis中布式锁的实现及原理 】讲解了redis中布式锁的理论、原理及解决方案。
【九、redis缓存的回收策略-LRU算法】我们讲解了redis中如何配置缓存回收策略及回收策略的几种模式,另外还要讲解回收策略的执行过程和redis中实际使用的回收策略。
【十、redis中的哨兵模式(Sentinel)】中讲解了Redis中的哨兵模式,包括如何配置哨兵模式、哨兵模式下的客观下线和主观下线及故障转移策略等。
【十一、redis中的事物】讲解了redis中的事物,包括如何开启事物,如何使用事物做日常操作等。
从【十二、初识redis集群】开始,我们学习redis集群,包括redis集群的使用、搭建及redis集群内部原理等。【十二、初识redis集群】中主要先初识redis集群,了解他的优势及模型等。
本章中我们主要学习,如何搭建redis集群、如何使用redis集群、redis集群中数据的键是如何分配的以及redis集群中每个节点的属性。
如果大家在工作、学习、面试中针对redis还有什么疑问或者其他问题,可以评论区告诉我。
使用集群->
使用最多的时java客户端, Jedis
最近添加了对集群的支持。
搭建集群->
通过使用 Redis 集群命令行工具 redis-trib .
测试 Redis 集群->
比较简单的办法就是使用 redis-rb-cluster 或者 redis-cli
。
Redis 集群协议中的客户端和服务器端->
所有的集群节点都通过TCP连接(TCP bus?)和一个二进制协议(集群连接,cluster bus)建立通信。 每一个节点都通过集群连接(cluster bus)与集群上的其余每个节点连接起来。节点们使用一个 gossip
协议来传播集群的信息。
由于集群节点不能代理(proxy)请求,所以客户端在接收到重定向错误(redirections errors) -MOVED 和 -ASK 的时候, 将命令重定向到其他节点。
理论上来说,客户端是可以自由地向集群中的所有节点发送请求,在需要的时候把请求重定向到其他节点,所以客户端是不需要保存集群状态。 不过客户端可以缓存键值和节点之间的映射关系,这样能明显提高命令执行的效率。
*键哈希标签(Keys hash tags)->
计算哈希槽可以实现哈希标签(hash tags),但这有一个例外。哈希标签是确保两个键都在同一个哈希槽里的一种方式。将来也许会使用到哈希标签,例如为了在集群稳定的情况下(没有在做碎片重组操作)允许某些多键操作。
为了实现哈希标签,哈希槽是用另一种不同的方式计算的。基本来说,如果一个键包含一个 “{…}” 这样的模式,只有 { 和 } 之间的字符串会被用来做哈希以获取哈希槽。但是由于可能出现多个 { 或 },计算的算法如下:
如果键包含一个 { 字符。
那么在 { 的右边就会有一个 }。
在 { 和 } 之间会有一个或多个字符,第一个 } 一定是出现在第一个 { 之后。 然后不是直接计算键的哈希,只有在第一个 { 和它右边第一个 } 之间的内容会被用来计算哈希值。
例子:
- 比如这两个键 {user1000}.following 和 {user1000}.followers 会被哈希到同一个哈希槽里,因为只有
user1000 这个子串会被用来计算哈希值。 - 对于 foo{}{bar} 这个键,整个键都会被用来计算哈希值,因为第一个出现的 {
和它右边第一个出现的 } 之间没有任何字符。 - 对于 foozap 这个键,用来计算哈希值的是 {bar 这个子串,因为它是第一个 {
及其右边第一个 } 之间的内容。 - 对于 foo{bar}{zap} 这个键,用来计算哈希值的是 bar这个子串,因为算法会在第一次有效或无效(比如中间没有任何字节)地匹配到 { 和 } 的时候停止。
- 按照这个算法,如果一个键是以 {}
开头的话,那么就当作整个键会被用来计算哈希值。当使用二进制数据做为键名称的时候,这是非常有用的。
集群节点属性->
在集群中,每个节点都有一个唯一的名字。节点名字是一个十六进制表示的160 bit 随机数,这个随机数是节点第一次启动时获得的(通常是用 /dev/urandom)
。 节点会把它的ID保存在配置文件里,以后永远使用这个ID,只要这个节点配置文件没有被系统管理员删除掉。节点ID是用于在整个集群中标识每个节点。
一个给定的节点可以在不改变节点ID的情况下改变 IP 和地址。集群能检测到 IP 或端口的变化,然后使用在集群连接(cluster bus)上的 gossip 协议来发布广播消息,通知配置变更。
每个节点都有其他相关信息是所有节点都知道的:
- 节点的 IP 地址和 TCP 端口号。
-各种标识。
-节点使用的哈希槽。
-最近一次用集群连接发送 ping 包的时间。
-最近一次在回复中收到一个 pong 包的时间。
-最近一次标识节点失效的时间。
-该节点的从节点个数。
-如果该节点是从节点,会有主节点ID信息。(如果它是个主节点则该信息置为0000000…)
使用 CLUSTER NODES
命令可以获得以上的一些信息,这个命令可以发送到集群中的所有节点,无论主节点还是从节点。 下面的例子是在一个只有三个节点的小集群中发送 CLUSTER NODES 命令到一个主节点得到的输出。
$ redis-cli cluster nodes
d1861060fe6a534d42d8a19aeb36600e18785e04 127.0.0.1:6379 myself - 0 1318428930 1 connected 0-1364
3886e65cc906bfd9b1f7e7bde468726a052d1dae 127.0.0.1:6380 master - 1318428930 1318428931 2 connected 1365-2729
d289c575dcbc4bdd2931585fd4339089e461a27d 127.0.0.1:6381 master - 1318428931 1318428931 3 connected 2730-4095
在上面罗列出来的信息中,各个域依次表示的是:节点ID,IP地址:端口号,标识,上一次发送 ping 包的时间,上一次收到 pong 包的时间,连接状态,节点使用的哈希槽
。
后续redis中将要讲解的内容梳理