redis集群
创建集群
第一步 在redis-cluster中创建6个文件夹
mkdir -p /usr/local/redis-cluser
mkdir 7001 mkdir 7002 mkdir 7003 mkdir 7004 mkdir 7005 mkdir 7006
第二步 将redis.conf配置文件分别放在这6文件下
/usr/redis/redis/etc# cp redis.conf /usr/redis/redis/redis-cluster/7001
对配置文件做如下修改
1)daemonize yes
*2) bind 192.168.119.130
3) dir "/usr/redis/redis/redis-cluter/7001/"
4) cluster-enabled yes
5) cluster-config-file nodes-7001.conf
6) cluster-node-timeout 5000
7) appendonly yes
8) port 7001 分别对应每台机器的端口号
第三步 由于redis集群需要使用ruby命令,所以需要安装ruby
1)yum install ruby
2) yum install rubygems
3) gem install redis **可能出现版本不一致问题
第四步 分别启动6个redis实例,然后检查是否启动成功 **前面配置文件中dir目录要创建
/usr/redis/redis/bin/redis-server /usr/redis/redis/redis-cluster/7001/redis.conf
ps -ef| grep redis 或 netstat -tunpl | grep redis 查看服务器运行状态
第五步 创建集群: 进入 redis的src目录下
执行 ./redis-trib.rb create --replicas 1 192.168.242.137:7001 192.168.242.137:7002 192.168.242.137:7003 192.168.242.137:7004 192.168.242.137:7005 192.168.242.137:7006
这里的1表示主节点和从节点的比例
查看集群状态 在进入节点客户端后 cluster nodes cluster info
连接集群中一个节点--要加-c
/usr/local/redis/bin/redis-cli -c -h 192.168.119.138 -p 7002
集群关闭 ps -ef | grep redis | awk '{print $2}' | xargs kill
在集群打开时添加节点
第一步:同上第一步
第二步:同上第二步
全局替换 :%s/old/new/g
第三步:启动redis实例
第四步:使用add-node命令(添加主节点):前者为新增节点,后者为已知存在节点
/usr/local/redis3.0/src/redis-trib.rb add-node 192.168.1.171:7007 192.168.1.171:7001
第五步: 为该主节点添加槽数(192.168.1.171:7001指任意一个主节点)
/usr/local/redis3.0/src/redis-trib.rb reshard 192.168.1.171:7001
1提示一:是希望你需要多少个槽移动到新的节点上,可以自己设置,比如300个槽。
2提示二:是你需要把这300个slot槽移动到那个节点上去(需要指定节点id),并且下个提示是输入all为从所有主节点(7001 7002 7003)中分别抽取响应的槽数(一共为200个槽到指定的新节点中!,并且会打印执行分片的计划。)
3提示三:输入yes确认开始执行分片任务。
第六步: 使用add-node命令(添加从节点):前者为新增节点,后者为已知存在节点
/usr/local/redis3.0/src/redis-trib.rb add-node 192.168.1.171:7008 192.168.1.171:7001
登录7008: /usr/redis/redis/bin/redis-cli -c -h 192.168.119.130 -p 7008
在7008上操作 cluster replicate fd3df847b734d1ef798935bc4f9af8176e5aad7(指定主节点的id)
在集群打开时删除节点
删除从节点7008,输入del-node命令,指定删除节点ip和端口,以及节点id
/usr/local/redis3.0/src/redis-trib.rb del-node 192.168.1.171:7008 97b0e0115326833724eb0ffe1d0574ee34618e9f
删除主节点7007:
第一步: 将7007上的数据移动到其他主节点上
/usr/local/redis3.0/src/redis-trib.rb reshard 192.168.1.171:7007(要删除的主节点)--(目前只能把master的数据迁移到一个节点上,暂时做不了平均分配功能)
1提示一:是希望你需要多少个槽移动到其他的主节点上,可以查看到。
2提示二:是你需要把这些slot槽移动到哪个主节点上去(需要指定节点id),
下个提示输入源节点(要删除的节点)
下一个输入done。
Source node #1:03ccad2ba5dd1e062464bc7590400441fafb63f2 //被删除master的node-id
Source node #2:done
3提示三:输入yes确认开始执行分片任务。
第二步:删除
/usr/local/redis3.0/src/redis-trib.rb del-node 192.168.1.171:7007 382634a4025778c040b7213453fd42a709f79e28
原理
redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。
Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。所以我们在测试的时候看到set 和 get 的时候,直接跳转到了7000端口的节点。
Redis 集群会把数据存在一个 master 节点,然后在这个 master 和其对应的salve 之间进行数据同步。当读取数据时,也根据一致性哈希算法到对应的 master 节点获取数据。只有当一个master 挂掉之后,才会启动一个对应的 salve 节点,充当 master 。
需要注意的是:必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了。
以下命令是集群所独有的。执行上述命令要先登录
//集群(cluster)
CLUSTER INFO 打印集群的信息
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
//节点(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)。
//键 (key)
CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。