1、如果是用apt-get或者yum install安装的redis,可以直接通过下面的命令停止/启动/重启redis:/etc/initd/redis-server stop/etc/initd/redis-server start/etc/initd/redis-server restart
2、如果是通过源码安装的redis,则可以通过redis的客户端程序redis-cli的shutdown命令来重启redis。
redis集群如何解决重启不了的问题
redis使用集群部署,如果遇到断电或者服务器重启,当再次启动的时候,有时候会启动不了。需要使用trib的fix命令进行修复。如果修复还是不行的话,可以清除节点数据再重新建集群,前提要备份之后 *** 作。
1、使用redis-cli连接上redis其中一台:redis-cli -c -h xxx -p 7001,输入cluster info查看当前集群的状态。
2、可以使用trib的check检测的集群状态:redis-tribrb check xxx:7001,[ERR] Not all 16384 slots are covered by nodes。
3、如果出现以上的错误,可以尝试使用fix命令修复:redis-tribrb fix xxx:7001。修复完成之后,在使用trib的check命令查看状态。
4、如果通过fix方式修复不了,pkill redis停止之前的redis进程,然后把aof,rdb,nodes节点文件删除,删除之前需要备份。
5、然后启动各个redis节点。
6、创建redis集群:redis-tribrb create --replicas 1 xxx:7000 xxx:7001 xxx:7002 xxx:7003 xxx:7004 xxx:7005。
7、集群创建完成之后,再次连接redis查看集群状态,redis服务已经启动完成。
配置集群命令:
进入redis解压缩目录,执行
src/redis-tribrb create --replicas 1 20164131:6379 20164132:6379 20164133:6379 20164134:6379 20164135:6379 20164136:6379
不过前提是你这6台redis-server都启动,并且bind对应内网ip
除非三主三从都挂了,否则整个集群还是可以正常使用的
参考官方文档:
网页链接
Caused by: orgspringframeworkdataredisRedisConnectionFailureException: Could not get a resource from the pool; nested exception is redisclientsjedisexceptionsJedisConnectionException: Could not get a resource from the poolat orgspringframeworkdataredisconnectionjedisJedisExceptionConverterconvert(JedisExceptionConverterjava:67)
at orgspringframeworkdataredisconnectionjedisJedisExceptionConverterconvert(JedisExceptionConverterjava:41)
at orgspringframeworkdataredisPassThroughExceptionTranslationStrategytranslate(PassThroughExceptionTranslationStrategyjava:37)
at orgspringframeworkdataredisconnectionjedisJedisClusterConnectionconvertJedisAccessException(JedisClusterConnectionjava:3999)
at orgspringframeworkdataredisconnectionjedisJedisClusterConnectionsetEx(JedisClusterConnectionjava:717)
at orgspringframeworkdatarediscoreDefaultValueOperations 11doInRedis(DefaultValueOperationsjava:186)
at orgspringframeworkdatarediscoreRedisTemplateexecute(RedisTemplatejava:207)
at orgspringframeworkdatarediscoreRedisTemplateexecute(RedisTemplatejava:169)
at orgspringframeworkdatarediscoreAbstractOperationsexecute(AbstractOperationsjava:91)
at orgspringframeworkdatarediscoreDefaultValueOperationsset(DefaultValueOperationsjava:182)
at iorenrencommonutilsSuppleDataUtilsprovideIcc(SuppleDataUtilsjava:107)
at iorenrenmodulesjobtaskTaskIcctaskFour(TaskIccjava:242)
10 common frames omitted
Caused by: redisclientsjedisexceptionsJedisConnectionException: Could not get a resource from the pool
at redisclientsutilPoolgetResource(Pooljava:53)
at redisclientsjedisJedisPoolgetResource(JedisPooljava:226)
at redisclientsjedisJedisSlotBasedConnectionHandlergetConnectionFromSlot(JedisSlotBasedConnectionHandlerjava:66)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:116)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:141)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:141)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:141)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:141)
at redisclientsjedisJedisClusterCommandrunBinary(JedisClusterCommandjava:60)
at redisclientsjedisBinaryJedisClustersetex(BinaryJedisClusterjava:268)
at orgspringframeworkdataredisconnectionjedisJedisClusterConnectionsetEx(JedisClusterConnectionjava:715)
18 common frames omitted
Caused by: redisclientsjedisexceptionsJedisConnectionException: javanetSocketTimeoutException: connect timed out
at redisclientsjedisConnectionconnect(Connectionjava:207)
at redisclientsjedisBinaryClientconnect(BinaryClientjava:93)
at redisclientsjedisBinaryJedisconnect(BinaryJedisjava:1767)
at redisclientsjedisJedisFactorymakeObject(JedisFactoryjava:106)
at orgapachecommonspool2implGenericObjectPoolcreate(GenericObjectPooljava:868)
at orgapachecommonspool2implGenericObjectPoolborrowObject(GenericObjectPooljava:435)
at orgapachecommonspool2implGenericObjectPoolborrowObject(GenericObjectPooljava:363)
at redisclientsutilPoolgetResource(Pooljava:49)
28 common frames omitted
Caused by: javanetSocketTimeoutException: connect timed out
at javanetDualStackPlainSocketImplwaitForConnect(Native Method)
at javanetDualStackPlainSocketImplsocketConnect(DualStackPlainSocketImpljava:85)
at javanetAbstractPlainSocketImpldoConnect(AbstractPlainSocketImpljava:350)
at javanetAbstractPlainSocketImplconnectToAddress(AbstractPlainSocketImpljava:206)
at javanetAbstractPlainSocketImplconnect(AbstractPlainSocketImpljava:188)
at javanetPlainSocketImplconnect(PlainSocketImpljava:172)
at javanetSocksSocketImplconnect(SocksSocketImpljava:392)
at javanetSocketconnect(Socketjava:589)
at redisclientsjedisConnectionconnect(Connectionjava:184)
35 common frames omitted
最近在本地测试通过springboot基础redis的方式连接redis集群,启动的时候没有报错。
到时当执行保存,查询到redis的 *** 作的时候,报上面的错误。
首先看到错误信息,先是connect timed out后,再出现的Could not get a resource from the pool错误。一开始排查这个错误,由于使用的是默认连接池,debug的时候,也看到有装载连接池,为啥报错呢。本地通过redis-manger工具,连接集群地址也可以连接访问。从日志也看不出还有其他的错误信息。
于是自己写了main方法直接 *** 作JedisCluster的方式来测试,出现的错误跟上面全文一样。用抓包工具wireshark过滤集群的地址,查看连接的消息也是正常的。
另外一个项目使用的reddison客户端,于是测试了deamo用reddison来连接集群地址,启动的时候,发现报如下错误
乖乖,恍然大悟;102871731地址是服务器的内网地址,本机是连不上内网地址的,只有通过外网地址连接。而我配置的是外网地址。然而,客户端在集群同步和心跳检查的时候,是拉取的集群信息,redis集群信息里面的节点的信息
配置的是内网地址。客户端就通过这个内网地址来同步信息了。
再次同wireshark过滤集群102871731,发现有大量的超时重传的包,也没有响应。
在哨兵模式中,仍然只有一个 master 节点。当并发写请求较大时,哨兵模式并不能缓解写压力。
在redis-cluster集群中,每一个主节点可以添加多个从节点,主节点和从节点遵循主从模式的特性。
当用户需要处理更多的读请求时,添加从节点可以扩展系统的读性能。
redis集群的主节点内置了类似Sentinel的节点故障检测和自动故障转移功能。当集群中的某个主节点下线时,集群中的其他在线主节点发现了以后,会对已下线的主节点进行故障转移。集群进行故障转移的方法和Sentient进行故障转移的方法基本一致,不同的是,在集群里面,故障转移是由集群中其他在线的主节点负责进行的,所以集群中不需要使用Sentinel。
redis-cluster集群将键存储空间分割为16384个槽位(slot),事实上集群最大节点数量是16384个官方建议最大节点数量不超过1000个节点。
所有主节点都负责16384个哈希槽中的一部分,当16384个槽都有某个节点在负责处理时,集群进入上线状态,并开始处理客户端发送的数据命令请求。
一个slot槽位可以存放多个数据,key的槽位计算公式:HASH_SLOT = CRC16(key) mod 16384
由于Redis集群无中心节点,请求会随机发给任意主节点。
主节点只会处理自己负责槽位的命令请求,其他槽位的命令请求,该主节点会返回客户端一个转向错误。
客户端根据错误中包含的地址和端口重新向正确的负责的主节点发起命令请求。
系统:CentOS7
Redis: 509
Redis节点
注意:
配置文件主要修改:
执行结果
按照之前的配置修改并启动,使用以下命令将其加入集群:
添加完新节点后,需要对新添加的主节点进行hash槽重新分配,这样该主节点才能存储数据,redis共有16384个槽。
删除从节点19216816413:7000,node_id:cb21c351b3d2378976bf7d215553d0e04d7fad43
执行结果
存在slot的主节点无法直接删除,所以我们需要先移动主节点19216816413:7001的slot至其他三个主节点
查看集群节点信息
删除主节点
执行结果
查看集群信息
安装redis集群需要版本号在30以上redis-cluster安装前需要安装ruby环境搭建集群需要使用到官方提供的ruby脚本。需要安装ruby的环境。yum-yinstallrubyyum-yinstallrubygemsredis集群管理工具redis-tribrb[root@bogon~]#cdredis-300[root@bogonredis-300]#cdsrc[root@bogonsrc]#llrb-rwxrwxr-x1rootroot48141Apr107:01redis-tribrb脚本需要的ruby包:redis-300gem安装geminstallredis-300gem[root@bogon~]#geminstallredis-300gemSuccessfullyinstalledredis-3001geminstalledInstallingridocumentationforredis-300InstallingRDocdocumentationforredis-300集群的搭建需求,创建6台redis服务器,虚拟机模拟端口号为7001-7006第二步:修改redis的配置文件1、修改端口号第三步:把创建集群的ruby脚本复制到redis-cluster目录下。第四步:启动6个redis实例第五步:创建集群。Redis-Sentinel是redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端都没有实现主从切换的功能。
而redis-sentinel就是一个独立运行的进程,用于监控多个master-slave集群,
自动发现master宕机,进行自动切换slave > master
每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令
如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线
在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。
主观下线和客观下线
主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover
SDOWN适合于Master和Slave,只要一个 Sentinel 发现Master进入了ODOWN, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对下线的主服务器执行自动故障迁移 *** 作。
ODOWN只适用于Master,对于Slave的 Redis 实例,Sentinel 在将它们判断为下线前不需要进行协商, 所以Slave的 Sentinel 永远不会达到ODOWN。
Redis主从复制可将主节点数据同步给从节点,从节点此时有两个作用:
但是问题是:
那么这个问题,redis-sentinel就可以解决了
Redis的一个进程,但是不存储数据,只是监控redis
本实验是在测试环境下,因此只准备一台linux服务器用作环境!!
服务器环境,一台即可完成 *** 作
所有配置文件如下
总体redis配置文件如下,6379为master,6380和6381为slave
redis-6380conf slave配置文件详解,6381端口的配置文件,仅仅和6380端口不一样
在主节点上查看主从通信关系
在从节点上查看主从关系(6380、6379)
此时可以在master上写入数据,在slave上查看数据,此时主从复制配置完成
redis-sentinel-26379conf配置文件写入如下信息
redis-sentinel-26380conf和redis-sentinel-26381conf的配置仅仅差异是port(端口)的不同。
然后启动三个sentinel哨兵
此时查看哨兵是否成功通信
实例的思路
首先查看三个Redis的进程状态
第一个
第二个
第三个
直接干掉master,然后等待其他两个节点是否能自动被哨兵sentienl,切换为master节点
此时查看两个slave的状态
然后会发现slave节点成为master节点!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)