Redis 性能优化

这篇具有很好参考价值的文章主要介绍了Redis 性能优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

当我们操作 Redis 发现耗时较长时,原因可能有两个:

  • 服务间存在网络延迟
  • Redis 服务本身存在问题

如果是第一种情况,那么所有服务都会发生网络延迟,只需要联系运维处理即可,这里主要讨论第二种情况


Redis 基准性能测试

基准性能指 Redis 在一台负载正常的机器上的最大响应延迟和平均响应延迟,我们可以找一台同配置的机器,与原机器比较基准性能,看看 Redis 是不是真的变慢了

从 Redis 2.8.7 开始,redis-cli 命令可以追加 –intrinsic-latency 选项,用于监测和统计某个时间段内 Redis 的最大延迟

# 60 指的是测试时长为 60s,可以任意指定
redis-cli -h 127.0.0.1 -p 6379 --intrinsic-latency 60
Max latency so far: 1 microseconds.
Max latency so far: 157 microseconds.
Max latency so far: 173 microseconds.
Max latency so far: 323 microseconds.
Max latency so far: 324 microseconds.
Max latency so far: 325 microseconds.
Max latency so far: 334 microseconds.
Max latency so far: 520 microseconds.
Max latency so far: 527 microseconds.
Max latency so far: 591 microseconds.
Max latency so far: 1178 microseconds.
Max latency so far: 2299 microseconds.
Max latency so far: 2881 microseconds.
Max latency so far: 4113 microseconds.

597018388 total runs (avg latency: 0.1005 microseconds / 100.50 nanoseconds per run).
Worst run took 40926x longer than the average latency.

从输出结果可以看出 60s 内最大延迟是 4113 微秒

使用以下命令,查看 Redis 的最小、最大、平均访问延迟

``shell
redis-cli -h 127.0.0.1 -p 6379 --latency
min: 0, max: 6, avg: 0.24 (6064 samples)

按 ctrl + c 结束命令,可见平均延迟为0.24ms,共统计了 6064 个样本数据

还可以使用以下命令,查看一段时间内 Redis 的最小、最大、平均访问延迟

