性能测试性能优化中的缓存中间件优化

67 阅读4分钟

在高并发系统中,为了缓解数据库的查询压力,对某些热点数据和核心业务数据添加缓存层进行访问,高并发系统常使用Redis作为缓存层。在实际应用中,不合理地使用Redis会带来一些性能问题,起不到预期效果。

以下是Redis优化的常用手段。

一、避免big key设计

Redis对同一种数据类型会使用不同的内部编码进行存储,比如字符串的内部编码就有int(整数编码)、raw(优化内存分配的字符串编码)、embstr(动态字符串编码)3种,这是因为Redis的作者想通过不同编码实现效率和空间的平衡,然而数据量越大使用的内部编码就越复杂,而越复杂的内部编码存储的性能就越低。

这还只是写入时的速度,当键值对内容较大时,还会带来另外几个问题,具体如下。

内容越大需要的持久化时间就越长,需要挂起的时间越长,Redis的性能就会越低:

内容越大在网络上传输的内容就越多,需要的时间就越长,整体的运行速度就越低。

内容越大占用的内存就越多,就会更频繁地触发内存淘汰机制,从而给Redis带来更大的运行负担。

二、使用lazyfree特性

lazy free意为惰性删除或延迟删除,意思是在删除的时候提供异步延时释放键值的功能,把键值释放操作放在单独的B10(Background 10)子线程中处理,以减少删除操作对Redis主线程的阻塞,可以有效地避免删除big key带来的性能和可用性问题。

lazy free有4种设置,含义如下。

lazyfree-lazy-eviction:表示当Redis运行内存超过最大内存限制(通过maxmemory参数设置)时,是否开启lazy free机制将其删除。

lazyfree-lazy-expire:表示当键值过期之后是否开启lazy free机制将其删除。

lazyfree-lazy-server-del:有些指令在处理已存在的键时,会带有一个隐式的del键的操作。比如rename命令,当目标键已存在,Redis会先删除目标键,如果这些目标键是一个big key,就会造成阻塞删除的问题,此配置表示在这种场景中是否开启lazy free机制删除。

slave-lazy-flush:针对从节点进行全量数据同步,从节点在加载主节点的RDB文件前,会运行flushal来清理自己的数据,它表示此时是否开启lazy free机制删除。

三、设置键值的过期时间

应根据实际的业务情况对键值设置合理的过期时间,Redis会帮你自动清除过期的键值对,以节约对内存的占用,避免键值过多堆积以及频繁触发内存淘汰策略。

尽量避免使用复杂度高的命令。

开启slowlog监控耗时命令。

使用Pipeline批量操作数据。

避免大量数据同时过期。

客户端使用连接池,减少非必要调用。

合理设置Redis内存,选择合适的内存淘汰策略,禁用swap。

Redis目前提供了8种内存淘汰策略,其中两种基于LFU算法的聚略是在4.0版本之后增加的。

noeviction:不淘汰任何数据,当内存不足时,新增操作会报错,Redis默认内存淘汰策略。

allkeys-ru:淘汰整个键值中最久未使用的键值。

allkeys-random:随机淘汰任意键值。

volatile-ru:淘汰所有设置了过期时间的键值中最久未使用的键值。

volatile-random:随机淘汰设置了过期时间的任意键值。

volatile-ttl:优先淘汰更早过期的键值。

在Redis 4.0中新增的两种淘汰策略如下。

volatile-lfu:淘汰所有设置了过期时间的键值中使用最少的键值。volatile-xxx表示从设置了过期键的键值中淘汰数据。

alkeys-fu:淘汰整个键值中使用最少的键值。alkeys-xxx表示从所有的键值中淘汰数据。