查看Redis各项指标

首先要能够连接到Redis并获取性能相关的指标。

本文使用redis-cli客户端指令连接到Redis,使用info [section]命令获取相关指标。

不指定section时,会获取所有10项指标:

  • Server
  • Clients
  • Memory
  • Persistence
  • Stats
  • Replication
  • CPU
  • Modules
  • Cluster
  • Keyspace

也可以指定section为其中之一,这样只会输出相关内容:

在这里插入图片描述

下面分析一下可能造成性能问题的指标。

基准性能

我们关注的一般是业务系统的性能,但是有些时候,业务系统的性能变慢了,并不一定是数据操作的问题。

所以,在业务接口,特别是外部调用接口进行时延统计是很有帮助的。

增加时延统计会在一定程度上增大时延,但是这种增加的时延,相对于解决问题时能够方便地定位,还是值得的。

一旦确定了是Redis数据存取性能导致的业务性能变差,就要专门针对Redis进行性能分析验证了。

在这之前,还是要知道一点,就是在正常情况下,Redis的性能到底怎么样呢,平均延迟和最大延迟分别是多少才是正常的?

注意,不同软硬件环境下,Redis的性能是不同的。可能,在配置较低的机器上,延迟个1ms都是正常的,但在性能较高的服务器上,延迟0.5ms都可能是Redis变慢了。

可以通过下面的方式查看60s内实例的最大响应延迟:

% redis-cli -h 127.0.0.1 -p 6379 --intrinsic-latency 60
Max latency so far: 1 microseconds.
Max latency so far: 5 microseconds.
Max latency so far: 17 microseconds.
Max latency so far: 26 microseconds.
Max latency so far: 194 microseconds.
Max latency so far: 198 microseconds.
Max latency so far: 201 microseconds.

1130732454 total runs (avg latency: 0.0531 microseconds / 53.06 nanoseconds per run).
Worst run took 3788x longer than the average latency.

为了避免业务服务器到 Redis 服务器之间的网络延迟,你需要直接在 Redis 服务器上测试实例的响应延迟情况。

从结果可以看到,60s内的最大响应时延为201us,即0.201ms。

也可以测试一段时间内Redis的最小、最大和平均时延:

