这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
- 避免缓慢的查询命令 慢速查询命令是指执行速度较慢的命令。Redis提供了很多命令,但并不是所有的命令都很慢,这与命令的复杂性有关。因此,了解Redis不同命令的复杂度是很有必要的。
例如,当Value类型为String时,GET/SET操作主要对Redis的哈希表索引进行操作。这个操作的复杂度基本是固定的,O(1)。但当Value type为Set时,SORT和SUNION/ members操作的复杂度分别为O(N+M*log(M))和O(N)。其中N是Set中的元素数量,M是SORT操作返回的元素数量。这会增加很多复杂性。Redis官方文档描述了每个命令的复杂性。如果需要了解命令的复杂程度,可以直接查询。
当发现Redis性能较慢时,可以通过Redis日志或时延监控工具查询慢速请求,并根据请求对应的具体命令和官方文档确认是否使用复杂度较高的慢速查询命令。
如果存在大量慢速查询命令,建议使用以下两种方式:
相反,应该使用其他有效的命令:例如,如果需要返回SET的所有成员,就不要使用members命令。相反,应该使用scan多次返回,以避免一次返回大量数据而阻塞线程。
当你需要做SORT、交集和联合时,在客户端上做,而不是使用SORT、SUNION、SINTER等,这会降低Redis实例的速度。
- 在生产环境下禁用keys命令 keys命令是最容易被忽略的慢查询命令,因为keys命令需要遍历存储的键和值对,因此操作延时很高,在生产环境中很可能造成Redis阻塞;因此,不建议在生产环境下使用keys命令。
3.密钥需要设置过期时间 Redis是一个内存数据库,所有的数据都在内存中,一旦内存占用过大,就会极大地影响性能,所以有必要对数据的过期时间设置一个时间限制,这样Redis就可以定期删除过期的数据。
- 不批量设置相同的密钥过期时间 默认情况下,Redis每100毫秒删除一些过期的密钥。算法如下: 对ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP密钥的数量进行采样,并删除所有过期密钥。
如果超过25%的密钥过期,则重复删除过程,直到过期密钥的百分比降到25%以下。
ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP是一个Redis参数。缺省值为20。在这种情况下,每秒将删除大约200个过期密钥。该策略有助于清除过期密钥,释放内存空间。如果你每秒删除200个过期密钥,也不会对Redis造成太大影响。
但是,如果该算法的第二部分被触发,Redis将继续删除以释放内存空间。注意,删除操作是阻塞的(在Redis 4.0之后,可以使用异步线程机制来减少阻塞效应)。因此,一旦触发该条件,Redis线程将继续删除,将无法正常服务于其他键值操作,导致其他键值操作进一步延迟,Redis将变慢。
频繁使用EXPIREAT和相同的time参数设置过期密钥将触发第二种算法,这将导致大量密钥在一秒内过期。
因此,在开发过程中禁止批量密钥过期是很重要的。
- 仔细选择数据结构 Redis使用五种数据结构:字符串、散列、列表、集和zset(排序集)。正如您所看到的,使用字符串可以在大多数情况下解决这个问题。然而,这并不一定是最好的选择。下面简要说明它们各自的应用场景:
string:单个缓存结果,不与其他KVS关联 hash:一个对象包含许多需要单独存储的属性。注意:在这种情况下不要使用字符串,因为字符串占用更多内存 list:一个Object包含大量的数据,这些数据可以重复和有序 set:一个对象包含大量的数据。不要求数据顺序,但不允许数据重复 zset: Object包含大量数据,数据本身包含一个权重值,可用于排序 Redis还提供了几种扩展类型,如下: HyperLogLog:适用于基数统计,如PV, UV统计,错误问题,不适合精确统计。 位图:适用于二进制状态的统计数据,例如签入,或者有时钟的,或者没有时钟的。
- 检查持久性策略 的符合