标题:【Redis30】Redis进阶:一些简单运维技巧

文章目录
    分类:存储运维 标签:Redis

    Redis进阶:一些简单运维技巧

    关于 Redis 的运维,我的经验仅限于安装、备份,而且还是最简单的利用一些面板工具。之前很多篇文章中我都强调过,我没有 Redis 的主从及分布式的真实项目经历。经历过的流量最大的项目也只是一台 Redis 实例就抗住了。毕竟 Redis 具有号称单机单实例写入 8万/秒 ,读取 11万/秒 的能力,咱们一般的项目根本达不到啊。而且即使机器性能有差异,减一半,甚至减三分之一,3万/秒 的读取和写入的系统咱也没接触过。(最大接触到的是 3000条数据/秒 写入 List 队列)


    因此,用不上也就接触不到,简单配置的一台 Redis 的性能就比我所接触过的最高流量上限还高了很多了。很多运维及优化相关的内容没法以真实的项目经验来做为参考,这里也就只能是将一些看过的有印象的资料分享出来。

    查看大 Key

    Redis本身提供发现大对象的工具,对应命令:redis-cli --bigkeys 。注意,是 redis-cli 的参数哦。

    ➜  ~ redis-cli --bigkeys
    # Scanning the entire keyspace to find biggest keys as well as
    # average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
    # per 100 SCAN commands (not usually needed).
    
    [00.00%] Biggest string found so far '"a"' with 3 bytes
    [00.00%] Biggest list   found so far '"b"' with 4 items
    
    -------- summary -------
    
    Sampled 2 keys in the keyspace!
    Total key length in bytes is 2 (avg len 1.00)
    
    Biggest   list found '"b"' has 4 items
    Biggest string found '"a"' has 3 bytes
    
    1 lists with 4 items (50.00% of keys, avg size 4.00)
    0 hashs with 0 fields (00.00% of keys, avg size 0.00)
    1 strings with 3 bytes (50.00% of keys, avg size 3.00)
    0 streams with 0 entries (00.00% of keys, avg size 0.00)
    0 sets with 0 members (00.00% of keys, avg size 0.00)
    0 zsets with 0 members (00.00% of keys, avg size 0.00)

    我这里没什么数据,所以可能看不出啥效果,虽说看不出,但咱也得简单解释一下。

    • Biggest string found so far '"a"' with 3 bytes 包括下面那一条,就是每个类型中所找到的最大的 Key

    • 底下还会统计每个类型中有几个,复合类型中有几个 items 或者 fields ,同时在这些内容中,一些比例信息,平均的大小等

    虽说有这些内容,如果需要按照某个阈值来查找指定的大键,还是没法通过 --bigkey 来实现。这时,其实可以通过另外一个内部命令来实现。

    127.0.0.1:6379> hmset c a 111111 b 22
    OK
    
    127.0.0.1:6379> DEBUG OBJECT c
    Value at:0x7fc197352960 refcount:1 encoding:ziplist serializedlength:26 lru:13093574 lru_seconds_idle:12

    DEBUG OBJECT 用于返回调试对象的基本信息。在这些信息中,我们可以看到它现在是 ziplist 格式,数据长度为 serializedlength ,简单地理解,它就可以看成是 strlen 查看 String 类型的结果。这样,我们就可以根据不同的 Key 占据的字节长度来确定哪些是大 Key 。怎么删除大 Key ?不记得的小伙伴赶紧来复习一下哦。


    再问一个:怎么遍历所有的 Key ?忘了 SCAN 命令了?不记得的小伙伴也请赶紧来复习一下。

    操作大 Key

    操作大 Key 一般是读写两个方面,读的话好说,尽量用 scan 系列命令代替 KEYS *,还包括 hscansscanzscan 。写的话,分段写,不要一次大批量(几万上百万)的插入、更新,或者干脆别用大 Key 。删除的话,unlink 还记得吧,另外 6 以上版本,开启 lazy-free 也可以让 del 去后台运行。查询数量,llenhlenscardzcard 的性能没问题,链表有记录数量字段,返回很快。


    记住,范围操作都很惨!全是我们之前学习过的内容,这个 bigkey 问题也是非常常见的面试题。

    监控系统信息

    通过 redis-cli --stat 命令,可以实时地监控当前 Redis 的使用情况。同样,它也是一个 redis-cli 的参数工具。

    ➜  ~ redis-cli --stat
    ------- data ------ --------------------- load -------------------- - child -
    keys       mem      clients blocked requests            connections
    3          1.11M    1       0       92459301 (+0)       932
    3          1.11M    1       0       92459302 (+1)       932
    3          1.11M    1       0       92459303 (+1)       932
    3          1.11M    1       0       92459304 (+1)       932
    ………………
    ………………

    运行之后,会不停地输出当前 Redis 的信息,包括 Key 的数量,占用内存的大小,连接的客户端信息等等。

    查看内存交换情况

    内存交换就是我们 Linux 系统中的 SWAP 部分的内容。当物理内存不够的时候,会借用一些磁盘空间来当做类似 Windows 的虚拟内存空间。既然一提到磁盘了,那肯定就有一个问题,性能会剧烈下降。


    那么我们要怎么知道,当前 Redis 是否使用了 SWAP 了呢?


    首先看下当前 Redis 的进程 ID 。

    ➜  ~ redis-cli info server | grep process_id
    process_id:820

    然后,到操作系统的 /proc 目录下查看内存交换情况。

     cat /proc/4476/smaps | grep Swap
     Swap: 0 kB
     ………………

    如果交换量都是 0kB 或者个别的是 4kB ,则是正常现象,说明Redis进程内存没有被交换。好了,现在我们知道了会有这个交换内存的情况,也知道了怎么查看有没有发生内存交换,那么预防内存交换的方法有哪些呢?

    • 保证机器充足的可用内存。

    • 确保所有 Redis 实例设置最大可用内存(maxmemory),防止极端情况下 Redis 内存不可控的增长。

    • 降低系统使用swap优先级,如echo 10 > /proc/sys/vm/swappiness ,具体信息大家可以查阅 Linux 相关的资料。

    连接数问题

    在学习配置文件时,我们就看到过,Redis 的连接数可以通过 maxclients 这个参数进行配置,默认情况下它是 10000 。当我们有超过 10000 个客户端来连接时,Redis 就会拒绝连接。


    info 命令下的 stats 子命令中,有一个 rejected_connections 属性,表示的就是被拒绝的连接的数量。

    ➜  ~ redis-cli info stats | grep rejected
    rejected_connections:0

    可以通过查看这个属性,获得当前我们系统的连接情况,看是不是要适当调节 maxclients 的大小。注意,如果是非本机连接,还要注意操作系统的 ulimit 情况。

    内存碎片

    同样在配置文件中,我们也学习过内存碎片相关的配置信息。在系统的实际运行中,其实也可以在 info memory 中查看到内存碎片的信息。

    127.0.0.1:6379> info memory
    # Memory
    used_memory:1163184
    …………
    used_memory_rss:1626112
    …………
    …………
    mem_fragmentation_ratio:1.45
    …………

    需要重点关注的就是上面这三个属性的值。

    • used_memory 使用的内存

    • used_memory_rss 从系统角度,显示Redis进程占用的物理内存总量,与top及ps命令看到的值是一致的

    • mem_fragmentation_ratio 上面这两位的比值

    实际使用的内存比系统显示占用的内存小,说明有一些内存没有被正式的数据使用,而是被内存碎片占用了。如果两者相差很大,说明碎片率很严重。不过 mem_fragmentation_ratio 如果小于 1 也不是什么好事,说明 Redis 使用了 SWAP 交换内存到磁盘了。


    注意到我这里的 mem_fragmentation_ratio 比值计算其实是不精准的,1626112/1163184 约等于 1.40 ,这一块并没有找到合适的资料来解释,有相关经验的小伙伴可以留言告知一下哈,或许也可能是我本地没什么数据,还有别的虚占内存被计算了之类的。要么咱们就暂且认为 mem_fragmentation_ratio 的公式并不是完全的 used_memory_rss/used_memory ,可能还有别的参数。


    可以看出,这个值大于 1 ,小于 1 都不是什么好事,但也很难控制在完整的 1 上,因此,一般认为在 1 到 1.5 之间是比较健康的,超过 1.5 了就表示有 50% 的内存被碎片占用了。


    内存碎片的处理,一是可以在配置文件中打开 activedefrag 让系统自动进行碎片整理,另外也可以通过命令 MEMORY PURGE 命令手动清理,但这个命令会占用主进程,如果本身 Redis 占用的内存非常大的话,会造成进程卡顿。

    缓存命中率

    这个问题印象很深刻啊,为啥?因为面试的时候被问到过,当时年轻的我当然毫无意外的回答不出来。其实,也是通过 info 就可以查看到缓存的命中情况,然后根据一个公式就可以计算出缓存的命中率了。

    127.0.0.1:6379> info stats
    # Stats
    ……………………
    keyspace_hits:3316018
    keyspace_misses:6362034
    ……………………

    是的,就是这两个属性值。从名称就可以看出,一个是键空间命中数,一个是未命中数。


    有了这两个基础值后,命中率就可以这么算:命中数/(命中数+未命中数)。


    上面信息中我们的系统命中率就是 3316018/(3316018+6362034) = 0.34 ,好像有点低呀,可不是,咱这是本地测试机呀。如果确实是命中率过低,要检查缓存击穿的问题,这个很影响命中率。另外还要注意的就是缓存过期和失效的时机与架构设计,都是影响命中率的关键。

    总结

    Redis 正式学习系列的内容到此为止了。通过这 30 篇文章和视频的学习,相信咱们对基础的 Redis 使用应该是没有什么太大的问题了,至少大部分面试常见题也是能够轻松应对了。或者说,最差最差咱也不只是会用 GET、SET 的那一类码农了,多少还是知道 List 、Hash 、Set 、Sorted Set 这些数据类型以及它们的应用场景了。


    好了,后续如果还有 Redis 相关的内容,应该也是偏优化和实战方面的内容,不会包含在这个系列中,会是单独的文章或者是其它学习系列中牵涉到 Redis 部分的一些内容。


    感谢大家的支持,脚步不要停歇,咱们接下来就先进入到 Nginx 的学习中吧。

    视频链接

    微信文章地址:https://mp.weixin.qq.com/s/CVY5BnsyOQ6PhSBCG-59mg

    B站视频地址:https://www.bilibili.com/video/BV11h4y1D74X/

    微信视频地址:https://mp.weixin.qq.com/s/ar_f-6qPg1-oC4WpigdGPg

    搜索
    关注