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 ...
随机推荐
- JZOJ 【NOIP2017提高A组模拟9.14】捕老鼠
JZOJ [NOIP2017提高A组模拟9.14]捕老鼠 题目 Description 为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠.于是,猫被农夫约派去捕 ...
- Cys_Control(三) MTextBox
一.查看TextBox原样式 通过Blend查看TextBox原有样式 <Window.Resources> <SolidColorBrush x:Key="TextBox ...
- argparse使用范例
if __name__ == "__main__": # https://docs.python.org/zh-cn/dev/library/argparse.html impor ...
- (七)if/else就是goto
一.CPU如何执行指令 CPU上有数以亿计的晶体管组层的复杂电路,我们先不用管具体电路如何实现:逻辑上我们可以认为CPU由许多寄存器组成,而这些寄存器又由许多锁存器和触发器组成,N个锁存器或触发器就可 ...
- python核心高级学习总结8------动态性、__slots__、生成器、迭代器、装饰、闭包
python的动态性 什么是动态性呢,简单地来说就是可以在运行时可以改变其结构,如:新的函数.对象.代码都可以被引进或者修改,除了Python外,还有Ruby.PHP.javascript等也是动态语 ...
- PyQt(Python+Qt)学习随笔:QMdiArea多文档界面区域的viewMode、documentMode、tabsClosable、tabPosition等属性介绍
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 viewMode属性用于控制子窗口是使用子窗口模式(QMdiArea. ...
- 转1:Python字符编码详解
Python27字符编码详解 声明 一 字符编码基础 1 抽象字符清单ACR 2 已编码字符集CCS 3 字符编码格式CEF 31 ASCII初创 311 ASCII 312 EASCII 32 MB ...
- PyQt学习随笔:重写setData方法截获Model/View中视图数据项编辑的注意事项
根据<PyQt学习随笔:Model/View中视图数据项编辑变动实时获取变动数据的方法>可以重写从PyQt的Model类继承的setData方法来实时截获View中对数据的更改,但需要注意 ...
- PyQt(Python+Qt)学习随笔:图例解释QFrame类的lineWidth、midLineWidth以及frameWidth属性
老猿Python博文目录 老猿Python博客地址 QFrame类有四个跟宽度相关的属性,分别是width.lineWidth.midLineWidth以及frameWidth属性.width是整个Q ...
- John the Ripper快速密码破解工具简单使用
在某场比赛中师傅们说需要用到该工具,学习之 题目给了我们一个流量包,分析 发现 .hint.php.swp文件 该文件是使用 vim 编辑文件时异常退出而产生的,可以通过 vim -r 文件名 进行相 ...