主要影响redis性能的三个要素如下:redis自身操作特性、操作系统、文件系统。

Redis样例 redissom_redis

redis自身操作特性

1. 慢指令查询

         比如当Value 类型为 Set 时,SORT、SUNION/SMEMBERS 操作复杂度分别为 O(N+M*log(M)) 和 O(N)。复杂度增加了很多。

处理方式:用其他高效命令代替。比如说,如果你需要返回一个 SET 中的所有成员时,不要使用SMEMBERS 命令,而是要使用 SSCAN 多次迭代返回,避免一次返回大量数据,造成线程阻塞。当你需要执行排序、交集、并集操作时,可以在客户端完成,而不要用 SORT、SUNION、SINTER 这些命令,以免拖慢 Redis 实例。

 

2. 过期 key 操作

Redis 键值对的 key 可以设置过期时间。默认情况下,Redis 每 100 毫秒会删除一些过期key,具体的算法如下:

  • 采样 ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 个数的 key,并将其中过期的key 全部删除;
  • 如果超过 25% 的 key 过期了,则重复删除的过程,直到过期 key 的比例降至 25% 以下。

ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP默认是 20,那么,一秒内基本有 200 个过期 key 会被删除。这一策略对清除过期 key、释放内存空间很有帮助。如果每秒钟删除 200 个过期 key,并不会对 Redis 造成太大影响。

但是如果频繁使用带有相同时间参数的 EXPIREAT 命令设置过期 key,那么在同一时间就会有大量的key过期,删除的操作会影响redis(在redis4.0之后redis用异步的线程机制来减少影响)。

 

文件系统:AOF 模式

调整写回策略

Redis样例 redissom_数据_02

 

操作系统:swap

内存 swap 是操作系统里将内存数据在内存和磁盘间来回换入和换出的机制,涉及到磁盘的读写。

正常情况下,Redis 的操作是直接通过访问内存就能完成,一旦 swap 被触发了,Redis 的请求操作需要等到磁盘数据读写完成才行。

触发 swap 的原因主要是物理机器内存不足,对于 Redis 而言,有两种常见的情况:

  1. Redis 实例自身使用了大量的内存,导致物理机器的可用内存不足;
  2. 和 Redis 实例在同一台机器上运行的其他进程,在进行大量的文件读写操作。文件读写本身会占用系统内存,这会导致分配给 Redis 实例的内存量变少,进而触发 Redis 发生swap。

方案:增加机器的内存或者使用 Redis 集群。

 

操作系统:内存大页

Linux 内核从 2.6.38 开始支持内存大页机制,该机制支持 2MB 大小的内存页分配,而常规的内存页分配是按 4KB 的粒度来执行的。

虽然内存大页可以给redis带来内存分配方面的受益,但是另一方面,Redis 为了提供数据可靠性保证,需要将数据做持久化保存。客户端的写请求可能会修改正在进行持久化的数据。在这一过程中,Redis 就会采用写时复制机制,也就是说,一旦有数据要被修改,Redis 并不会直接修改内存中的数据,而是将这些数据拷贝一份,然后再进行修改。如果用的是内存大页,那么性能肯定会受影响。