% redis-cli -h 127.0.0.1 -p 6379 --latency-history -i 1
min: 0, max: 1, avg: 0.20 (98 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.24 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.21 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.23 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.18 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.23 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.22 (97 samples) -- 1.00 seconds range

可以看到,每隔1s,Redis的平时响应延迟在0.18-0.24ms之间。

综上,可以通过以下步骤来判断Redis实例是否变慢了:

  1. 在没有业务进行的情况下,在服务器上测试一个正常 Redis 实例的基准性能
  2. 测试待验证实例的基准性能
  3. 如果这个实例的运行延迟是正常 Redis 基准性能的 2 倍以上,就认为这个 Redis 实例确实变慢了

那么,就可以从以下方面查找Redis变慢的原因了。

内存

通过info memory查看信息。

在这里插入图片描述

这些信息反映了Redis存储数据所使用的内存,当前使用了341M。

注意,由于内存碎片等原因,这些值可能与Redis实际使用的内存并不绝对相等。

内存使用情况可能会导致严重的性能问题,如果Redis实例使用的内存超过可用内存,操作系统会把旧的页面写入磁盘。

要知道,从磁盘读写数据要比直接内存读写慢10^5(内存读写通常0.1us,而磁盘需要10ms)。

如果出现了页面交换问题,Redis的性能和依赖Redis数据的应用的性能都会受到与业务影响。

好在关注used_memory_human字段的值,基本就可以排除这个问题。

有以下方法可以尝试:

  • 如果所有数据远小于4GB,那么可以使用32-bit的Redis实例。

    • 指针在32-bit下是4个字节,而64bit是8个字节,这样能最大限度节省内存使用
    • 缺点是即使系统内存大于4G,32bit的Redis实例也只能使用4G内存
  • 尽量使用hash数据结构。

    • Redis使用非常的方式存储小hash数据(小于100个field)
    • 如在存储用户信息时,使用hash保存诸如name/addr/qq/wechat等信息要比单独以它们为key存储更高效
  • 设置超时时间。

    • 这是一个非常好的习惯
    • 对于不需要长期保存的数据,总是在写入数据时指定超时时间能够节省大量内存
  • 设定删除key的策略。

    • 可以在配置文件中指定使用的最大内存量
    • 对于不进行快照备份的实例,可以限定为系统内存的95%。对于快照备份,则减半到45%
    • 指定内存到达上限时的删除数据策略,一般使用volatile-ttl或者allkeys-lru就足够了
    • 支持的策略如下:

    在这里插入图片描述

命令数量

使用info stats可查看统计数据。

其中,重要的一条是:total_commands_processed,处理命令总量。

跟踪监控这个值可以很好地排查Redis性能问题。

因为Redis是单线程处理命令的,即使在6.0版本之后,处理指令的依然是单线程顺序进行。

通常情况下,1Gb/s的网络的延迟是200us,如果指令的响应时间明显大于200us,可能就是命令请求队列的数据太多了。

如果真是这种情况,你会发现total_commands_processed增长很快,甚至达到一个峰值。

如果是因为一些慢指令导致的延迟增大,那么看到的是total_commands_processed下降或者不变,而Redis性能却在下降。

不管哪种情况,都需要同时关注total_commands_processed指标和延迟情况,可以写个脚本定时记录total_commands_processed值。

下面是解决上述两种情况下导致延迟增大的一些建议:

  • 使用支持多参数的命令。

    • 如果瞬时发送大量指令到Redis,后面的指令就要等待前面的指令执行完成后都会被处理
    • 对于同样的需求,如向list表头插入1000个元素,可以使用循环lset1000个元素,也可以完全不要循环,使用lpush1000这一条指令
    • 下表是使用多参数指令的对应:

    在这里插入图片描述在这里插入图片描述

  • 使用pipeline命令。

    • 使用pipeline可以避免逐条发送指令,而是一次发送多条指令
    • 这样可以把多次的网络传输延迟缩减到1次
    • 网络传输时延显著大于实例指令执行时间时,这种方式会得到很好的效果
  • 避免在大数据集上使用慢指令。

    • 如果Redis处理的指令数量在减少,而延迟在增加,那么很可能执行了慢指令
    • 慢指令,意味着指令执行时长随着处理的数据集的增大显著上升
    • 大数据集上避免使用它们可以提高Redis性能
    • 下表是慢指令及其解决方式:

    在这里插入图片描述
    在这里插入图片描述

延迟

延迟指标指的是Redis服务响应的平均时延,单位为ms。

使用下面的指令可以得到结果:

% redis-cli --latency -h 127.0.0.1 -p 6379
min: 0, max: 5, avg: 0.16 (31260 samples)

在1GBits/s的网络中,典型的时延是200us。

如果测试的结果明显偏大,就需要具体定位一下原因了。

可以尝试以下方法:

  • 使用slowlog输出慢指令。

    • Redis默认会记录执行时间超过10ms的指令(这个值可在配置文件中修改)
    • 注意,这个时间仅指指令的执行时间,不包括网络延迟
    • 如果一般指令的执行时间是0.2ms,那么10ms的延迟已经是它的50倍
    • 使用slowlog get可查看最近的10条耗时超过10ms的指令,第3个字段就是耗时时长,单位us

    在这里插入图片描述

  • 监控连接数量。

    • Redis是单线程执行指令的,如果连接的客户端过多,会导致它们共享一个服务,这样每个客户端都要排队等候
    • 由于应用上的bug,可能会有一些连接没有及时释放,导致连接越来越多
    • 使用info clients查看,connected_clients便是
    • 这个值默认是10000,但是当连接数量超过5000时,如果有客户端发送大量指令,就会使Redis变得比较慢了
  • 限制最大连接数量。

    • 通过配置文件设置maxclients为想要的数值即可
    • 一般可设置为预计连接数的1.1倍到1.5倍
    • 一旦连接数量超过该值,新的连接会被拒绝,并接收到max number of clients reached错误
    • 这便于开发者发现问题
bigkey

如果通过查看慢日志,发现并不是复杂度高的指令导致的,而是set/del等简单指令导致的,那很可能是操作了bigkey。

Redis 在写入数据时,需要为新的数据分配内存,相对应的,当从 Redis 中删除数据时,它会释放对应的内存空间。

如果一个 key 写入的 value 非常大,那么 Redis 在分配内存时就会比较耗时。同样的,当删除这个 key 时,释放内存也会比较耗时,这种类型的 key 我们一般称之为 bigkey。

此时,你需要检查你的业务代码,是否存在写入 bigkey 的情况。你需要评估写入一个 key 的数据大小,尽量避免一个 key 存入过大的数据。

扫描bigkeys的方法:redis-cli -h 127.0.0.1 -p 6379 --bigkeys -i 0.01

一般string长度大于10K,list长度大于10240认为是bigkeys。

从输出结果我们可以很清晰地看到,每种数据类型所占用的最大内存 / 拥有最多元素的 key 是哪一个,以及每种数据类型在整个实例中的占比和平均大小 / 元素数量。

其实,使用这个命令的原理,就是 Redis 在内部执行了 SCAN 命令,遍历整个实例中所有的 key,然后针对 key 的类型,分别执行 STRLEN、LLEN、HLEN、SCARD、ZCARD 命令,来获取 String 类型的长度、容器类型(List、Hash、Set、ZSet)的元素个数。

执行这个命令时要注意:

  • 对线上实例进行 bigkey 扫描时,Redis 的 OPS 会突增,为了降低扫描过程中对 Redis 的影响,最好控制一下扫描的频率,指定 -i 参数即可,它表示扫描过程中每次扫描后休息的时间间隔,单位是秒
  • 扫描结果中,对于容器类型(List、Hash、Set、ZSet)的 key,只能扫描出元素最多的 key。但一个 key 的元素多,不一定表示占用内存也多,你还需要根据业务情况,进一步评估内存占用情况

优化方向:

  • 业务应用尽量避免写入 bigkey
  • 如果你使用的 Redis 是 4.0 以上版本,用 UNLINK 命令替代 DEL,此命令可以把释放 key 内存的操作,放到后台线程中去执行,从而降低对 Redis 的影响
  • 如果你使用的 Redis 是 6.0 以上版本,可以开启 lazy-free 机制(lazyfree-lazy-user-del = yes),在执行 DEL 命令时,释放内存也会放到后台线程中执行
碎片率

mem_fragmentation_ratio可通过info memory查看。

mem_fragmentation_ratio = used_memory_rss / used_memory

其中,used_memory_rss是操作系统分配给Redis的内存,而used_memory是Redis使用的内存。

RSS(Resident Set Size),指操作系统分配给Redis的物理内存大小。除了用户定义数据和Redis内部数据占用,还包含了内存碎片。

内存碎片是由操作系统的低效内存分配/释放引起的。

那么如何使用mem_fragmentation_ratio分析它对Redis性能的影响呢?

mem_fragmentation_ratio应该只比1大一点,这意味着内存碎片较小且不会发生内存交换。

如果这个值达到了1.5,Redis实际使用了它所需要的1.5倍内存,内存碎片就很严重了。

如果这个值小于1,则表示Redis内存使用超过物理内存,发生了内存页面交换,这会导致严重的性能问题。

如果mem_fragmentation_ratio的值不是在1-1.5之间,可以考虑使用下面的方法来定位和解决:

  • 重启Redis实例。

    • 如果mem_fragmentation_ratio超过了1.5,重启后操作系统会回收内存碎片
    • 如果used_memory_peak和used_memory_rss大致相等,都远大于used_memory,那么很可能内存碎片已经产生
    • 要重启redis,记得使用shutdown save保存数据
    • Redis4.0以上版本支持自动碎片整理的功能,可以通过配置开启碎片自动整理(activedefrag yes)。注意:开启内存碎片整理,它也有可能会导致 Redis 性能下降
    • Redis 的碎片整理工作是也在主线程中执行的,当其进行碎片整理时,必然会消耗 CPU 资源,产生更多的耗时,从而影响到客户端的请求
    • 需要开启这个功能时,最好提前测试评估它对 Redis 的影响
  • 限制内存交换

    • 如果mem_fragmentation_ratio小于1,很可能已经发生内存交换
  • 调换内存分配器

    • Redis支持多种内存分配器(glibc, jemalloc, tcmalloc等)
    • 在清楚地理解了它们的区别之后,重新编程Redis可以指定内存分配器
    • 只有在确认这会给你带来好处后再做
数据清除

evicted_keys指标表示因为达到了最大内存使用上限maxmemory导致的数据被清除的数量。

只有设置了maxmemory,才会导致evicted_keys有值。

一旦到达了Redis内存使用上限,可以使用volatile-lru/volatile-lfu/volatile-random/volatile-ttl等策略来清除数据。

如果evicted_keys的值经常大于0,就要注意这是否导致了性能下降,因为清除数据也会占用Redis实例的性能。

所以,减少evicted_keys发生的概率,就能保证Redis的性能不受该特性的影响。

下面是一些方法:

  • 增加最大可用内存限制。

    • 在使用AOF持久化时,可以把内存限制设定为系统可用内存的95%
  • Redis实例切片。

    • 可以把数据分割,分别存储到不同的Redis实例
    • 这样可以利用多个实例的资源,甚至多台服务器的资源
    • 当数据集确实太大,并且maxmemory设置后依然存在问题时,这种方式可以尝试
    • 分割的方法有多种:
      • hash分割:对key作hash映射到不同的组,每个组对应一个Redis实例
      • 客户端分割:由Redis客户端决定指定的key操作的实例
      • 代理分割:所有客户端请求发送到代理,由代理根据策略写入相应的实例
集中过期

如果平时在操作 Redis 时,并没有延迟很大的情况发生,但在某个时间点突然出现一波延时,其现象表现为:变慢的时间点很有规律,例如某个整点,或者每间隔多久就会发生一波延迟。

这种情况可能是业务代码中是否存在设置大量 key 集中过期的情况。

如果有大量的 key 在某个固定时间点集中过期,在这个时间点访问 Redis 时,就有可能导致延时变大。

Redis 的过期数据采用被动过期 + 主动过期两种策略:

  • 被动过期:只有当访问某个 key 时,才判断这个 key 是否已过期,如果已过期,则从实例中删除
  • 主动过期:Redis 内部维护了一个定时任务,默认每隔 100 毫秒(1秒10次)就会从全局的过期哈希表中随机取出 20 个 key,然后删除其中过期的 key,如果过期 key 的比例超过了 25%,则继续重复此过程,直到过期 key 的比例下降到 25% 以下,或者这次任务的执行耗时超过了 25 毫秒,才会退出循环

注意,这个主动过期 key 的定时任务,是在 Redis 主线程中执行的。

也就是说如果在执行主动过期的过程中,出现了需要大量删除过期 key 的情况,那么此时应用程序在访问 Redis 时,必须要等待这个过期任务执行结束,Redis 才可以服务这个客户端请求。

如果此时需要过期删除的是一个 bigkey,那么这个耗时会更久。而且,这个操作延迟的命令并不会记录在慢日志中。

因为慢日志中只记录一个命令真正操作内存数据的耗时,而 Redis 主动删除过期 key 的逻辑,是在命令真正执行之前执行的。

所以,此时你会看到,慢日志中没有操作耗时的命令,但我们的应用程序却感知到了延迟变大,其实时间都花费在了删除过期 key 上,这种情况我们需要尤为注意。

排查:

  • 业务代码中是否存在集中过期 key 的逻辑,如 expireat / pexpireat 命令
  • 集中过期 key 增加一个随机过期时间(如redis.expireat(key, expire_time + random(300))),把集中过期的时间打散,降低 Redis 清理过期 key 的压力
  • 如果你使用的 Redis 是 4.0 以上版本,可以开启 lazy-free 机制(lazyfree-lazy-expire yes),当删除过期 key 时,把释放内存的操作放到后台线程中执行,避免阻塞主线程
fork耗时

为了保证 Redis 数据的安全性,我们可能会开启后台定时 RDB 和 AOF rewrite 功能。

但如果你发现,操作 Redis 延迟变大,都发生在 Redis 后台 RDB 和 AOF rewrite 期间,那你就需要排查,在这期间有可能导致变慢的情况。

当 Redis 开启了后台 RDB 和 AOF rewrite 后,在执行时,它们都需要主进程创建出一个子进程进行数据的持久化。

主进程创建子进程,会调用操作系统提供的 fork 函数。

而 fork 在执行过程中,主进程需要拷贝自己的内存页表给子进程,如果这个实例很大,那么这个拷贝的过程也会比较耗时。

而且这个 fork 过程会消耗大量的 CPU 资源,在完成 fork 之前,整个 Redis 实例会被阻塞住,无法处理任何客户端请求。

如果此时你的 CPU 资源本来就很紧张,那么 fork 的耗时会更长,甚至达到秒级,这会严重影响 Redis 的性能。

那如何确认确实是因为 fork 耗时导致的 Redis 延迟变大呢?

你可以在 Redis 上执行 INFO stats 命令,查看 latest_fork_usec 项,单位微秒。

这个时间就是主进程在 fork 子进程期间,整个实例阻塞无法处理客户端请求的时间。

如果你发现这个耗时很久,就要警惕起来了,这意味在这期间,你的整个 Redis 实例都处于不可用的状态。

除了数据持久化会生成 RDB 之外,当主从节点第一次建立数据同步时,主节点也创建子进程生成 RDB,然后发给从节点进行一次全量同步,所以,这个过程也会对 Redis 产生性能影响。

优化方案:

  • 控制 Redis 实例的内存:尽量在 10G 以下,执行 fork 的耗时与实例大小有关,实例越大,耗时越久
  • 合理配置数据持久化策略:在 slave 节点执行 RDB 备份,推荐在低峰期执行,而对于丢失数据不敏感的业务(例如把 Redis 当做纯缓存使用),可以关闭 AOF 和 AOF rewrite
  • Redis 实例不要部署在虚拟机上:fork 的耗时也与系统也有关,虚拟机比物理机耗时更久
  • 降低主从库全量同步的概率:适当调大 repl-backlog-size 参数,避免主从全量同步
AOF

如果你的 AOF 配置不合理,还是有可能会导致性能问题。

当 Redis 开启 AOF 后,其工作原理如下:

  • Redis 执行写命令后,把这个命令写入到 AOF 文件内存中(write 系统调用)
  • Redis 根据配置的 AOF 刷盘策略,把 AOF 内存数据刷到磁盘上(fsync 系统调用)

为了保证 AOF 文件数据的安全性,Redis 提供了 3 种刷盘机制:

  • appendfsync always:主线程每次执行写操作后立即刷盘,此方案会占用比较大的磁盘 IO 资源,但数据安全性最高
  • appendfsync no:主线程每次写操作只写内存就返回,内存数据什么时候刷到磁盘,交由操作系统决定,此方案对性能影响最小,但数据安全性也最低,Redis 宕机时丢失的数据取决于操作系统刷盘时机
  • appendfsync everysec:主线程每次写操作只写内存就返回,然后由后台线程每隔 1 秒执行一次刷盘操作(触发fsync系统调用),此方案对性能影响相对较小,但当 Redis 宕机时会丢失 1 秒的数据

如果你的 Redis 只用作纯缓存,对于数据丢失不敏感,采用配置 appendfsync no 即可。

大部分情况下会采用第三种方式。

这个方案优势在于,Redis 主线程写完内存后就返回,具体的刷盘操作是放到后台线程中执行的,后台线程每隔 1 秒把内存中的数据刷到磁盘中。

这种方案既兼顾了性能,又尽可能地保证了数据安全,但这种方案还是存在导致 Redis 延迟变大的情况发生,甚至会阻塞整个 Redis。

为什么?我把 AOF 最耗时的刷盘操作,放到后台线程中也会影响到 Redis 主线程?

试想这样一种情况:当 Redis 后台线程在执行 AOF 文件刷盘时,如果此时磁盘的 IO 负载很高,那这个后台线程在执行刷盘操作(fsync系统调用)时就会被阻塞住。

此时的主线程依旧会接收写请求,紧接着,主线程又需要把数据写到文件内存中(write 系统调用),但此时的后台子线程由于磁盘负载过高,导致 fsync 发生阻塞,迟迟不能返回,那主线程在执行 write 系统调用时,也会被阻塞住,直到后台线程 fsync 执行完成后,主线程执行 write 才能成功返回。

所以,尽管你的 AOF 配置为 appendfsync everysec,也不能掉以轻心,要警惕磁盘压力过大导致的 Redis 有性能问题。

排查:

  • 子进程正在执行 AOF rewrite,这个过程会占用大量的磁盘 IO 资源
  • 有其他应用程序在执行大量的写文件操作,也会占用磁盘 IO 资源

第一种情况说白了就是,Redis 的 AOF 后台子线程刷盘操作,撞上了子进程 AOF rewrite!

Redis 提供了一个配置项,当子进程在 AOF rewrite 期间,可以让后台子线程不执行刷盘(不触发 fsync 系统调用)操作。

这相当于在 AOF rewrite 期间,临时把 appendfsync 设置为了 none,配置如下:no-appendfsync-on-rewrite yes

当然,开启这个配置项,在 AOF rewrite 期间,如果实例发生宕机,那么此时会丢失更多的数据,性能和数据安全性,你需要权衡后进行选择。

如果占用磁盘资源的是其他应用程序,那就比较简单了,你需要定位到是哪个应用程序在大量写磁盘,然后把这个应用程序迁移到其他机器上执行就好了,避免对 Redis 产生影响。

当然,如果你对 Redis 的性能和数据安全都有很高的要求,那么我建议从硬件层面来优化,更换为 SSD 磁盘,提高磁盘的 IO 能力,保证 AOF 期间有充足的磁盘资源可以使用。

绑定CPU

很多时候,我们在部署服务时,为了提高服务性能,降低应用程序在多个 CPU 核心之间的上下文切换带来的性能损耗,通常采用的方案是进程绑定 CPU 的方式提高性能。

但在部署 Redis 时,如果你需要绑定 CPU 来提高其性能,需要慎重。

为什么?

因为 Redis 在绑定 CPU 时,是有很多考究的,如果你不了解 Redis 的运行原理,随意绑定 CPU 不仅不会提高性能,甚至有可能会带来相反的效果。

我们都知道,一般现代的服务器会有多个 CPU,而每个 CPU 又包含多个物理核心,每个物理核心又分为多个逻辑核心,每个物理核下的逻辑核共用 L1/L2 Cache。

而 Redis Server 除了主线程服务客户端请求之外,还会创建子进程、子线程。

其中子进程用于数据持久化,而子线程用于执行一些比较耗时操作,例如异步释放 fd、异步 AOF 刷盘、异步 lazy-free 等等。

如果你把 Redis 进程只绑定了一个 CPU 逻辑核心上,那么当 Redis 在进行数据持久化时,fork 出的子进程会继承父进程的 CPU 使用偏好。

而此时的子进程会消耗大量的 CPU 资源进行数据持久化(把实例数据全部扫描出来需要耗费CPU),这就会导致子进程会与主进程发生 CPU 争抢,进而影响到主进程服务客户端请求,访问延迟变大。

这就是 Redis 绑定 CPU 带来的性能问题。

优化:

  • 不要让 Redis 进程只绑定在一个 CPU 逻辑核上,而是绑定在多个逻辑核心上,而且,绑定的多个逻辑核心最好是同一个物理核心,这样它们还可以共用 L1/L2 Cache。
    • 只能在一定程度上缓解主线程、子进程、后台线程在 CPU 资源上的竞争
  • 让主线程、子进程、后台线程,分别绑定在固定的 CPU 核心上,不让它们来回切换

对于第二种方式,Redis 在 6.0 版本已经推出了这个功能,我们可以通过以下配置,对主线程、后台线程、后台 RDB 进程、AOF rewrite 进程,绑定固定的 CPU 逻辑核心:

# It is possible to pin different threads and processes of Redis to specific
# CPUs in your system, in order to maximize the performances of the server.
# This is useful both in order to pin different Redis threads in different
# CPUs, but also in order to make sure that multiple Redis instances running
# in the same host will be pinned to different CPUs.
#
# Normally you can do this using the "taskset" command, however it is also
# possible to this via Redis configuration directly, both in Linux and FreeBSD.
#
# You can pin the server/IO threads, bio threads, aof rewrite child process, and
# the bgsave child process. The syntax to specify the cpu list is the same as
# the taskset command:
#
# Set redis server/io threads to cpu affinity 0,2,4,6:
# server_cpulist 0-7:2
#
# Set bio threads to cpu affinity 1,3:
# bio_cpulist 1,3
#
# Set aof rewrite child process to cpu affinity 8,9,10,11:
# aof_rewrite_cpulist 8-11
#
# Set bgsave child process to cpu affinity 1,10,11
# bgsave_cpulist 1,10-11

一般来说,Redis 的性能已经足够优秀,除非你对 Redis 的性能有更加严苛的要求,否则不建议你绑定 CPU。

从上面的分析你也能看出,绑定 CPU 需要你对计算机体系结构有非常清晰的了解,否则谨慎操作。

小结

从开发者角度来说,使用Redis就是要发挥出它应有的性能。

而了解这些可能影响性能的指标是很有好处的,在设计、测试和问题排查中会很有帮助。

参考资料

understanding the top 5 redis performance metrics
Redis 性能问题!从此调优不在话下

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