今天打开电脑,连接redis,发现连接不上了...
原因是找不到主机...查看虚拟机ip,发现ip变了...
于是想到之前配置redis集群的时候,在redis.conf中配置了bind为虚拟机的ip地址,觉得应该是这个原因,于是修
配置bind:127.0.0.1,重启集群,想想应该是没问题了,但是...
服务启起来了,ip也显示为127.0.0.1,但是进行check的时候报了异常,can't connect to node 192.168.21.128...是的
连的还是旧的ip...设置了bind属性貌似不起作用,于是尝试去查询资料,没有找到解决方案,感觉是集群已经被我玩坏了,
其实仔细一想redis一定是把一些参数保存在了其集群的配置文件中,check的时候是去配置文件中读取ip的。
如下图,进入其中一个节点的配置文件:
appendonly.aof和dump.rdb是持久化的数据备份文件,redis.conf是配置文件,redis-server及redis-cli是执行redis启动,
连接等操作的脚本,nodes-8001.conf和redis.pid分别对应redis.conf中的cluster-config-file和pidfile属性,猜想应该是和
这两个文件有关系,有两个解决方案,第一研究源码,去修改两个文件中的相关配置,可能会出现不可预知的问题,
第二个方案重新搭建集群,简单粗暴但是一定有效,当然前提是对数据做好备份。我选择了第二种,顺便能搞下数据
的恢复。首先新建一个文件夹,将备份文件移过去,之后将除redis.conf,redis-cli和redis-server以外的文件全部移除
这个时候的集群配置应该已经完全没了,尝试重新搭建集群
此时的几个redis服务都没有任何key,集群搭建相当顺利!这个时候check已经成功了,ip顺利的变成了重新配置的
127.0.0.1,现在尝试对数据进行恢复具体步骤是将之前的转移的备份文件覆盖新生成的备份文件,然后重启redis服务,
这里使用aof来恢复数据
重启之后乍一看是恢复成功了,但是check的时候发现了异常
且get数据也有问题
到这一步,我挖了个大坑....fix不成功之后我直接将1243和5798两个槽设成了stable,check是成功了,但是get key根本
get不到数据,可以说数据被我玩坏了...第一次失败了,不过反正之前的备份文件还在,重头再来吧...移除配置、重新搭建
集群、覆盖备份文件、重启服务,遇到了同样的问题,果然还是原来的配方....不过这次学聪明了,经过一番研究,我找到
了某个博主的fix经验,原来之前每次使用fix都失败是这样的原因!!这里引用下这位博主的总结经验。
fix的作业流程:
1、先检查该slot是谁负责的,迁移的源节点如果没完成迁移,owner还是该节点。没有owner的slot无法完成修复功能。
2、遍历每个节点,获取哪些节点标记该slot为migrating状态,哪些节点标记该slot为importing状态。对于owner不是该节点,但是通过cluster countkeysinslot获取到该节点有数据的情况,也认为该节点为importing状态。
3、如果migrating和importing状态的节点均只有1个,这可能是迁移过程中redis-trib.rb被中断所致,直接执行move_slot继续完成迁移任务即可。传递dots和fix为true。
4、如果migrating为空,importing状态的节点大于0,那么这种情况执行回滚流程,将importing状态的节点数据通过move_slot方法导给slot的owner节点,传递dots、fix和cold为true。接着对importing的节点执行cluster stable命令恢复稳定。
5、如果importing状态的节点为空,有一个migrating状态的节点,而且该节点在当前slot没有数据,那么可以直接把这个slot设为stable。
6、如果migrating和importing状态不是上述情况,目前redis-trib.rb工具无法修复,上述的三种情况也已经覆盖了通过redis-trib.rb工具迁移出现异常的各个方面,人为的异常情形太多,很难考虑完全
我的理解是须要通过fix修复异常slot,须要明确告诉redisslot的目标节点是哪个,源节点是哪个,而我之前的一系列操作造成了
两个问题slot只存在目标节点,把源节点丢失了(因为check的时候发现只有importing状态,而没有migrating状态),那fix当然
不成功啊!
修改如下:
为这两个问题节点指定源节点,重新fix,成功,且数据恢复正常。最后对比下第一次fix失败打印的日志和fix成功
打印的日志。
失败日志:
成功日志:
总结:
1.搭建redis集群,服务器的ip必须要设置成固定
2.对问题slot,不要轻易设置stable,很容易造成数据丢失
3.后面的集群测试发现即使migrating和imorting状态都存在,依然可能fix失败(不得不吐槽,redis-cluster的坑有很多啊)
此时可以使用CLUSTER SETSLOT <slot> NODE <node_id>搭配CLUSTER BUMPEPOCH来强制集群的其他节点同意slot
的归属。
CLUSTER BUMPEPOCH参考:Redis Cluster迁移目标节点宕机下填坑
集群命令汇总
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槽中的键。