Redis里put方法到底咋设计的,原理和实现细节随便聊聊
- 问答
- 2026-01-05 19:22:59
- 11
核心目标:把键值对稳稳当当地放进去
SET命令最基本、最简单的任务就是:你给我一个键(key)和一个值(value),我把它存到内存里,比如你执行 SET username "张三",Redis就要完成这几步:
- 查重与内存管理:Redis会先看看内存里是不是已经存在一个叫“username”的键了,如果存在,它需要先把旧值占用的内存清理掉,因为Redis是自己管理内存的,得精打细算,它会计算新值“张三”这个字符串需要占多大地方,并分配相应的内存。
- 编码与存储:你以为“张三”这个字符串就直接存进去了?没那么简单,Redis为了节省内存和提高效率,玩了很多小花招,也就是所谓的“编码优化”,如果一个字符串很短,它可能会用一种叫
embstr的方式存储,把键和值在内存里紧挨着放,这样找起来快,如果字符串很长,或者数字,Redis可能会把它转换成整数类型来存,这样占的空间更小,这个过程对用户是完全透明的,你感觉不到,但正是这些细节决定了Redis的性能。 - 更新索引:Redis的所有键值对都存储在一个巨大的全局哈希表里,你可以把这个哈希表想象成一个有很多房间(桶)的大楼,当你执行SET时,Redis会根据键“username”计算出一个哈希值,这个值决定了它应该去哪个“房间”,然后它就把这个键值对放进对应的房间里,如果那个房间已经有其他键了(哈希冲突),Redis会用链表把他们都串起来(后来新版本也会用跳表等更高效的结构)。
不只是简单存放:丰富的“开关”选项
如果SET只能干这么点事,那它就太普通了,它的强大之处在于提供了一堆可选参数,让你能精细控制存放行为,这就像是给简单的“放东西”这个动作加上了各种智能开关。
- 过期时间(EX/PX):这是缓存场景最常用的功能,你可以
SET key value EX 10,告诉Redis这个键值对只能活10秒,10秒后,它会被自动删除,这完美解决了缓存数据失效的问题,实现上,Redis会有专门的机制(比如定期删除和惰性删除)来清理这些过期的键。 - 条件设置(NX/XX):这实现了类似“锁”的功能。
NX:只有在这个键不存在的时候,我才设置它,这简直就是为分布式锁量身定做的,比如多个客户端同时想抢一个锁,用SET lock_key unique_value NX,只有一个客户端能成功,因为他最先创建了这个键。XX:正好相反,只有在这个键已经存在的时候,我才更新它的值,这在某些需要先检查状态的场景下有用。
- GET老值:有些版本的Redis的
SET命令还支持GET选项,意思是“设置我这个新值,但同时把旧值返回给我”,这在一个操作里完成了“读-改-写”,是原子性的,很实用。
背后的大家伙:全局哈希字典与多态

不管你用不用那些高级选项,你塞进去的每一个键值对,最终都落脚于一个叫全局哈希字典的数据结构里(来源:Redis设计与实现),这个字典是Redis所有数据的入口,速度极快,理论上接近O(1)的查找时间复杂度。
更有意思的是,这个字典的“值”并不是直接存储你的字符串或者列表,而是存储了一个指向一个叫redisObject结构的指针,这个redisObject可以说是Redis里所有数据类型的“包装盒”或者“元数据”,它里面记录了:
- 实际的数据类型:比如是字符串(string)、列表(list)、哈希(hash)等。
- 实际数据的编码方式:就是我们刚才提到的,比如字符串是
embstr还是raw,列表是压缩列表还是双向链表等。 - 其他管理信息:比如过期时间、引用计数等。
这种设计使得Redis的数据存储非常灵活,是一种“多态”的体现。SET命令在处理时,并不需要关心你存的具体是啥,它只管把键和这个“万能包装盒”存到哈希表里,当其他命令(如GET)来读取时,再根据redisObject里记录的类型和编码,用正确的方式把数据取出来。

持久化的考量:内存里的变动如何落地?
你SET了一个值,它只是在内存里生效了,但如果Redis服务器重启,内存数据就全丢了,put”这个动作还牵涉到持久化问题,Redis主要通过两种方式把内存的数据变动(包括SET)记下来:
- RDB(快照):隔一段时间,或者满足一定条件时,Redis会把整个内存数据集拍一张快照,保存成一个压缩的二进制文件(dump.rdb),你的SET操作可能要在下一次快照时才会被固化到磁盘上。
- AOF(追加日志):更常见的方式是,每执行一条写命令(比如SET),Redis就把它以协议文本的形式追加到一个日志文件(appendonly.aof)的末尾,这样即使服务器宕机,重启后重新执行一遍AOF文件里的所有命令,就能恢复数据,为了保证数据不丢失,还可以配置为每执行一条命令就强制刷一次磁盘(性能有代价),或者每秒刷一次(折中方案)。
一个简单的SET命令背后,可能还会触发AOF文件的写入操作,甚至可能引起后台的持久化进程工作。
总结一下
所以你看,Redis里这个看似简单的“put”(SET命令),其设计一点也不简单,它不仅仅是将数据扔进内存哈希表那么简单,而是一个集成了精细内存管理、多编码优化、条件逻辑控制、过期时间管理、并与持久化机制紧密协作的复杂操作,它的设计哲学是:给用户提供一个极其简单直观的接口,但在接口之下,通过精妙的数据结构和算法,实现高性能、高并发的数据存取,这也就是为什么Redis能成为一个如此受欢迎的内存数据库。
本文由雪和泽于2026-01-05发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/75122.html
