Share猿,一个极客共同交流学习的社区!
RedisCluster 是redis的亲儿子,他是redis做者本身提供的redis集群解决方案。node
去中心化集群指的就是各个节点之间都是平等的,并且每一个节点具备高度自治的特征,节点之间相互链接通信保持数据的一致性。咱们最熟知的去中心应用比特币系统,就是一个去中心化的系统。redis
经过上一节学习codies集群,咱们知道codies有1024个槽位,为何cluster集群会有这么多,什么是槽位/hash槽哪?算法
槽位其实就至关于咱们缓存桶,16384个槽位就至关于16384个存储数据的缓存桶,cluster集群会把这个16384个缓存桶均匀分配给集群的各个节点。数组
节点A覆盖0-5460;缓存
节点B覆盖5461-10922;安全
节点C覆盖10923-16383.ruby
当咱们在集群中放置一个key-value的时候,cluster会根据CRC16(key)mod16384得出的值,该值决定咱们的key-value放到哪一个缓存桶里面。bash
当咱们新增集群节点的时候,新增的集群节点会从现有的各个节点中获取一部分缓存桶。网络
节点A覆盖1365-5460app
节点B覆盖6827-10922
节点C覆盖12288-16383
节点D覆盖0-1364,5461-6826,10923-12287
看到这里,想必你们也知道什么是redis cluster的槽位,为何cluster集群的槽位比codies多的缘由。
通过网上查资料,发现,所谓的去中心化节点准确的说应该是去中心化主节点,上面的ABC节点在部署的时候咱们还要对其部署对应的从节点,这样才能保证其中一个主节点挂了而不影响整个集群。因此cluster集群是一种:去中心化+主从的集群模式。
Cluster 默认会对 key 值使用 crc16 算法进行 hash 获得一个整数值,而后用这个整数值对 16384 进行取模来获得具体槽位。
Cluster 还容许用户强制某个 key 挂在特定槽位上,经过在 key 字符串里面嵌入 tag 标记,这就能够强制 key 所挂在的槽位等于 tag 所在的槽位。
说的直白一点就是从一个节点跳到另外一个集群节点。
当咱们对一个集群节点发送了一个指令,发现该节点不存在该指令的槽位,这时它会向客户端发送一个特殊的跳转指令携带目标操做的节点地址,告诉客户端去连这个节点去获取数据。
GET x
-MOVED 3999 127.0.0.1:6381复制代码
MOVED 指令的第一个参数 3999 是 key 对应的槽位编号,后面是目标节点地址。MOVED 指令前面有一个减号,表示该指令是一个错误消息。
客户端收到 MOVED 指令后,要当即纠正本地的槽位映射表。后续全部 key 将使用新的槽位映射表。
Redis Cluster 提供了工具 redis-trib 可让运维人员手动调整槽位的分配状况,它使用 Ruby 语言进行开发,经过组合各类原生的 Redis Cluster 指令来实现。
redis-trib提供了UI界面方便咱们的迁移,还提供了自动平衡槽位的工具,无需人工干预就能均衡集群负载。
从源节点获取内容 => 存到目标节点 => 从源节点删除内容。
Redis Cluster 能够为每一个主节点设置若干个从节点,单主节点故障时,集群会自动将其中某个从节点提高为主节点。若是某个主节点没有从节点,那么当它发生故障时,集群将彻底处于不可用状态。不过 Redis 也提供了一个参数cluster-require-full-coverage能够容许部分节点故障,其它节点还能够继续提供对外访问。
所谓网络抖动就是网络异常状况,忽然不可访问,一下子又好了。这种状况可能致使cluster的主从节点频繁切换。
针对上述状况,cluster提供了一个选项cluster-node-timeout,他存在的意义在于防止网络抖动而引发频繁的节点切换。设置了该选项只有当节点长期失联的时候才会进行主从切换。
只有当大多数节点都认定了某个节点失联了,集群才认为该节点须要进行主从切换来容错。
一个节点发现某个节点失联了 (PFail),它会将这条信息向整个集群广播,其它节点也就能够收到这点失联信息。
若是一个节点收到了某个节点失联的数量 (PFail Count) 已经达到了集群的大多数,就能够标记该节点为肯定下线状态 (Fail),而后向整个集群广播,强迫其它节点也接收该节点已经下线的事实,并当即对该失联节点进行主从切换。
要使用 Cluster,必须安装另一个包,这个包是依赖 redis-py 包的。pip install redis-py-cluster
>>> from rediscluster import StrictRedisCluster
>>> # Requires at least one node for cluster discovery. Multiple nodes is recommended.
>>> startup_nodes = [{"host": "127.0.0.1", "port": "7000"}]
>>> rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
>>> rc.set("foo", "bar")
True
>>> print(rc.get("foo"))
'bar'复制代码
Cluster 是去中心化的,它有多个节点组成,构造 StrictRedisCluster 实例时,咱们能够只用一个节点地址,其它地址能够自动经过这个节点来发现。不过若是提供多个节点地址,安全性会更好。若是只提供一个节点地址,那么当这个节点挂了,客户端就必须更换地址才能够继续访问 Cluster。 第二个参数 decode_responses 表示是否要将返回结果中的 byte 数组转换成 unicode。
Cluster 使用起来很是方便,用起来和普通的 redis-py 差异不大,仅仅是构造方式不一样。可是它们也有至关大的不同之处,好比 Cluster 不支持事务,Cluster 的 mget 方法相比 Redis 要慢不少,被拆分红了多个 get指令,Cluster 的 rename 方法再也不是原子的,它须要将数据从原节点转移到目标节点。
客户端保存了槽位和节点的映射关系表,它须要即时获得更新,才能够正常地将某条指令发到正确的节点中。
咱们前面提到 Cluster 有两个特殊的 error 指令,一个是 moved,一个是 asking。
第一个 moved 是用来纠正槽位的。
第二个 asking 指令和 moved 不同,它是用来临时纠正槽位的。
moved 和 asking 指令都是重试指令,客户端会由于这两个指令多重试一次。
建立cluster目录,并建立6个配置文件
port 7000 //端口7000,7002,7003..
daemonize yes //redis后台运行
pidfile ./redis_7000.pid //pidfile文件对应7000,7001,7002
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_7000.conf //集群的配置 配置文件首次启动自动生成 7000,7001,7002
cluster-node-timeout 15000 //请求超时 默认15秒,可自行设置
appendonly yes //aof日志开启 有须要就开启,它会每次写操做都记录一条日志
//若设置密码,master和slave需同时配置下面两个参数:
masterauth "12345678" //链接master的密码
requirepass "12345678" //本身的密码
ruby redis-trib.rb //测试是否安装成功,若已经安装过,可跳过此步
安装
cp /usr/andy/redis/redis-3.2.0/src/redis-trib.rb .
yum install ruby
yum install rubygems
gem install redis-3.2.2.gem //需下载redis-3.2.2.gem
执行下面命令建立集群(需为真实ip,否则外网没法访问):
./redis-trib.rb create --replicas 1 192.168.0.217:7000 192.168.0.217:7001 192.168.0.217:7002 192.168.0.217:7003 192.168.0.217:7004 192.168.0.217:7005
能够看到:
集群
cluster info :打印集群的信息
cluster nodes :列出集群当前已知的全部节点( node),以及这些节点的相关信息。
节点
cluster meet ip port:将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
cluster forget <node_id> :从集群中移除 node_id 指定的节点。
cluster replicate <node_id> :将当前节点设置为 node_id 指定的节点的从节点。
cluster saveconfig :将节点的配置文件保存到硬盘里面。
槽(slot)
cluster addslots <slot> [slot ...] :将一个或多个槽( slot)指派( assign)给当前节点。
cluster delslots <slot> [slot ...] :移除一个或多个槽对当前节点的指派。
cluster flushslots :移除指派给当前节点的全部槽,让当前节点变成一个没有指派任何槽的节点。
cluster setslot <slot> node <node_id> :将槽 slot 指派给 node_id 指定的节点,若是槽已经指派给另外一个节点,那么先让另外一个节点删除该槽>,而后再进行指派。
cluster setslot <slot> migrating <node_id> :将本节点的槽 slot 迁移到 node_id 指定的节点中。
cluster setslot <slot> importing <node_id> :从 node_id 指定的节点中导入槽 slot 到本节点。
cluster setslot <slot> stable :取消对槽 slot 的导入( import)或者迁移( migrate)。
键
cluster keyslot <key> :计算键 key 应该被放置在哪一个槽上。
cluster countkeysinslot <slot> :返回槽 slot 目前包含的键值对数量。
cluster getkeysinslot <slot> <count> :返回 count 个 slot 槽中的键
学完这一小节明白了cluster集群的基本原理,以及槽位等一些相关概念,了解了CRC16算法,学会如何搭建一个cluster集群。
扫描如下二维码关注社区公众号↓↓↓↓↓↓↓↓
更多资讯请在简书、微博、今日头条、掘金、CSDN均可以经过搜索“Share猿”加入Share猿社区!!!