Redis集群搭建采坑总结
背景
先澄清一下,整个过程问题都不是我解决的,我在里面就是起了个打酱油的角色。因为实际上我负责这个项目,整个过程也比较清楚。之前也跟具体负责的同事说过,等过段时间带他做做项目复盘。结果一直忙,之前做的事情都快忘了也没带他做复盘。所以趁着还记得,总结一下这个问题,也算一起做个复盘总结了。
本周一的时候,我们测试环境遇到一个问题:启动一个服务就会导致后端调用耗时增加。当时咨询了对这个问题之前有了解的同事得到的答复是因为一笔请求发到两套测试环境(一个请求需要在两套环境下运行结果做对比),因为这两套环境共用同一套redis集群。收到第二个相同请求的时候,会将这笔请求标记为重复请求。下游接收到这笔请求是重复的,需要重新查询数据库验证请求是否重复,不是的话做一个纠正。所以这时候会造成请求延迟升高。
负责解决这个问题的同事小A就问我:那是不是再搭建一套将两套Redis集群分开就解决了。我说不一定,还有解释不通的地方:一个环境服务不启动不写redis,另一个环境服务启动写redis的时候也会遇到这个问题。
于是小A找了这个服务相关负责的同事了解业务。因为测试环境的总责任人是我,所以了解业务的时候,小A也把我拉了一起了解。通过同事的讲述了解到一个环境中服务要写两个机房。如果两个机房的Redis是同一套也会被标记成重复请求。
至此,解决环境问题的方法有了答案:每套环境要搭建两套Redis集群,两个环境4套Redis集群来解决问题。
往往,一个答案只是一系列问题的开始。
时间线
我们的搭建方案是直接在使用Redis的服务上搭建连接它的两套Redis集群,只改下端口,多跑两个进程。
问题1:服务器退出登录Redis服务会停止
小A告诉我遇到问题的现象:按照网上经典的安装启动教程,启动成功了。但是当干会儿别的,ssh自动退出登录之后再看Redis服务就停止了。
我听到这里首先想到的是这个现象基本可以断定是以非daemon进程在运行,于是我上网上找了以deamon方式运行的命令发给小A:
redis-server ./redis.conf --daemonize yes
小A看了解决方法补充到那一定也可以在配置文件里直接配置daemon方式运行。我表示赞同,他也是这么做的。我当时没有点破,相信刚毕业的他不久也自己会发现配置文件和显示命令实际上是一回事。只是一个是永久生效,一个是每次运行时生效。而直接用这条命令只是为了说明本质问题。
问题2:服务连接Redis报错Not Auth
小A又向我反馈报了一个错,说他在网上查的是Redis版本问题,估计需要重新搭建Redis。我过去看了一下:Redis集群是3.X的版本,jedis客户端用的是2.9的版本。没有听说过Redis3.X的版本有不向下兼容的问题,同时因为这个Redis是从负责Redis的团队要过来的安装包,应该和现在跑着的是一个版本。如果怀疑Redis的团队发的安装包与之前不一样的话,我也确信之前肯定版本不会低于3.0,因为Redis是从3.0之后才支持集群的。所以我判定不是Redis版本问题。让他再查查。实际上我的意思是让他换关键词来查。比如可以按照报错的提示原因来查,也可以按照异常来查,不同的关键词搜索可以获得不同的信息。
然后我看了报的错:其他的没细看,只见赫然写着:Not Auth。我就问:Redis服务有没有设置密码。他说没有,还演示了一下,我在旁边确认了没有。就查看客户端配置有没有配置密码。果然客户端里有密码配置。这就与服务端不匹配了。
问题3:报错cluster support disabled
小A将客户端密码去掉重新打包部署之后,Not Auth的错不报了,但是其实报了两个错,还有一个错没解决:就是提示cluster support disabled。
我说集群方式启动应该就是一个配置,应该有个cluster-enabled什么的从no改成yes。我还出了个馊主意(注意这里用到的馊主意,想想《红楼梦》里每句话都是剧透,这里也不例外):我说理论上一台集群也可以算一个集群。应该可以直接改个配置就以集群方式启动了。
小A按照我说的思路用直接改配置为集群的方法,客户端再启动果然没有报错了。
问题4:请求延迟没有好转,Redis服务端没有写入成功数据
客户端没有报错之后,小A重试原问题现场,请求延迟没有好转。另外,还发现Redis服务端没有写入成功的数据。
这次我和小A首先一起排查配置有没有配置对。发现配置没有问题,我就跟小A说:让他多打日志。客户端连接的地方打一些,读写数据的地方打一些。
通过这个方法,小A定位到客户端连接的连接池为空。最终自己排查到是一台机器的集群的哈希槽在一台机器情况下哈希槽分配有问题,数据写入失败。最后每个集群多起了2个Redis进程做成3个节点的集群解决了问题。
可优化的排查思路分析
在问题4排查的时候,我和小A一起检查了配置是否正确来确认Redis请求是请求到了正确的服务端。其实,有个更为直接和说明问题的方法:抓包。可以tcpdump端口查请求流量是不是正确从客户端发出来了,被转发到了哪里。
在《技术方案设计的方法》里我也提到,很多时候搜索不到自己想要的信息很可能是关键词的问题。排查问题的时候也可以试着换换关键词来搜索。
根本原因分析
这里面有个问题没有彻底搞清楚:为什么一台机器的Redis集群会有问题。
问了小A,当时异常时getSlots方法时返回了空。就是说问题实际上可能是slot没有被分配。
我就问他单台机器的时候有没有在redis-cli客户端上运行cluster info命令。他给我发了下面的运行情况截图。

