• 记一次Redis KEY莫名丢失的问题排查


    第一次察觉有key被莫名删除时:

    1. 首先想到的是不是内存不足,导致被淘汰了,赶紧查看内存使用情况:
      1. # free -m
      2. total used free shared buffers cached
      3. Mem: 8023 7535 488 1 100 373
      4. -/+ buffers/cache: 7061 961
      5. Swap: 3967 2198 1769

      内存有余量。

    2. 那是不是redis配置里限制了redis的最大内存呢,看一下redis配置文件,
      vim /..../redis.conf
      

      看了下没对maxmemory做限制。

    3. redis-cli ,进入客户端
      查看内存概况
      1. 127.0.0.1:6379[1]> info memory
      2. # Memory
      3. used_memory:2375848#由Redis分配器分配的内存总量,
      4. used_memory_human:2.27M # 以人易读的格式返回
      5. used_memory_rss:8454144#从操作系统的角度,返回 Redis 已被分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致,即RSS。
      6. used_memory_rss_human:8.06M
      7. used_memory_peak:5255280#redis使用内存的峰值
      8. used_memory_peak_human:5.01M
      9. total_system_memory:8412987392#系统内存
      10. total_system_memory_human:7.84G
      11. used_memory_lua:37888 #Lua 引擎所使用的内存大小
      12. used_memory_lua_human:37.00K
      13. maxmemory:0 #0表示不限制
      14. maxmemory_human:0B
      15. maxmemory_policy:allkeys-lru#key的缓存淘汰策略
      16. mem_fragmentation_ratio:3.56#used_memory_rss 和 used_memory 之间的比率
      17. mem_allocator:jemalloc-4.4.0#编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc

      1)当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。
      内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。
      2)当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。
      3)当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory 的值可能和操作系统显示的 Redis 内存占用并不一致。查看 used_memory_peak 的值可以验证这种情况是否发生。

      可以看到used_memory并没有多少,至此可以看出不是内存不足了
      不带单位的,默认的单位是B

      尝试写入几次,发现被删除的时间约为1min左右,怀疑是有脚本在执行特殊命令
      于是乎,执行:
       

      redis-cli monitor >/home/redis/redis-op.log
      

      查看客户端都执行了什么命令,通过观察log文件内容变化,发现问题所在:

      1. # tail -f /home/fpf/redis-op.log
      2. .......
      3. 1611058888.482474 [1 200.200.107.241:48126] "SELECT" "1"
      4. 1611058888.482548 [1 200.200.107.241:48126] "HSET" "JOIN_DOMAIN:6c7bd46a70bd7477937dc90313461aa5" "12345665698" "200.200.170.29"
      5. 1611058922.783485 [0 200.200.107.241:39078] "SELECT" "0"
      6. 1611058922.786919 [0 200.200.107.241:39078] "PING"
      7. 1611058922.787479 [0 200.200.107.241:39078] "GET" "mjcogmt5frm185597sea37ehqq"
      8. 1611058922.811595 [0 200.200.107.241:39082] "SELECT" "1"
      9. 1611058922.811844 [1 200.200.107.241:39082] "KEYS" "visit:*"
      10. 1611058922.811985 [1 200.200.107.241:39082] "FLUSHDB"
      11. 1611058922.854436 [0 200.200.107.241:39078] "PING"
      12. ......

      可以清晰的看到对于db 1操作,在HSET后会有个FLUSHDB动作,破案完结

      题外话

      在处理问题的过程中,发现info这个命令还是挺好用的,

      1. #直接执行info可以看到redis服务的很多信息,但太多,容易眼花,可以加个选项,例如
      2. 127.0.0.1:6379> info commandstats
      3. # Commandstats
      4. cmdstat_get:calls=2,usec=9,usec_per_call=4.50
      5. cmdstat_setex:calls=2,usec=9,usec_per_call=4.50
      6. cmdstat_hset:calls=1,usec=4,usec_per_call=4.00
      7. cmdstat_select:calls=4,usec=5,usec_per_call=1.25
      8. cmdstat_keys:calls=2,usec=18,usec_per_call=9.00
      9. cmdstat_ping:calls=4,usec=3,usec_per_call=0.75
      10. cmdstat_flushdb:calls=1,usec=20,usec_per_call=20.00
      11. cmdstat_info:calls=7,usec=505,usec_per_call=72.14
      12. cmdstat_config:calls=1,usec=6,usec_per_call=6.00

      可以在不重启服务的情况下通过 config resetstat重置info commandstats结果

      另外 config 这个命令也挺好用的

      1. 127.0.0.1:6379> config get maxmemory
      2. 1) "maxmemory"
      3. 2) "0"

       

    4. 参考资料

      1:查看redis内存使用情况
      2:redis内存管理
      3:redis maxmemory配置

  • 相关阅读:
    22. 深度学习 - 自动求导
    【kafka】 | 01 | kafka和zookeeper的部署及使用方法
    网易内部高并发进阶笔记, GitHub 抢先开源,标星 89k,下载已破百万
    MySQL数据库
    Palo Alto PAN-OS 10.1 for vSphere & KVM -- 基于机器学习的新一代防火墙
    矩阵分析与应用-5.3-共轭梯度与无约束最优化
    交叉导轨究竟用在哪里?
    【面试高高手】—— Java进阶
    弘辽科技:淘宝店流量一直起不来是为什么?流量少怎么办?
    HarmonyOS【ArkUI组件--TextInput】
  • 原文地址:https://blog.csdn.net/WXF_Sir/article/details/126371259