from 等等 skiplist 数据访问 更新 1.10 都没有 daemon rst
前面已经介绍了Redis Cluster集群及其部署过程,下面再补充下有关Redis Cluster应用原理部分内容,以便更加深刻透彻地理解Redis Cluster。
一、Redis Cluster集群最核心的三个目标
二、Redis架构变化与CAP理论
Redis Cluster集群功能推出已经有一段时间了。在单机版的Redis中,每个Master之间是没有任何通信的,所以我们一般在Jedis客户端或者Codis这样的代理中做Pre-sharding。按照CAP理论来说,单机版的Redis属于保证CP(Consistency & Partition-Tolerancy)而牺牲A(Availability),也就说Redis能够保证所有用户看到相同的数据(一致性,因为Redis不自动冗余数据)和网络通信出问题时,暂时隔离开的子系统能继续运行(分区容忍性,因为Master之间没有直接关系,不需要通信),但是不保证某些结点故障时,所有请求都能被响应(可用性,某个Master结点挂了的话,那么它上面分片的数据就无法访问了)。
有了Cluster功能后,Redis从一个单纯的NoSQL内存数据库变成了分布式NoSQL数据库,CAP模型也从CP变成了AP。也就是说,通过自动分片和冗余数据,Redis具有了真正的分布式能力,某个结点挂了的话,因为数据在其他结点上有备份,所以其他结点顶上来就可以继续提供服务,保证了Availability。然而,也正因为这一点,Redis无法保证曾经的强一致性了。这也是CAP理论要求的,三者只能取其二。
三、Redis Cluster集群部署
1)集群部署和配置
这个之前已经介绍过了,部署过程参考:http://www.cnblogs.com/kevingrace/p/7846324.html
要想开启Redis Cluster模式,有几项配置是必须的,还可以额外添加一些配置:
配置好后,根据集群规模,拷贝出来几份同样的配置文件,唯一不同的就是监听端口,可以依次改为7001、7002… 因为Redis Cluster如果数据冗余是1的话,至少要3个Master和3个Slave,所以可以拷贝出6个实例的配置文件。为了避免相互影响,为6个实例的配置文件建立独立的文件夹。
2)redis-trib管理器
redis-trib依赖Ruby和RubyGems,以及redis扩展。可以先用which命令查看是否已安装ruby和rubygems,用gem list –local查看本地是否已安装redis扩展。
最简便的方法就是用apt或yum包管理器安装RubyGems后执行gem install redis。如果网络或环境受限的话,可以手动安装RubyGems和redis扩展(可以从CSDN下载):
- [root@8gVm Software]# wget https://github.com/rubygems/rubygems/releases/download/v2.2.3/rubygems-2.2.3.tgz
- [root@8gVm Software]# tar xzvf rubygems-2.2.3.tgz
- [root@8gVm Software]# cd rubygems-2.2.3
- [root@8gVm rubygems-2.2.3]# ruby setup.rb --no-rdoc --no-ri
- [root@8gVm Software]# wget https://rubygems.org/downloads/redis-3.2.1.gem
- [root@8gVm Software]# gem install redis-3.2.1.gem --local --no-rdoc --no-ri
- Successfully installed redis-3.2.1
- 1 gem installed
3)集群建立
首先,启动配置好的6个Redis实例。
- [root@8gVm redis-3.0.4]# for ((i=0; i<6; ++i));docd cfg-cluster/700$i && ../../src/redis-server redis.conf.700$i && cd -;done
此时6个实例还没有形成集群,现在用redis-trb.rb管理脚本建立起集群。可以看到,redis-trib默认用前3个实例作为Master,后3个作为Slave。因为Redis基于Master-Slave做数据备份,而非像Cassandra或Hazelcast一样不区分结点角色,自动复制并分配Slot的位置到各个结点。
- [root@8gVm redis-3.0.4]# src/redis-trib.rb create --replicas 1 192.168.1.100:7000 192.168.1.100:7001 192.168.1.100:7002 192.168.1.100:7003 192.168.1.100:7004 192.168.1.100:7005
- >>> Creating cluster
- Connecting to node 192.168.1.100:7000: OK
- Connecting to node 192.168.1.100:7001: OK
- Connecting to node 192.168.1.100:7002: OK
- Connecting to node 192.168.1.100:7003: OK
- Connecting to node 192.168.1.100:7004: OK
- Connecting to node 192.168.1.100:7005: OK
- >>> Performing hash slots allocation on 6 nodes...
- Using 3 masters:
- 192.168.1.100:7000
- 192.168.1.100:7001
- 192.168.1.100:7002
- Adding replica 192.168.1.100:7003 to 192.168.1.100:7000
- Adding replica 192.168.1.100:7004 to 192.168.1.100:7001
- Adding replica 192.168.1.100:7005 to 192.168.1.100:7002
- ...
- Can I set the above configuration? (type ‘yes‘ to accept): yes
- >>> Nodes configuration updated
- >>> Assign a different config epoch to each node
- >>> Sending CLUSTER MEET messages to join the cluster
- Waiting for the cluster to join....
- >>> Performing Cluster Check (using node 192.168.1.100:7000)
- ...
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
至此,Redis Cluster集群就已经建立成功了!“贴心”的Redis还在utils/create-cluster下提供了一个create-cluster脚本,能够创建出一个集群,类似上面建立起的3主3从的集群。
4)Redis Cluster集群简单测试
连接到集群中的任意一个结点,启动redis-cli时要加-c选项,存取两个Key-Value感受一下Redis久违的集群功能。
- [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000
- 192.168.1.100:7000> set foo bar
- -> Redirected to slot [12182] located at 192.168.1.100:7002
- OK
- 192.168.1.100:7002> set hello world
- -> Redirected to slot [866] located at 192.168.1.100:7000
- OK
- 192.168.1.100:7000> get foo
- -> Redirected to slot [12182] located at 192.168.1.100:7002
- "bar"
- 192.168.1.100:7002> get hello
- -> Redirected to slot [866] located at 192.168.1.100:7000
- "world"
仔细观察能够注意到,redis-cli根据指示,不断在7000和7002结点之前重定向跳转。如果启动时不加-c选项的话,就能看到以错误形式显示出的MOVED重定向消息。
- [root@8gVm redis-3.0.4]# src/redis-cli -h 192.168.1.100 -p 7000
- 192.168.1.100:7000> get foo
- (error) MOVED 12182 192.168.1.100:7002
5)Redis Cluster 集群重启
目前redis-trib的功能还比较弱,需要重启集群的话,需要先手动kill掉各个进程,然后重新启动就可以了。这确实有点太傻X, 网上有人反馈说重启有问题,不过本人暂时还没遇到问题。
- [root@8gVm redis-3.0.4]# ps -ef | grep redis|grep -v grep | awk ‘{print $2}‘ | xargs kill -9
6)Redis Cluster集群数据迁移
这就需要体验一下Redis集群的Resharding功能了~~
- 1)创建测试数据
- 首先保存foo1~10共10个Key-Value作为测试数据。
- [root@8gVm redis-3.0.4]# for ((i=0; i<10; ++i))
- > do
- > src/redis-cli -c -h 192.168.1.100 -p 7000 set foo$i bar
- > done
- [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000
- 192.168.1.100:7000> keys *
- 1) "foo6"
- 2) "foo7"
- 3) "foo3"
- 4) "foo2"
- 192.168.1.100:7000> get foo4
- -> Redirected to slot [9426] located at 192.168.1.100:7001
- "bar"
- 192.168.1.100:7001> keys *
- 1) "foo4"
- 2) "foo8"
- 192.168.1.100:7001> get foo5
- -> Redirected to slot [13555] located at 192.168.1.100:7002
- "bar"
- 192.168.1.100:7002> keys *
- 1) "foo5"
- 2) "foo1"
- 3) "foo10"
- 4) "foo9"
- 2)启动新结点
- 参照之前的方法新拷贝出两份redis.conf配置文件redis.conf.7010和7011,与之前结点的配置文件做一下区分。启动新的两个Redis实例之后,通过redis-trib.rb脚本添加新的Master和Slave到集群中。
- [root@8gVm redis-3.0.4]# cd cfg-cluster/7010 && ../../src/redis-server redis.conf.7010 && cd -
- [root@8gVm redis-3.0.4]# cd cfg-cluster/7011 && ../../src/redis-server redis.conf.7011 && cd -
- 3)添加到集群
- 使用redis-trib.rb add-node分别将两个新结点添加到集群中,一个作为Master,一个作为其Slave。
- [root@8gVm redis-3.0.4]# src/redis-trib.rb add-node 192.168.1.100:7010 192.168.1.100:7000
- >>> Adding node 192.168.1.100:7010 to cluster 192.168.1.100:7000
- Connecting to node 192.168.1.100:7000: OK
- Connecting to node 192.168.1.100:7001: OK
- Connecting to node 192.168.1.100:7002: OK
- Connecting to node 192.168.1.100:7005: OK
- Connecting to node 192.168.1.100:7003: OK
- Connecting to node 192.168.1.100:7004: OK
- >>> Performing Cluster Check (using node 192.168.1.100:7000)
- ...
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
- Connecting to node 192.168.1.100:7010: OK
- >>> Send CLUSTER MEET to node 192.168.1.100:7010 to make it join the cluster.
- [OK] New node added correctly.
- [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 cluster nodes
- 0d1f9c979684e0bffc8230c7bb6c7c0d37d8a5a9 192.168.1.100:7010 master - 0 1442452249525 0 connected
- ...
- [root@8gVm redis-3.0.4]# src/redis-trib.rb add-node --slave --master-id 0d1f9c979684e0bffc8230c7bb6c7c0d37d8a5a9 192.168.1.100:7011 192.168.1.100:7000
- >>> Adding node 192.168.1.100:7011 to cluster 192.168.1.100:7000
- Connecting to node 192.168.1.100:7000: OK
- Connecting to node 192.168.1.100:7010: OK
- Connecting to node 192.168.1.100:7001: OK
- Connecting to node 192.168.1.100:7002: OK
- Connecting to node 192.168.1.100:7005: OK
- Connecting to node 192.168.1.100:7003: OK
- Connecting to node 192.168.1.100:7004: OK
- >>> Performing Cluster Check (using node 192.168.1.100:7000)
- ...
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
- Connecting to node 192.168.1.100:7011: OK
- >>> Send CLUSTER MEET to node 192.168.1.100:7011 to make it join the cluster.
- Waiting for the cluster to join.
- >>> Configure node as replica of 192.168.1.100:7010.
- [OK] New node added correctly.
- 4) Resharding
- 通过redis-trib.rb reshard可以交互式地迁移Slot。下面的例子将5000个Slot从7000~7002迁移到7010上。也可以通过./redis-trib.rb reshard <host>:<port> --from <node-id> --to <node-id> --slots --yes在程序中自动完成迁移。
- [root@8gVm redis-3.0.4]# src/redis-trib.rb reshard 192.168.1.100:7000
- Connecting to node 192.168.1.100:7000: OK
- Connecting to node 192.168.1.100:7010: OK
- Connecting to node 192.168.1.100:7001: OK
- Connecting to node 192.168.1.100:7002: OK
- Connecting to node 192.168.1.100:7005: OK
- Connecting to node 192.168.1.100:7011: OK
- Connecting to node 192.168.1.100:7003: OK
- Connecting to node 192.168.1.100:7004: OK
- >>> Performing Cluster Check (using node 192.168.1.100:7000)
- M: b2036adda128b2eeffa36c3a2056444d23b548a8 192.168.1.100:7000
- slots:0-5460 (4128 slots) master
- 1 additional replica(s)
- M: 0d1f9c979684e0bffc8230c7bb6c7c0d37d8a5a9 192.168.1.100:7010
- slots:0 (4000 slots) master
- 1 additional replica(s)
- ...
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
- How many slots do you want to move (from 1 to 16384)? 5000
- What is the receiving node ID? 0d1f9c979684e0bffc8230c7bb6c7c0d37d8a5a9
- Please enter all the source node IDs.
- Type ‘all‘ to use all the nodes as source nodes for the hash slots.
- Type ‘done‘ once you entered all the source nodes IDs.
- Source node #1:all
- [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 cluster nodes
- 0d1f9c979684e0bffc8230c7bb6c7c0d37d8a5a9 192.168.1.100:7010 master - 0 1442455872019 7 connected 0-1332 5461-6794 10923-12255
- b2036adda128b2eeffa36c3a2056444d23b548a8 192.168.1.100:7000 myself,master - 0 0 1 connected 1333-5460
- b5ab302f5c2395e3c8194c354a85d02f89bace62 192.168.1.100:7001 master - 0 1442455875022 2 connected 6795-10922
- 0c565e207ce3118470fd5ed3c806eb78f1fdfc01 192.168.1.100:7002 master - 0 1442455874521 3 connected 12256-16383
- 迁移完成后,查看之前保存的foo1~10的分布情况,可以看到部分Key已经迁移到了新的结点7010上。
- [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 keys "*"
- 1) "foo3"
- 2) "foo7"
- [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7001 keys "*"
- 1) "foo4"
- 2) "foo8"
- 3) "foo0"
- [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7002 keys "*"
- 1) "foo1"
- 2) "foo9"
- 3) "foo5"
- [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7010 keys "*"
- 1) "foo6"
- 2) "foo2"
7)Redis Cluster集群故障转移
在高可用性方面,Redis可算是能够”Auto”一把了!Redis Cluster重用了Sentinel(哨兵)的代码逻辑,不需要单独启动一个Sentinel集群,Redis Cluster本身就能自动进行Master选举和Failover切换。下面我们故意kill掉7010结点,之后可以看到结点状态变成了fail,而Slave 7011被选举为新的Master。
[root@8gVm redis-3.0.4]# kill 43637 [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 cluster nodes 0d1f9c979684e0bffc8230c7bb6c7c0d37d8a5a9 192.168.1.100:7010 master,fail - 1442456829380 1442456825674 7 disconnected b2036adda128b2eeffa36c3a2056444d23b548a8 192.168.1.100:7000 myself,master - 0 0 1 connected 1333-5460 b5ab302f5c2395e3c8194c354a85d02f89bace62 192.168.1.100:7001 master - 0 1442456848722 2 connected 6795-10922 0c565e207ce3118470fd5ed3c806eb78f1fdfc01 192.168.1.100:7002 master - 0 1442456846717 3 connected 12256-16383 5a3c67248b1df554fbf2c93112ba429f31b1d3d1 192.168.1.100:7005 slave 0c565e207ce3118470fd5ed3c806eb78f1fdfc01 0 1442456847720 6 connected 99bff22b97119cf158d225c2b450732a1c0d3c44 192.168.1.100:7011 master - 0 1442456849725 8 connected 0-1332 5461-6794 10923-12255 cd305d509c34842a8047e19239b64df94c13cb96 192.168.1.100:7003 slave b2036adda128b2eeffa36c3a2056444d23b548a8 0 1442456848220 4 connected 64b544cdd75c1ce395fb9d0af024b7f2b77213a3 192.168.1.100:7004 slave b5ab302f5c2395e3c8194c354a85d02f89bace62 0 1442456845715 5 connected
尝试查询之前保存在7010上的Key,可以看到7011顶替上来继续提供服务,整个集群没有受到影响。
[root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 get foo6 "bar" [root@8gVm redis-3.0.4]# [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 get foo2 "bar"
通过上面可以知道,用Redis提供的redis-trib或create-cluster脚本能几步甚至一步就建立起一个Redis集群。本篇为了深入了解Redis Cluster的用户,所以要暂时抛开这些方便的工具,完全手动建立一遍上面的3主3从集群。
8)Redis Cluster集群发现:MEET
最开始时,每个Redis实例自己是一个集群,可以通过cluster meet让各个结点互相“握手”。这也是Redis Cluster目前的一个欠缺之处:缺少结点的自动发现功能。
[root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 cluster nodes 33c0bd93d7c7403ef0239ff01eb79bfa15d2a32c :7000 myself,master - 0 0 0 connected [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 cluster meet 192.168.1.100 7001 OK ... [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 cluster meet 192.168.1.100 7005 OK [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 cluster nodes 7b953ec26bbdbf67179e5d37e3cf91626774e96f 192.168.1.100:7003 master - 0 1442466369259 4 connected 5d9f14cec1f731b6477c1e1055cecd6eff3812d4 192.168.1.100:7005 master - 0 1442466368659 4 connected 33c0bd93d7c7403ef0239ff01eb79bfa15d2a32c 192.168.1.100:7000 myself,master - 0 0 1 connected 63162ed000db9d5309e622ec319a1dcb29a3304e 192.168.1.100:7001 master - 0 1442466371262 3 connected 45baa2cb45435398ba5d559cdb574cfae4083893 192.168.1.100:7002 master - 0 1442466372264 2 connected cdd5b3a244761023f653e08cb14721f70c399b82 192.168.1.100:7004 master - 0 1442466370261 0 connecte
9)Redis Cluster集群的角色设置(REPLICATE)
结点全部“握手”成功后,就可以用cluster replicate命令为结点指定角色了,默认每个结点都是Master。
[root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7003 cluster replicate 33c0bd93d7c7403ef0239ff01eb79bfa15d2a32c OK [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7004 cluster replicate 63162ed000db9d5309e622ec319a1dcb29a3304e OK [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7005 cluster replicate 45baa2cb45435398ba5d559cdb574cfae4083893 OK [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 cluster nodes 7b953ec26bbdbf67179e5d37e3cf91626774e96f 192.168.1.100:7003 slave 33c0bd93d7c7403ef0239ff01eb79bfa15d2a32c 0 1442466812984 4 connected 5d9f14cec1f731b6477c1e1055cecd6eff3812d4 192.168.1.100:7005 slave 45baa2cb45435398ba5d559cdb574cfae4083893 0 1442466813986 5 connected 33c0bd93d7c7403ef0239ff01eb79bfa15d2a32c 192.168.1.100:7000 myself,master - 0 0 1 connected 63162ed000db9d5309e622ec319a1dcb29a3304e 192.168.1.100:7001 master - 0 1442466814987 3 connected 45baa2cb45435398ba5d559cdb574cfae4083893 192.168.1.100:7002 master - 0 1442466811982 2 connected cdd5b3a244761023f653e08cb14721f70c399b82 192.168.1.100:7004 slave 63162ed000db9d5309e622ec319a1dcb29a3304e 0 1442466812483 3 connected
10)Redis Cluster的槽指派(ADDSLOTS)
设置好主从关系之后,就可以用cluster addslots命令指派16384个槽的位置了。有点恶心的是,ADDSLOTS命令需要在参数中一个个指明槽的ID,而不能指定范围。这里用Bash 3.0的特性简化了,不然就得用Bash的循环来完成了:
[root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7000 cluster addslots {0..5000} OK [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7001 cluster addslots {5001..10000} OK [root@8gVm redis-3.0.4]# src/redis-cli -c -h 192.168.1.100 -p 7001 cluster addslots {10001..16383} OK [root@8gVm redis-3.0.4]# src/redis-trib.rb check 192.168.1.100:7000 Connecting to node 192.168.1.100:7000: OK ... >>> Performing Cluster Check (using node 192.168.1.100:7000) ... [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
这样就通过手动执行命令得到了与之前一样的集群。
11)Redis Cluster集群的数据迁移(MIGRATE)
真正开始Resharding之前,redis-trib会先在源结点和目的结点上执行cluster setslot
关于迁移过程中的数据访问,客户端访问源结点时,如果Key还在源结点上就直接操作。如果已经不在源结点了,就向客户端返回一个ASK错误,将客户端重定向到目的结点。
12)Redis Cluster集群内部数据结构
Redis Cluster功能涉及三个核心的数据结构clusterState、clusterNode、clusterLink都在cluster.h中定义。这三个数据结构中最重要的属性就是:clusterState.slots、clusterState.slots_to_keys和clusterNode.slots了,它们保存了三种映射关系:
集群状态,每个节点都保存着一个这样的状态,记录了它们眼中的集群的样子。另外,虽然这个结构主要用于记录集群的属性,但是为了节约资源,有些与节点有关的属性,比如 slots_to_keys 、 failover_auth_count 也被放到了这个结构里面。
ypedef struct clusterState { ... 指向当前节点的指针 clusterNode *myself; /* This node */ 集群当前的状态:是在线还是下线 int state; /* REDIS_CLUSTER_OK, REDIS_CLUSTER_FAIL, ... */ 集群节点名单(包括 myself 节点) 字典的键为节点的名字,字典的值为 clusterNode 结构 dict *nodes; /* Hash table of name -> clusterNode structures */ 记录要从当前节点迁移到目标节点的槽,以及迁移的目标节点 migrating_slots_to[i] = NULL 表示槽 i 未被迁移 migrating_slots_to[i] = clusterNode_A 表示槽 i 要从本节点迁移至节点 A clusterNode *migrating_slots_to[REDIS_CLUSTER_SLOTS]; 记录要从源节点迁移到本节点的槽,以及进行迁移的源节点 importing_slots_from[i] = NULL 表示槽 i 未进行导入 importing_slots_from[i] = clusterNode_A 表示正从节点 A 中导入槽 i clusterNode *importing_slots_from[REDIS_CLUSTER_SLOTS]; 负责处理各个槽的节点 例如 slots[i] = clusterNode_A 表示槽 i 由节点 A 处理 clusterNode *slots[REDIS_CLUSTER_SLOTS]; 跳跃表,表中以槽作为分值,键作为成员,对槽进行有序排序 当需要对某些槽进行区间(range)操作时,这个跳跃表可以提供方便 具体操作定义在 db.c 里面 zskiplist *slots_to_keys; ... } clusterState; 节点状态 struct clusterNode { ... 节点标识 使用各种不同的标识值记录节点的角色(比如主节点或者从节点), 以及节点目前所处的状态(比如在线或者下线)。 int flags; /* REDIS_NODE_... */ 由这个节点负责处理的槽 一共有 REDIS_CLUSTER_SLOTS / 8 个字节长 每个字节的每个位记录了一个槽的保存状态 位的值为 1 表示槽正由本节点处理,值为 0 则表示槽并非本节点处理 比如 slots[0] 的第一个位保存了槽 0 的保存情况 slots[0] 的第二个位保存了槽 1 的保存情况,以此类推 unsigned char slots[REDIS_CLUSTER_SLOTS/8]; /* slots handled by this node */ 指针数组,指向各个从节点 struct clusterNode **slaves; /* pointers to slave nodes */ 如果这是一个从节点,那么指向主节点 struct clusterNode *slaveof; /* pointer to the master node */ ... }; /* clusterLink encapsulates everything needed to talk with a remote node. */ clusterLink 包含了与其他节点进行通讯所需的全部信息 typedef struct clusterLink { ... TCP 套接字描述符 int fd; /* TCP socket file descriptor */ 与这个连接相关联的节点,如果没有的话就为 NULL struct clusterNode *node; /* Node related to this link if any, or NULL */ ... } clusterLink;
13)Redis Cluster集群的处理流程全梳理
在单机模式下,Redis对请求的处理很简单。Key存在的话,就执行请求中的操作;Key不存在的话,就告诉客户端Key不存在。然而在集群模式下,因为涉及到请求重定向和Slot迁移,所以对请求的处理变得很复杂,流程如下:
14)Redis Cluster集群现实存在的问题
尽管属于无中心化架构一类的分布式系统,但不同产品的细节实现和代码质量还是有不少差异的,就比如Redis Cluster有些地方的设计看起来就有一些“奇葩”和简陋:
Redis Cluster集群总结性梳理
来源: http://www.bubuko.com/infodetail-2415210.html