Quicklist 数据结构是 Redis 在 3.2 才引入的一个双向链表的数据结构,确实来说是一个 Ziplist 的双向链表 。
Quicklist 的每一个数据节点是一个 Ziplist,Ziplist 本身就是一个紧凑列表 。
假使,Quicklist 包含了 5 个 Ziplist 的节点,每个 Ziplist 列表又包含了 5 个数据,那么在外部看来,这个 Quicklist 就包含了 25 个数据项 。
文章插图
Quicklist 的结构设计简单总结起来,是一个空间和时间的折中方案:
- 双向链表可以在两端进行 Push 和 Pop 操作,但是它在每一个节点除了保存自身的数据外,还要保存两个指针,增加额外的内存开销 。
- Ziplist 本身是一块连续的内存,存储和查询效率很高,但是,它不利于修改操作,每次数据变动时都会引发内存 Realloc,如果 Ziplist 长度很长时,一次 Realloc 会导致大批量数据拷贝 。
对象共享
Redis 在自己的对象系统中构建了一个引用计数方法,通过这个方法程序可以跟踪对象的引用计数信息,除了可以在适当的时候进行对象释放,还可以用来作为对象共享 。
举个例子,假使键 A 创建了一个整数值 100 的字符串作为值对象,这个时候键 B 也创建保存同样整数值 100 的字符串对象作为值对象 。
文章插图
那么在 Redis 的操作时:
- 讲数据库键的指针指向一个现有的值对象 。
- 讲被共享的值对象引用计数加一 。
Redis 是如何实现主从复制
文章插图
几个定义:
- runID:服务器运行的 ID 。
- Offset:主服务器的复制偏移量和从服务器复制的偏移量 。
- Replication backlog:主服务器的复制积压缓冲区 。
Psync 命令具有完整重同步和部分重同步两种模式:
- 完整同步用于处理初次复制情况:完整重同步的执行步骤和 Sync 命令执行步骤一致,都是通过让主服务器创建并发送 RDB 文件,以及向从服务器发送保存在缓冲区的写命令来进行同步 。
- 部分重同步是用于处理断线后重复制情况:当从服务器在断线后重新连接主服务器时,主服务可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态 。
文章插图
完整重同步:
- Slave 发送 Psync 给 Master,由于是第一次发送,不带上 runID 和 Offset 。
- Master 接收到请求,发送 Master 的 runID 和 Offset 给从节点 。
- Master 生成保存 RDB 文件 。
- Master 发送 RDB 文件给 Slave 。
- 在发送 RDB 这个操作的同时,写操作会复制到缓冲区 Replication Backlog Buffer 中,并从 Buffer 区发送到 Slave 。
- Slave 将 RDB 文件的数据装载,并更新自身数据 。
这些都是大量的开销,所以在 Redis 2.8 之后也实现了部分重同步的机制 。
文章插图
部分重同步:
- 网络发生错误,Master 和 Slave 失去连接 。
- Master 依然向 Buffer 缓冲区写入数据 。
- Slave 重新连接上 Master 。
- Slave 向 Master 发送自己目前的 runID 和 Offset 。
- Master 会判断 Slave 发送给自己的 Offset 是否存在 Buffer 队列中 。
- 如果存在,则发送 Continue 给 Slave;如果不存在,意味着可能错误了太多的数据,缓冲区已经被清空,这个时候就需要重新进行全量的复制 。
- 面试问Redis集群,被虐的不行了
- 光动能是西铁城好还是卡西欧好?我有话要说
- 咖啡入门常识及意式咖啡豆分享
- 前5个基于Redis的Java对象
- 一款免费的Redis桌面客户端:RediNav
- Redis 图形化工具
- 瞬间几千次的重复提交,我用Spring Boot+Redis扛住了
- Redis如何清除过期key? 一篇文章带你走近源码!
- Centos7 搭建LTMP环境PHP、Tengine、Mysql、Supervisord、Redis
- Redis内存分析工具--rdr安装与使用