```shell
redis-cli -h 127.0.0.1 -p 6379 --latency-history -i 1
min: 0, max: 1, avg: 0.29 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.25 (96 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.28 (96 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.26 (96 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.27 (97 samples) -- 1.00 seconds range
...

以上输出结果是,每隔 1 秒采样 Redis 的平均操作耗时,其结果分布在 0.25 ~ 0.29ms 之间

通过以上命令,我们可以在相同配置的服务器上测试比较 Redis 的基准性能,找到可能变慢了的 Redis 实例


原因分析

找到目标,接下来分析可能导致 Redis 变慢的因素

1. 使用慢日志查询耗时命令

Redis 提供了慢日志命令的统计功能,它记录了有哪些命令在执行时耗时比较久

查看 Redis 慢日志之前,你需要设置慢日志的阈值,例如,设置慢日志的阈值为 10ms,并且保留最近 128 条慢日志记录

在 redis.conf 中设置,重启 Redis 实例来生效

slowlog-log-slower-than 10000
slowlog-max-len 128

也通过 CONFIG SET 命令动态设置

CONFIG SET slowlog-log-slower-than 10000
CONFIG SET slowlog-max-len 128

执行 slowlog get 命令查询最近记录的慢日志,可以指定返回条数,不指定默认十条

127.0.0.1:6379> SLOWLOG get 5
1) 1) (integer) 32693       # 慢日志ID
    2) (integer) 1593763337  # 执行时间戳
    3) (integer) 5299        # 执行耗时(微秒)
    4) 1) "LRANGE"           # 具体执行的命令和参数
        2) "user_list:2000"
        3) "0"
        4) "-1"
2) 1) (integer) 32692
    2) (integer) 1593763337
    3) (integer) 5044
    4) 1) "GET"
        2) "user_info:1000"
.....

通过查看慢日志,我们就可以知道在什么时间点,执行了哪些命令比较耗时,一般原因有以下两个:

  • 使用复杂度过高的命令,如 SORT、SUNION、ZUNIONSTORE 等聚合类命令,
  • 查询返回数据量过大

2. 操作 bigkey

如果你查询慢日志发现,并不是复杂度过高的命令导致的,而都是 SET / DEL 这种简单命令出现在慢日志中,那么你就要考虑你的实例否写入了 bigkey

Redis 在写入数据时,需要为新的数据分配内存,相对应的,当从 Redis 中删除数据时,它会释放对应的内存空间。如果一个 key 写入的 value 非常大,那么 Redis 在分配内存时就会比较耗时。同样的,当删除这个 key 时,释放内存也会比较耗时,这种类型的 key 我们一般称之为 bigkey

Redis 提供了扫描 bigkey 的命令,用于扫描一个实例 bigkey 的分布情况

redis-cli -h 127.0.0.1 -p 6379 --bigkeys

...
-------- summary -------

Sampled 829675 keys in the keyspace!
Total key length in bytes is 10059825 (avg len 12.13)

Biggest string found 'key:291880' has 10 bytes
Biggest   list found 'mylist:004' has 40 items
Biggest    set found 'myset:2386' has 38 members
Biggest   hash found 'myhash:3574' has 37 fields
Biggest   zset found 'myzset:2704' has 42 members

36313 strings with 363130 bytes (04.38% of keys, avg size 10.00)
787393 lists with 896540 items (94.90% of keys, avg size 1.14)
1994 sets with 40052 members (00.24% of keys, avg size 20.09)
1990 hashs with 39632 fields (00.24% of keys, avg size 19.92)
1985 zsets with 39750 members (00.24% of keys, avg size 20.03)
  • 该命令使用 scan 方式对 key 进行统计,所以无需担心造成阻塞,但可能会对 Redis 实例造成一定的负担
  • 输出大概分为两部分,summary 之上的部分只是显示了扫描的过程,summary 部分给出了每种数据结构中最大的 Key
  • 统计的 bigkey 只有 string 类型是以字节长度来衡量,list、set、zset 等都是以元素个数作为衡量,不能说明其占用内存就一定多

针对 bigkey 导致延迟的问题,有两点可以优化:

  • 将 bigkey 拆分成多个小的 key,需要修改应用程序的代码
  • 使用压缩算法来减小对象的大小
  • 如果你使用的 Redis 是 4.0 以上版本,用 unlink 命令替代 del 命令异步删除
  • 如果你使用的 Redis 是 6.0 以上版本,可以开启 lazy-free 机制(lazyfree-lazy-user-del = yes),在执行 del 命令时,释放内存也会放到后台线程中执行

3. 集中过期

如果有大量的 key 在某个固定时间点集中过期,在这个时间点访问 Redis 时,就有可能导致延时变大,如果此时需要过期删除的是一个 bigkey,那么这个耗时会更久

解决办法是分散过期时间,可以为集中过期 key 增加一个随机过期时间。如果你使用的 Redis 是 4.0 以上版本,可以开启 lazy-free 机制(lazyfree-lazy-expire yes),当删除过期 key 时,把释放内存的操作放到后台线程中执行,避免阻塞主线程

4. 可用内存达到上限

Redis 可以设置最大可用内存(maxmemory),默认是实例内存。当 Redis 达到 maxmemory 时,Redis 必须清除部分数据,从而造成延迟。如果存储了 bigkey,那么耗时会更久

使用 info memory 命令查看 Redis 内存占用情况,比较 used_memory 和 maxmemory

localhost:6379> info memory
used_memory:692264  # redis 服务器分配的内存总量,也就是内部存储数据的内存占用量
used_memory_human:676.04K  # 以可读形式返回 used_memory
used_memory_rss:655336  # 从操作系统的角度返回 redis 进程占用的物理内存总量
.....
maxmemory:0  # redis 能使用的最大内存上限,0 表示没有上限
maxmemory_human:0B  # 以可读形式返回 maxmemory

可以调整 Redis 的内存淘汰策略,比如改为随机淘汰,随机淘汰速度要快很多,尽可能减少耗时。如果使用的是 Redis 4.0 以上版本,开启 layz-free 机制,把淘汰 key 释放内存的操作放到后台线程中执行(lazyfree-lazy-eviction = yes)

5. fork 耗时

当 Redis 开启了后台 RDB 和 AOF rewrite 后,需要主进程创建出一个子进程进行数据的持久化。主进程创建子进程,会调用操作系统提供的 fork 函数。而 fork 在执行过程中,主进程需要拷贝自己的内存页表给子进程,如果这个实例很大,那么这个拷贝的过程也会比较耗时

可以执行 info stats 命令获取到 latest_fork_usec 指标,表示 Redis 最近一次 fork 操作耗时,如果耗时很大,比如超过1秒,则需要做出优化调整

localhost:6379> info stats
...
latest_fork_usec:59477  # 上一次 fork 耗时,单位微秒
...

推荐在低峰期进行备份,而对于丢失数据不敏感的业务(例如把 Redis 当做纯缓存使用)可以关闭持久化文章来源地址https://www.toymoban.com/news/detail-778565.html

到了这里,关于Redis 性能优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • redis 性能优化一

    目录 前言 尾延迟 前言 说到redis 性能优化,优化的目的是什么?提高响应,减少延迟。就要关注两点,一是尾延迟,二是Redis 的基线性能。只有指标,我们的优化,才有意义,才能做监控以及报警。这些指标需要借助一定工具进行压力测试,高于这个值就说明需要优化了,这

    2024年03月14日
    浏览(38)
  • 【Redis】Redis性能优化:理解与使用Redis Pipeline

    原创不易,注重版权。转载请注明原作者和原文链接 当我们谈论Redis数据处理和存储的优化方法时,「 Redis Pipeline 」无疑是一个不能忽视的重要技术。 在使用Redis的过程中,频繁的网络往返操作可能会引发严重的性能问题,尤其是当大量并发操作需要快速响应的时候。这就是

    2024年02月07日
    浏览(29)
  • Redis性能优化:理解与使用Redis Pipeline

    本文已收录至GitHub,推荐阅读 👉 Java随想录 微信公众号:Java随想录 原创不易,注重版权。转载请注明原作者和原文链接 目录 Pipeline介绍 原生批命令(MSET, MGET) VS Pipeline Pipeline的优缺点 一些疑问 Pipeline代码实现 当我们谈论Redis数据处理和存储的优化方法时,「 Redis Pipeline 」

    2024年02月08日
    浏览(39)
  • Redis缓存设计与性能优化

    缓存穿透是指查询一个根本不存在的数据, 缓存层和存储层都不会命中 , 通常出于容错的考虑, 如果从存储层查不到数据则不写入缓存层。 缓存穿透将导致不存在的数据每次请求都要到存储层去查询, 失去了缓存保护后端存储的意义。 造成缓存穿透的基本原因有两个:

    2024年02月07日
    浏览(36)
  • 6. Redis缓存设计与性能优化

    本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。 课程内容: 1、多级缓存架构详解 2、缓存穿透缓存击穿缓存雪崩详解 3、热点缓存key重建优化 4、缓存与数据库双写不一致终极解决 5、Redis开发规范与性能优化 ngnix到Lua到web层,到re

    2024年02月11日
    浏览(38)
  • Redis10大性能优化策略(下)

    1)尽量不使用 O(N) 以上复杂度过高的命令,对于数据的聚合操作,放在客户端做。 2)执行 O(N) 命令,保证 N 尽量的小(推荐 N = 300),每次获取尽量少的数据,让 Redis 可以及时处理返回。 一般有两种方案来规避这个问题: 1.集中过期 key 增加一个随机过期时间,把集中过期

    2024年02月13日
    浏览(37)
  • Redis10大性能优化点(上)

    对 Redis 进行基准性能测试 例如,我的机器配置比较低,当延迟为 2ms 时,我就认为 Redis 变慢了,但是如果你的硬件配置比较高,那么在你的运行环境下,可能延迟是 0.5ms 时就可以认为 Redis 变慢了。 所以,你只有了解了你的 Redis 在生产环境服务器上的基准性能,才能进一步

    2024年02月12日
    浏览(40)
  • 49.Redis缓存设计与性能优化

    缓存与数据库双写不一致 小概率事件 //线程1 写数据库stock = 5 ---------------》更新缓存 //线程2 写数据库stock = 4 -----》更新缓存 //线程1 ------》写数据库stock = 10 -----》删除缓存 //线程2 -----------------------------------------------------------------------------------------------》写数据库stock = 9 -

    2024年02月08日
    浏览(32)
  • Redis 高并发下的性能优化技术

    Redis是一款高性能的键值存储数据库。与传统的数据库相比,Redis拥有更高的读写速度以及更丰富的数据结构支持。 尽管Redis拥有出色的性能表现,但在高并发场景下其仍存在着一些性能问题需要我们注意。本文将围绕这些问题进行分析,并提供一些解决方案。 Redis采用单进程

    2024年02月10日
    浏览(44)
  • 【Redis 神秘大陆】005 常见性能优化方式

    https://github.com/sohutv/cachecloud/blob/main/redis-ecs/script/cachecloud-init.sh 5.2.1 维度化缓存 在电商系统中,一个商品可能包含多个维度的数据,如基础属性、图片列表、上下架状态、规格参数、商品介绍等。针对这种情况,可以采用维度化缓存方案进行优化,以减少更新成本和服务压力

    2024年04月17日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包