这张截图验证了我的猜想,slot没有被分配,集群状态为失败,所以连接不上。
那需要连接上的条件并非是集群里有几个节点,而是slots分配,集群状态成功。

为了验证这个猜想,我搭建了一个一个节点的集群,手动cluster addslots了0到16383个slot。集群判断16384个slot都分配完毕,自动状态改成OK。
这整个过程说明了:网上都是说Redis集群必须是3个节点以上的最好是单数个节点来启动。单数个节点是为了投票的时候可以三局两胜得出结论:一半以上的节点挂掉整个集群不可用。而对于Redis根本上判断集群是否可用是根据slot有没有完整的16384个slot在提供服务决定的。
总结
我觉得在整个过程中小A的表现我觉得很OK的。有4点:
1>主观能动性
在过程中,他自己通过网上搜素找资源,自己解决了很多问题。整个问题处理过程中其实没花费我多少时间,花时间的事情他都自己解决了。
2>合理的利用了各种资源
对于业务不理解,他找了理解业务的同事。技术问题搞不定他找了我。因为我对项目负责,所以找我是很合情合理的。同时,我是很希望他遇到这种事情来找我的。因为他找我证明他是信任我的,相信我能一定程度帮到他。第二,他找我是把我当成一种资源。作为资源我被需要,是有价值的。被需要让人觉得很踏实。
我在有搞不定的事情的时候也向上寻求帮助。比如之前需要其他组协作的时候人家有排期遇到困难,领导出面帮忙搞定了。还有申请资源由于暂时性资源紧张,申请不到,也是更上级出面帮忙搞定了。一个称职的上级一定可以成为一种资源,也愿意让自己成为资源。但是成为资源的形式不同,有的可能提供的是战略,有的提供的是精神支持等。
3>事后总结
问题解决后,小A有自己写wiki总结事情经过,避免后人采坑,同时自身也有总结收获。
4>及时沟通
中间过程中,他每个关键步骤都有及时跟我沟通。因为解决完后他反馈给我:他自己觉得对于redis原理还没有理解,所以不清楚为什么3个节点就OK的原因。我因为了解他的想法,所以才自己又实验给出一个根本原因分析。
关于Redis,就一句话:那些很多人说只有面试的时候才能用到的东西,我总是发现实际工作中很有用。
相关阅读
MySQL常见6个考题在实际工作中的运用
Tair分布式缓存
Elasticsearch实战-磁盘IO被打满
业务开发转基础开发,这三种「高可用」架构你会么?
Redis集群搭建采坑总结的更多相关文章
- redis集群搭建踩坑笔记
推荐参考教程:https://blog.csdn.net/pucao_cug/article/details/69250101 错误: from /usr/lib/ruby/2.3.0/rubygem ...
- 搭建redis集群遇到的坑
搭建redis集群遇到的坑 #!/bin/bash # 作者: tuhooo # 日期: 2017.4.23 20.15 # 用途: 通过ruby脚本启动redis伪集群 if [ $2 == &qu ...
- 二、redis集群搭建
redis集群搭建 redis3.0后支持集群.集群中应该至少有三个节点,每个节点有一备份节点.需要6台服务器.搭建伪分布式,需要6个redis实例.搭建集群的步骤: 一.安装单机版redis 第一步 ...
- 25.redis集群搭建笔记
###Redis集群### 0.准备 软件: redis-3.0.0.gem redis-3.0.0.tar.gz#源码 1.安装ruby环境 redis基于ruby槽位计算,hash算法技术,k ...
- Redis 集群搭建详细指南
先有鸡还是先有蛋? 最近有朋友问了一个问题,说毕业后去大城市还是小城市?去大公司还是小公司?我的回答都是大城市!大公司! 为什么这么说呢,你想一下,无论女孩男孩找朋友都喜欢找个子高胸大的.同样的道理嘛 ...
- redis集群搭建及注意事项
上一篇:redis的安装及注意事项 这里,在一个Linux虚拟机上搭建6个节点的redis伪集群,思路很简单,一台虚拟机上开启6个redis实例,每个redis实例有自己的端口.这样的话,相当于模拟出 ...
- Linux Redis集群搭建与集群客户端实现(Python)
硬件环境 本文适用的硬件环境如下 Linux版本:CentOS release 6.7 (Final) Redis版本: Redis已经成功安装,安装路径为/home/idata/yangfan/lo ...
- [转载] Redis集群搭建最佳实践
转载自http://blog.csdn.net/sweetvvck/article/details/38315149?utm_source=tuicool 要搭建Redis集群,首先得考虑下面的几个问 ...
- Linux Redis集群搭建与集群客户端实现
硬件环境 本文适用的硬件环境如下 Linux版本:CentOS release 6.7 (Final) Redis版本: Redis已经成功安装,安装路径为/home/idata/yangfan/lo ...
随机推荐
- 半监督伪标签方法:Feature Space Regularization和Joint-Distance
原文链接 小样本学习与智能前沿 . 在这个公众号后台回复"200706",即可获得课件电子资源. @ 目录 Abstract I. INTRODUCTION Framework. ...
- PyQt(Python+Qt)学习随笔:Qt Designer中部件的焦点策略focusPolicy设置
在Qt Designer中可以设置部件的焦点策略,部件的焦点策略属性取值范围由枚举类型Qt.FocusPolicy来定义,该枚举类型及其含义如下表所示: 注意:经老猿测试鼠标轮滚动获取焦点,只有在鼠标 ...
- 开源版本Visifire的应用
Visifire曾经开源,保持使用开源版本是不会有版权问题滴. 引用的命名控件 using Visifire.Charts; using Visifire.Commons; 一.应用示例主要代码 // ...
- Nessus破解没有Scan选项的解决办法
如图,安装之后无Scan选项,流程按照吾爱破解上的文章:https://www.52pojie.cn/thread-1140341-1-1.html 解决办法为: 首先nessus.license在安 ...
- 补:冲刺Day2
每天举行站立式会议照片: 昨天已完成的工作: 各个成员在 Alpha 阶段认领的任务. 今天各个成员的任务安排. 冲刺Day1博客. 今天计划完成的工作: 成员 任务 高嘉淳 完成登陆.注册 覃泽泰 ...
- Java并发编程的艺术(二)——volatile、原子性
什么是volatile Java语言允许线程访问共享变量,为了确保共享变量能够被准确一致地更新,如果一个字段被声明为volatile,那么Java内存模型将会确保所有线程看到这个变量时值是一致的.保证 ...
- github内的一些操作
github远程仓库的克隆操作 1,找到你想要克隆的地址,复制下来 2,切入到git所在目录下,输入 git clone 复制的地址 设置过滤文件不纳入git管理 1,在git目录下创建一个.giti ...
- C#9.0新特性详解系列之六:增强的模式匹配
自C#7.0以来,模式匹配就作为C#的一项重要的新特性在不断地演化,这个借鉴于其小弟F#的函数式编程的概念,使得C#的本领越来越多,C#9.0就对模式匹配这一功能做了进一步的增强. 为了更为深入和全面 ...
- 通过镜像下载最新Android源码
参考了这两篇博客: http://blog.sina.com.cn/s/blog_70b9730f01016peg.html http://www.cnblogs.com/act262/p/41790 ...
- global和nonlocal之间的区别
在局部修全局的:global 在局部修改嵌套的:nonlocal nonlocal代码示范 # 在局部作用域内去修改嵌套作用域内的变量# 当我们在局部作用域内要修改嵌套作用域内的变量时,需要使用non ...