Django连接Redis集群问题排查思路和总结
wptr33 2024-12-25 16:02 15 浏览
问题背景
- Django 项目第一次发布到生产环境,启动后发现连不上 Redis 集群。
- 测试环境的 redis 集群没有密码,导致测试环境生产的配置格式会有差异
- 生产环境使用的 redis 配置,之前没人验证过,不知道是单机还是集群
- 生产环境 redis 的密码中特殊符合 @,同事说可能会 Django Cache 配置的 URI 切割符号冲突,他之前在 celery broker_url 配置时就遇到这个坑。
排查思路
- 测试环境和生产环境的配置不一样,因此要格外小心,生产环境配置不能照抄测试环境的
- 优先使用官方 redis-cli 确定 redis 是集群还是客户端,再去修改代码相关的配置
- 本地无法连接生产环境,因为需要通过跳板机登录上去生产环境,直接利用 Django shell 调试,而不每次修改代码后重新提交,然后构建。
- 出问题时,优先怀疑自己的代码问题,而不是找框架本身的问题,尤其是 Django 这种大框架。
排查过程
确认客户端类型
- 做一个最简单的 set 命令测试,直接报错。
rhea-flaskapi-live-sg(sg2|10.xxx:40681)@/workspace$ redis-cli -h redis.xxx.shopee.io -p 10010 -a xxxx@123
redis.xxx.shopee.io:10010> set a 123
(error) MOVED 15495 10.xxx.104:10011
- 经过搜索引擎查询,确认这个 redis 是集群,集群的连接命令是 redis-cli -c -h 连接地址 -p 端口 -a 密码 上面的命令少了 -c 参数
启动 Django Shell 连接 redis
from django_redis import get_redis_connection
conn = get_redis_connection()
直接就一个连接失败
确认账号密码和端口没问题后,问题同事配置有没验证过,他说直接从网上 cv 的,完全没经过验证。坑啊!!!
修改配置后重新测试
把生产的配置和测试配置比较好,修改了几个地方
- LOCATION 从 str 改成 List[str] ,加上默认 db ,也就是 [ f'redis://{DEFAULT_REDIS_URL}:{DEFAULT_REDIS_PORT}/0']
- REDIS_CLIENT_CLASS': 'rediscluster.RedisCluster 这个集群连接需要的客户端
- 连接池配置改成 'CONNECTION_POOL_CLASS': 'rediscluster.connection.ClusterConnectionPool'
信心满满,重启启动 django shell 测试,结果还是连接不上!这时候心情开始有点糟糕~
冷静, django shell 不行,那用 python shell 直连试试?
Python Shell 直连 redis
一点毛病都没有,直接连上了!
一脸懵逼,这到底是啥问题啊!
不死心,反复修改配置,测试 Django Shell 连接 Redis
结果依然是连接不上。
下班回家过程中的思考
不知不觉已经到了晚上九点,好累,不想卷了。下班回家吧
回家路上整个脑子都被这个问题困扰着。难道密码中含有 @ 符号的 redis 集群,Django 真的连接不上?反复的问自己。
问了其他同事,生产环境是否有其他的 redis 集群可以用来调试。很遗憾,并没有。
要不,我自己创建一个 redis 集群,把密码设置成含有 @ 符号?
可是,自己本地创建 redis 集群好麻烦啊。要本地安装虚拟机,想到一堆配置就直接劝退。
回到家后的纠结
洗完澡,和老婆聊了 1h 左右的视频。已经到 11 点多,准备睡觉?
那是不可能的,带着问题是很难入睡!哎,这个是老毛病了。
突然想到了一个点,最小试错原则。自己搭建本地集群很麻烦,公司又没有多余的集群。
那直接买一个云版的 redis 集群?说干就干,直接从床上起来,打开电脑。
最小试错原则,买云 Redis 集群,而不是自己搭建
这时问题又来了,阿里云还是腾讯云?
鉴于双 11 买了腾讯云 2c 4g 8m 的服务器,只要 199 就能 3 年。
再对比之前买阿里云那个 1c 2g 1m 服务器,3 年也要 100 多。
瞬间对腾讯云好感倍增,决定先买腾讯云。
买腾讯云 redis 集群
一顿操作,发现腾讯云是真的难用:
- 购买页面选好配置好,提交后,因为我没有余额,提示我充值。等我充值完,结果之前选择的配置没了,只好重新选择。
- redis 集群没有重启功能???
- 设置安全组时,只能在安全组的页面绑定实例;在实例页面无法绑定安全组。
最最最重要,给把实例绑定了安全组后,外网还是无法访问???(不管了,反正我就是很生气)
买阿里云 redis 集群
对腾讯云太失望了,不得不把最后一根稻草压在阿里云身上。
所幸,阿里云没有让我失望!
咔咔咔,一顿操作:
- 创建实例,这点阿里云是比腾讯云慢很多,大概要 7min 左右(纯感觉)
- 配置外网访问,很方便。这操作逻辑简直是秒杀腾讯云。
- 配置白名单,redis-cli 连接测试,成功通过!
- 修改配置,启动 Django shell 测试。
密码中含有 @ 符号,但连接一点毛病都没有!!!
至此,问题终于解决了!!!
我已经迫不及待明天去公司验证,但回过头一看,已经是深夜一点半。
自言自语的说了一句:"睡吧,卷王"
第二天去公司验证
rhea-flaskapi-live-sg(sg2|xxxx:26863)@/workspace$ python3.8 manage.py shell --settings=rhea.settings.prod
rhea.settings.prod
Python 3.8.7 (default, Oct 1 2021, 14:58:33)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django_redis import get_redis_connection
>>> conn = get_redis_connection()
>>>>conn.get("rhea:access_token:abc")
'huacai.li@shopee.com'
经过对比,发现配置只需要生产的配置仅需要在测试的配置上加多一个 :
修复最磨人的 bug,往往仅需要一点小小的改动~
为什么测试环境没报错了呢???
因为测试环境的 redis 集群不需要密码
总结
- 一切没经过自己验证的代码,一定要谨慎使用
- 最小试错原则。想验证一件事情时,尽量使用最小的成本去验证
- 生产和测试环境尽量保持配置相同
相关推荐
- Linux文件系统操作常用命令(linux文件内容操作命令)
-
在Linux系统中,有一些常用的文件系统操作命令,以下是这些命令的介绍和作用:#切换目录,其中./代表当前目录,../代表上一级目录cd#查看当前目录里的文件和文件夹ls#...
- 别小看tail 命令,它难倒了技术总监
-
我把自己以往的文章汇总成为了Github,欢迎各位大佬star...
- lnav:基于 Linux 的高级控制台日志文件查看器
-
lnav是一款开源的控制台日志文件查看器,专为Linux和Unix-like系统设计。它通过自动检测日志文件的格式,提取时间戳、日志级别等关键信息,并将多个日志文件的内容按时间顺序合并显示,...
- 声明式与命令式代码(声明模式和命令模式)
-
编程范式中的术语和差异信不信由你,你可能已经以开发人员的身份使用了多种编程范例。因为没有什么比用编程理论招待朋友更有趣的了,所以这篇文章可以帮助您认识代码中的流行范例。命令式编程命令式编程是我们从As...
- linux中的常用命令(linux常用命令和作用)
-
linux中的常用命令linux中的命令统称shell命令shell是一个命令行解释器,将用户命令解析为操作系统所能理解的指令,实现用户与操作系统的交互shell终端:我们平时输入命令,执行程序的那个...
- 提高工作效率的--Linux常用命令,能够决解95%以上的问题
-
点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf...
- 如何限制他人操作自己的电脑?(如何控制别人的电脑不让发现)
-
这段时间,小猪罗志祥正处于风口浪尖,具体是为啥?还不知道的小伙伴赶紧去补一下最近的娱乐圈八卦~简单来说,就是我们的小罗同事,以自己超强的体力,以及超强的时间管理能力,重新定义了「多人运动」的含义,重新...
- 最通俗易懂的命令模式讲解(命令模式百科)
-
我们先不讲什么是命令模式,先通过一个场景来引出命令模式,看看命令模式能解决什么样的问题。现在有一个渣男张三,他有还几个女朋友,你现在是不是还是单身狗,你就说你气不气?然后他需要每天分别叫几个女朋友起床...
- 互联网大厂后端必看!Spring Boot 中Runtime执行与停止命令?
-
你是否曾在使用SpringBoot开发项目时,遇到需要执行系统命令的场景?比如调用脚本进行文件处理,又或是启动外部程序?很多后端开发人员会使用Processexec=Runtime.get...
- Linux 常用命令(linux常用的20个命令面试)
-
日志排查类操作命令...
- Java字节码指令:if_icmpgt(0xA3)(java字节码使用的汇编语言)
-
if_icmpgt是Java字节码中的一条条件跳转指令,其全称是"IfIntegerCompareGreaterThan"。它用于比较两个整数值的大小。如果栈顶的第一个...
- 外贸干货|如何增加领英的曝光量和询盘
-
#跨境电商#...
- golang执行linux命令(golang调用shell脚本)
-
需求需要通过openssl生成rsa秘钥,然后保存该秘钥。代码实例packagemainimport("io/ioutil""bytes"&...
- LINUX磁盘挂载(linux磁盘挂载到windows)
-
1、使用root用户查看磁盘挂载情况:fdisk-l2、使用df查看当前磁盘挂载情况,根据和fdisk-l的结果进行对比,查看还有那些磁盘未使用3、挂载:mount磁盘挂载路径...
- Linux命令学习——nl命令(linux ln命令的使用)
-
nl命令主要功能为每一个文件添加行号,每一个输入的文件添加行号后发送到标准输出。当没有文件或文件为-时,读取标准输入...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
因果推断Matching方式实现代码 因果推断模型
-
git pull命令使用实例 git pull--rebase
-
面试官:git pull是哪两个指令的组合?
-
git 执行pull错误如何撤销 git pull fail
-
git pull 和git fetch 命令分别有什么作用?二者有什么区别?
-
git fetch 和git pull 的异同 git中fetch和pull的区别
-
git pull 之后本地代码被覆盖 解决方案
-
还可以这样玩?Git基本原理及各种骚操作,涨知识了
-
git命令之pull git.pull
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)