1. Redis删除策略的概述
Redis是一种非关系型数据库,以内存为中心,支持多种数据类型,目前已被广泛应用于许多高性能、高可用性的场景中。由于Redis的数据都存储在内存中,因此内存的容量和使用效率对Redis系统的性能和可靠性都有着至关重要的影响。
Redis采用了一种特殊的处理方式——写时复制—来实现多个进程间的数据共享。为了维护内存中的数据,Redis还需要一套逐出算法来实现自动删除过期的数据。目前Redis支持以下五种删除策略:
noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,这个时候可以选择不做任何操作,也可以设置成阻塞写入或者先删除旧的键值对以腾出空间后再写入。
allkeys-lru:在所有key中,最近最少使用的被优先移除。
volatile-lru:在设置了过期时间的key中,最近最少使用的被优先移除。
allkeys-random:从所有的key中随机移除。
volatile-random:从设置了过期时间的key中随机移除。
2. Redis的逐出策略
Redis采用写时复制的机制来保证复杂的数据结构的一致性,新增数据会先复制一份到新的内存块,修改数据会先复制一份成为副本,缓存的过期时间也是先以副本的形式保存在内存中的。Redis内存中的真实数据和过期时间是分离的,对内存的修改也是以副本为主,所以当新旧副本都存在时,会选择旧的数据删除,这样可以避免停止读写操作时对旧数据的丢失。所以说Redis的逐出策略是删除“旧版本”的副本。
2.1 LRU逐出策略
“LRU”(Least Recently Used,最近最少使用)是指在某个时间窗口内,最近最少被使用的数据会被最先删除。Redis采用LRU算法实现了allkeys-lru和volatile-lru两种删除策略。在allkeys-lru策略中,Redis会从所有的数据集中选择最近最少使用的数据进行删除。在volatile-lru策略中,Redis会从设置了过期时间的数据集中选择最近最少使用的数据进行删除。
2.2 Random逐出策略
Random策略是指从当前数据集中随机选择一个数据删除。Redis采用了allkeys-random和volatile-random两种策略实现这种逐出方式。在allkeys-random策略中,将从所有数据集中随机选择一个数据进行删除。而在volatile-random策略中,Redis将从设置了过期时间的数据集中随机选择一个数据进行删除。
3. Redis删除策略和逐出策略的选择和应用
选择适合自己业务场景的删除策略较为重要,并且也是Redis性能和安全的保障。对于进程内数据,如缓存,由于没有落地的需求,应当尽可能地使用allkeys-lru或volatile-lru策略,尽可能地利用内存空间。
而对于需要落地到磁盘的持久化数据来讲,数据量通常相对于进程内的内存数据较大,同时磁盘的读写速度又远低于内存速度。因此在这种场景下,我们可以考虑先牺牲一部分内存空间来进行数据持久化操作。而对于内存中的缓存数据来讲,我们可以使用allkeys-random或volatile-random策略,同时合理地设置过期时间,这样可以节约内存资源,避免浪费。
另外,在某些应用场景下,我们并不关心数据被逐出了,因此也可以选择noeviction策略。这种策略的优势在于,将数据的存在性判断留给用户进行处理,而缺点在于如果不及时探测并针对性的清理,数据堆积可能会导致Redis服务器的崩溃。
总结
Redis作为一种高性能的、内存型的、非关系型的数据库,逐出策略和删除策略是其内部实现的两个核心机制。合理地选择和应用删除和逐出策略能够优化Redis的性能,并且对于一些产品来说,还可以提高安全性和可靠性。建议不同产品在使用Redis时慎重考虑其使用场景和生成策略,强化防护能力。