redis学习笔记
一、简单动态字符串
SDS定义
struct sdsstr{
//已保存的字符串长度
int len;
//数组还剩余的空间
int free;
//保存字符串的字节数组
char buf[];
}
获取字符串长度O(1)、杜绝缓冲区溢出、内存重新分配次数、存储二进制
二、链表
redis重构了自己的链表实现
typedef struct listNode{
//前置节点
struct listNode *prev;
//后置节点
struct listNode *next;
//节点的值
void *value;
}listNode;
三、字典
redis的字典使用哈希表作为底层实现,一个哈希表可以有多个哈希表节点,
每个哈希表节点就保存了字典中的一个键值对。
redis采用渐进式rehash操作进行扩展
四、跳跃表
五、整数集合
这里的编码方式只的是int16_t、int32_t、int64_t,
整数集合的每个元素都是contents数组的一个数组项,各个数组项在数组中按值从小到大有序排列,且不存在重复项。
如果新添加的元素比现有所有元素类型都长时,集合会先进行升级再添加新元素。
整数集合不支持降级操作。
六、压缩列表
压缩列表是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串时,redis就会使用压缩列表作为列表键的底层实现。
previous_entry_length记录前一个节点的长度,此处存在连锁更新问题,
压缩列表要恰好存在连续多个长度250-253字节之间的节点才会发生。
七、对象
八、数据库
过期键的删除策略:定时删除、惰性删除、定期删除
redis采用惰性删除和定期删除两种。
九、RDB持久化
有两个redis命令可以用于生产RDB文件,save和bgsave,
save命令会阻塞服务器进程,bgsave命令会派生出一个子进程处理。
RDB文件的载入是服务器启动时自动执行的。
文件保存的是数据库中键值对的状态。
十、AOF持久化
通过保存redis服务器执行的写命令来记录数据库状态。
AOF文件会针对一条数据产生多条记录,导致文件过于庞大,redis提供了文件重写功能,redis会创建一个新的AOF文件代替现有的AOF文件,新旧两个AOF记录的数据库状态相同,但新文件小很多。
文件重写不是通过分析现有AOF文件实现的,而是通过读取服务器当前的数据库状态来实现的。
十一、事件
redis服务器是一个事件驱动程序,服务器需要处理一下两类事件:
文件事件:redis服务器通过套接字与客户端(或其他redis服务器)进行连接,而文件事件就是服务器对套接字事件的抽象,
时间事件:redis服务器中的一些操作需要在特定的时间点执行,而时间事件就是服务器对这类定时操作的抽象。
十二、客户端
略
十三、服务器
略
十四、复制
redis的复制分为同步和命令传播两个操作
部分重同步的实现:主从服务器的复制偏移量、主服务器的复制缓冲区、服务器运行ID
复制偏移量:主从服务器都会维持一个复制偏移量。主服务器发送N字节数据,复制偏移量加N,从服务器接收到N字节数据,从服务器的复制偏移量加N。
复制缓冲区:主服务器维护的一个固定长度、先进先出的队列,默认大小1M。
服务器运行ID:redis服务器启动时自动生成40个十六进制字符组成的运行ID。
十五、sentinel
哨兵是redis高可用解决方案,由一个或多个sentinel实例组成的哨兵系统,可以监视任意多个主服务器以及主服务器下的从服务器,如果主服务器下线会自动选择主服务器下的某个从服务器充当主服务器,继续对外提供服务。
检测主观下线:sentinel每秒会发送ping给监控的实例,如果规定时间内没有有效返回,则认为服务器主观下线。通过down-after-millionseconds配置。
不同的sentinel配置的参数时间可能不同,导致有的sentinel认为主服务器主观下线,有的则不认为主观下线。
检查客观下线:当sentinel将一个主服务器判定为主观下线后,会向其他监视此主服务器的sentinel发送消息询问,看他们是否认为此主服务器处于下线状态,当sentinel从其他sentinel得到足够多的已下线判断,sentinel就会将从服务器判定为客观下线,并对主服务器执行故障转移操作。
十六、集群
redis集群是redis提供的分布式数据库方案,集群通过分片来进行数据共享,并提供复制和故障转移功能。
通过cluster meet发现其他节点,meet--->pong--->ping
之后A节点通过gossip协议传播给集群的其他节点。
十七、发布与订阅
redis的发布与订阅功能由publish、subscribe、psubscribe等命令组成。
服务器状态在pubsub_channels字典保存了所有频道的订阅关系:subscribe命令负责将客户端和被订阅的频道关联到这个字典里面,而unsubscribe命令则负责解除客户端和被退订频道之间的关联。
十八、事务
1、redis通过multi、exec、watch等命令来实现事务功能。事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且事务执行期间,服务器不会中断事务去执行其他客户端的命令请求。
multi
command 1
command 2
....
exec
2、watch命令的实现
watch命令是一个乐观锁,它可以在exec命令执行之前,监视任意数量的数据库键,并在exec命令执行时,检查被监视的键是否至少有一个已经被修改过了,如果是的话,服务器将拒绝执行事务,并向客户端返回代表事务执行直白的空恢复。
十九、Lua脚本
redis从2.6版本开始引入对Lua脚本的支持,通过在服务器中嵌入Lua环境,redis客户端可以使用Lua脚本,直接在服务器端源自地执行多个redis命令。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话