背景

先澄清一下,整个过程问题都不是我解决的,我在里面就是起了个打酱油的角色。因为实际上我负责这个项目,整个过程也比较清楚。之前也跟具体负责的同事说过,等过段时间带他做做项目复盘。结果一直忙,之前做的事情都快忘了也没带他做复盘。所以趁着还记得,总结一下这个问题,也算一起做个复盘总结了。

本周一的时候,我们测试环境遇到一个问题:启动一个服务就会导致后端调用耗时增加。当时咨询了对这个问题之前有了解的同事得到的答复是因为一笔请求发到两套测试环境(一个请求需要在两套环境下运行结果做对比),因为这两套环境共用同一套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集群搭建采坑总结的更多相关文章

  1. redis集群搭建踩坑笔记

    推荐参考教程:https://blog.csdn.net/pucao_cug/article/details/69250101 错误: from /usr/lib/ruby/2.3.0/rubygem ...

  2. 搭建redis集群遇到的坑

    搭建redis集群遇到的坑 #!/bin/bash # 作者: tuhooo # 日期: 2017.4.23 20.15 # 用途: 通过ruby脚本启动redis伪集群 if [ $2 == &qu ...

  3. 二、redis集群搭建

    redis集群搭建 redis3.0后支持集群.集群中应该至少有三个节点,每个节点有一备份节点.需要6台服务器.搭建伪分布式,需要6个redis实例.搭建集群的步骤: 一.安装单机版redis 第一步 ...

  4. 25.redis集群搭建笔记

    ###Redis集群### 0.准备 软件: redis-3.0.0.gem redis-3.0.0.tar.gz#源码   1.安装ruby环境 redis基于ruby槽位计算,hash算法技术,k ...

  5. Redis 集群搭建详细指南

    先有鸡还是先有蛋? 最近有朋友问了一个问题,说毕业后去大城市还是小城市?去大公司还是小公司?我的回答都是大城市!大公司! 为什么这么说呢,你想一下,无论女孩男孩找朋友都喜欢找个子高胸大的.同样的道理嘛 ...

  6. redis集群搭建及注意事项

    上一篇:redis的安装及注意事项 这里,在一个Linux虚拟机上搭建6个节点的redis伪集群,思路很简单,一台虚拟机上开启6个redis实例,每个redis实例有自己的端口.这样的话,相当于模拟出 ...

  7. Linux Redis集群搭建与集群客户端实现(Python)

    硬件环境 本文适用的硬件环境如下 Linux版本:CentOS release 6.7 (Final) Redis版本: Redis已经成功安装,安装路径为/home/idata/yangfan/lo ...

  8. [转载] Redis集群搭建最佳实践

    转载自http://blog.csdn.net/sweetvvck/article/details/38315149?utm_source=tuicool 要搭建Redis集群,首先得考虑下面的几个问 ...

  9. Linux Redis集群搭建与集群客户端实现

    硬件环境 本文适用的硬件环境如下 Linux版本:CentOS release 6.7 (Final) Redis版本: Redis已经成功安装,安装路径为/home/idata/yangfan/lo ...

随机推荐

  1. 「考试」联赛模拟36-39,noip晚间小测2-3

    36.1 party(CF623D) 很是鸡贼的一道题 首先要明确一点,抓人是有策略,而不是随机的,可以认为等同于按一个给定的顺序猜人,那么这时猜中的概率就只是抓住这个人的概率了 对于每一次猜测,因为 ...

  2. 【2014广州市选day1】JZOJ2020年9月12日提高B组T2 导弹拦截

    [2014广州市选day1]JZOJ2020年9月12日提高B组T2 导弹拦截 题目 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统 V1.0.但是这种导弹拦截系统有一个缺 ...

  3. vue富文本编辑器vue-quill-editor

    1.下载Vue-Quill-Editor npm install vue-quill-editor --save 2.下载quill(Vue-Quill-Editor需要依赖) npm install ...

  4. PyQt(Python+Qt)学习随笔:containers容器类部件QStackedWidget堆叠窗口属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.堆叠窗口简介 StackedWidget堆叠窗口部件为一系列窗口部件的堆叠,对应类为QStack ...

  5. 第14.16节 爬虫实战2:赠人玫瑰,手留余香! request+BeautifulSoup实现csdn博文自动点赞

    写在前面:本文仅供参考学习,请勿用作它途,禁止转载! 在<第14.14节 爬虫实战准备:csdn博文点赞过程http请求和响应信息分析>老猿分析了csdn博文点赞处理的http请求和响应报 ...

  6. centos7.5以上poenssl和openssh升级

    2020年12月09日,360CERT监测发现  openssl  发布了  openssl 拒绝服务漏洞  的风险通告,该漏洞编号为  CVE-2020-1971  ,漏洞等级:高危 ,漏洞评分:7 ...

  7. CF1406E 【Deleting Numbers】

    蒟蒻语 蒟蒻这次 \(CF\) 又双叒叕掉分了,\(C\) 都没有调出来. 还好再最后 \(10\) 秒钟调了下 \(E\) 块长 (块长 \(100\) => \(98\)),才没有掉得那么惨 ...

  8. 前端进阶之认识与手写compose方法

    目录 前言:为什么要学习这个方法 compose简介 compose的实现 最容易理解的实现方式 手写javascript中reduce方法 redux中compose的实现 参考文章 最后 前言:为 ...

  9. rpl_semi_sync_master_wait_no_slave 参数研究实验

    最近在研究MySQL,刚学到半同步. 半同步的配置中,关于这两个参数: rpl_semi_sync_master_wait_no_slave rpl_semi_sync_master_wait_for ...

  10. 二、Linux文件系统结构

    为了方便管理文件和目录,Linux 系统将它们组织成一个以根目录 / 开始的倒置的树状结构.Linux 中的目录,和 Windows 系统中的文件夹类似,不同之处在于,Linux 系统中的目录也被当做 ...