Redis 在淘汰数据时,第一次随机选出 N 个数据放到候选集合,将 lru 字段值最小的数据淘汰。当再次需要淘汰数据时,会重新挑选数据放入第一次创建的候选集合,不过有一个挑选标准:进入该集合的数据的 lru 的值必须小于候选集合中最小的 lru 值。
Redis 内存淘汰机制有以下几种策略:noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。(Redis 默认策略)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 Key。(推荐使用)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 Key。
对于过期键的清除,Redis 提供三种策略:被动删除、主动删除和缓存淘汰策略,后者在内存使用超过 maxmemory 限制时触发。主从同步是 Redis 实现读写分离的基础,包含全量复制与增量复制两种方式。全量复制在从节点首次启动时进行,增量复制则在断开重连后仅同步部分数据,以避免大量数据传输。
Redis的LRU实现是近似算法,通过随机选取样本进行淘汰,利用lru字段记录访问时间。尽管这可能牺牲准确性,但在Redis 0中,其表现接近真LRU。然而,LRU算法仅关注访问时间,可能会淘汰热门数据。LFU算法通过调整访问次数和时间衰减函数,同时考虑访问频率和时间。
RDB 是 Redis 默认的持久化方案。RDB通过快照的形式将数据保存到磁盘中。所谓快照,可以理解为在某一时间点将数据集的一个快照。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个dump.rdb文件。Redis 重启会通过加载dump.rdb文件恢复数据。
Redis内存数据库凭借其出色的性能,但数据安全问题不容忽视。为确保数据在服务故障后的持久性,Redis提供了两种主要的持久化策略:RDB(Redis Database)和AOF(Append Only File)。RDB通过定期创建数据库快照实现持久化,可通过redis.conf中的save配置设置条件,如达到一定数据变化次数或运行时间。
aof和rdb是Redis持久化的两种方式,它们各自有特点和应用场合。aof持久化方式通过记录每次操作的命令日志来生成持久化文件,这使得数据恢复时能够恢复到最后一次操作前的状态。文件格式为文本,易于理解和维护。但是,aof的写入效率较低,且在发生故障时需要从最后一次写入点恢复,导致数据丢失的风险相对较高。
Redis支持三种持久化策略:RDB、AOF和混合持久化。其中RDB通过快照的方式获得某一时间点的数据副本,便于数据备份与集群同步。其在Redis服务器重启时能快速恢复数据。AOF则通过记录命令日志的方式实时地存储修改操作,以保证数据完整性。在数据恢复时,优先使用AOF文件。
理解Redis的持久化机制,关键在于RDB和AOF两种方式的选择。首先,Redis作为内存数据库,内存中的数据若不进行持久化,一旦服务器故障,数据将丢失。因此,RDB和AOF被设计来将内存数据保存到磁盘,确保服务重启后数据恢复。
- **len**:记录字符串实际使用的字节数,等同于字符串长度。- **free**:记录未使用的字节数,用于动态调整内存空间。通过这些改进,SDS在获取字符串长度、空间预分配和惰性释放、存储二进制数据方面提供了显著优势: **快速获取长度**:利用len属性,复杂度降低至O(1)。
SDS在设计时充分考虑了Redis的性能和安全需求,通过采用更高效的数据结构和算法优化,实现了对C语言字符串的改进和增强。具体而言,SDS在存储字符串时采用了一种紧凑的结构,不仅解决了C语言字符串的不安全性和查询效率低下的问题,还提供了更好的内存管理和性能表现。
Redis中的String是最基本的key-value结构,其中value不仅仅是字符串,还可以是整数、浮点数,最大容纳数据长度为512MB。内部实现包括数据结构和内部编码。数据结构使用int + SDS(简单动态字符串),内部编码有int、raw和embstr三种方式。
string作为redis中常用对象之一,普遍用于用户信息缓存等场景。当string对象中encoding编码为embstr或raw时都是采用sds作为其底层实现 1 SDS结构 源码文件位于redis安装目录src下的sds.h,sds声明了五种头部类型,分别为sdshdrsdshdrsdshdr1sdshdr3sdshdr64。
Redis数据类型包含String、List、Hash、Set和Zset。本文聚焦于String的底层数据结构。Redis对象作为每个对象的头部,包含了数据类型等信息,每种数据类型都必需携带。一个RedisObject占用16字节,用于存储数据类型和具体数据信息。String数据在Redis中通过SDS、int、embstr和raw四种形式存储。
1、Redis中的数据删除方式并非单一,包括DEL命令的同步删除和UNLINK命令的智能选择,以及根据对象类型和内存策略的异步删除。同步删除可能影响服务,而UNLINK则更智能。Redis还根据内存容量和驱逐策略进行Key的自动驱逐,其中noeviction策略可能导致写失败。
2、使用Lua脚本扫描并删除大量key。 脚本执行时,依据数据量动态调整删除频率,避免阻塞服务。Lua脚本的关键点包括: 使用scan命令高效获取数据。 利用UNLINK指令异步执行删除操作,减少系统阻塞。通过以上方法,我们成功实现了在不阻塞业务的情况下,高效清理Redis内存数据,优化了服务性能。
3、在清理旧的键值对时,使用`DEL`命令可以删除不再需要的键,但要注意谨慎操作,避免误删重要数据。如果需要定期进行清理,可以编写脚本或定时任务,自动化这个过程。通过这种转换和优化,Redis的内存管理将更加高效,有助于提高系统的整体性能和响应速度。
4、首先,关于到期缓存清除,Redis采取了惰性删除和定期删除的策略。惰性删除是当Redis试图从内存中获取数据,但未找到时,才会标记为过期并删除。定期删除则是在后台定期检查并移除过期的缓存条目,这样既避免了频繁的CPU操作,又确保了内存的实时更新。这种策略平衡了CPU资源的使用和内存空间的有效利用。
Redis的所有命令执行过程中不会被外部打断,这种特性使得大家常将Redis视为单线程程序。尽管实际上Redis使用了多线程技术,但在处理命令时,始终只有一个主线程在操作,因此,Redis可以被视作单线程架构,确保了其命令执行的原子性。
redis和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。
Redis查询中的List类型相关操作主要有以下几种: LPUSH 和 LPUSHX 这两个命令用于将一个或多个值推入列表的左边。其中,LPUSH命令可以接受一个key和一个值作为参数,而LPUSHX则仅使用一个已存在的key来操作。这两个命令都会将新元素添加到列表的头部。
Redis中值的类型不仅限于字符串,还支持如下抽象数据类型:字符串列表。无序不重复的字符串集合。有序不重复的字符串集合。键、值都为字符串的哈希表。值的类型决定了值本身支持的操作。Redis支持不同无序、有序的列表,无序、有序的集合间的交集、并集等高级服务器端原子操作。
Redis 的 list(列表)数据结构常用于异步消息队列。使用 rpush/lpush 操作入队列,使用 lpop 和 rpop 来出队列。客户端通过 pop 操作获取消息进行处理。处理完毕后,再次获取消息进行处理,如此循环。这就是作为队列消费者的客户端的生命周期。
在实现 Redis 缓存用户列表并支持分页展示时,主要依赖 Redis 的数据结构。首先,分页处理推荐使用 list 或 zset 结构。其中,list 结构简单直接,适用于无序且不需排序的场景;而 zset 结构则具备排序能力,适用于需要根据特定排序规则展示用户列表的情况。
实现思路 list链表键存储用户ID,用于分页查询,同时用于查询用户总数,key为personid。
把数据ID和排序打分存到Redis的skip list,即zset里;当查找数据时,先从Redis里的skip list取出对应的分页数据,得到ID列表。用multi get从redis上一次性把ID列表里的所有数据都取出来。如果有缺少某些ID的数据,再从数据库里查找,再一块返回给用户,并把查出来的数据按ID缓存到Redis里。