// 过期时间为指定毫秒时间戳(未来某个日期)
+```
+
+### 过期键删除策略
+**三种策略:定时删除、惰性删除、定期删除**
+定时删除:在设置过期时间的同时,同时设置一个定时器,让定时器在键过期时,立刻执行删除操作。对内存友好,但对 CPU 不友好(现阶段不易实现,消耗太大)。
+惰性删除:在取出键时才对键进行过期检查,对内存不友好,但对 CPU 友好,当过期键过多时,有可能会造成内存泄露类似的情况。
+定期删除:前两种方式的一种折中,难点在于确定时长和频率。
+
+**Redis 使用惰性删除和定期删除两种策略**
+
+**AOF、RDB 和 复制功能 对过期键的处理**
+1、生成 RDB 文件时不会包含过期键;
+2、载入 RDB 文件时,主服务器不会载入过期键,从服务器则会全部载入;
+3、AOF 文件写入,过期键未删除便不影响,当执行某个删除操作后,会向 AOF 追加删除命令;
+4、AOF 重写,只对未过期的键进行重写;
+5、复制模式下,从服务器的过期键删除动作由主服务器控制;主服务器删除一个键后会向所以的从服务器发送删除命令,从服务器只有接收到此命令才进行删除;
+
+**数据库通知**
+键空间通知:某个键执行了哪些命令
+键事件通知:某个命令被哪些键执行了
+
+
+## Redis 持久化
+因为 Redis 是内存数据库,它将自己的数据库状态存储在内存里面,所以如果不想办法将存储在内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,那么数据也会消失。
+
+### RDB(Redis DataBase) 持久化
+
+**RDB 文件的创建与载入**
+两个命令生成 RDB 文件
+1、SAVE:阻塞 Redis 服务器,直到 RDB 文件创建完成;
+2、BGSAVE:派出一个子进程创建 RDB 文件;
+Redis 服务器在启动时检测到 RDB 文件存在,就会自动载入 RDB 文件(阻塞状态),直到载入完成。
+(因为 AOF 文件的更新频率通常比 RDB 文件的更新频率高,所以如果开启了 AOF 功能,那么会优先使用 AOF 文件来还原)
+
+**自动间隔性保存**
+通过 save 选项设置多个保存条件,任意一个被满足,就会执行 BGSAVE。
+
+```C
+typedef struct redisServer{
+struct saveparam *saveparams; // 记录了保存条件的数组
+long long dirty; // 修改计数器
+time_t lastsave; // 上一次执行保存的时间
+}
+
+typedef struct saveparam{
+time_t seconds; // 秒数
+int changes; // 修改数
+}
+```
+
+**RDB 文件结构**
+五个部分:REDIS、db_version、databases、EOF、check_sum
+
+**分析 RDB 文件**
+
+### AOF(Append Only File) 持久化
+**AOF 持久化的实现**
+三个步骤
+命令追加(append):执行完一个命令之后,会以协议格式将命令追加到 aof_buf 末尾;
+文件写入:
+文件同步(sync)
+
+**AOF 文件的载入与数据还原**
+读,写,即可;
+
+**AOF 重写**
+因为该文件中会有很多冗余命令(如增了又删等等),因此,需要重写 AOF 文件,这样体积会小很多。重写其实只是重写读 数据库,并不会对 旧AOF 文件进行任何处理。当开始重写 AOF 文件时,此时会开辟一个缓存区,当有新命令到来时,会写入,最后重写完成时,再全部追加到新文件中。
+(疑问:新命令执行,如果是重写后的数据还好,如果是还未重写的数据,AOF 重写读一遍,缓存的又追加命令,那不是造成数据不一致了?)
+
+
+## 事件
+Redis 服务器是一个事件驱动程序,有一下两类事件
+文件事件(file event):套接字、I/O 多路复用程序、文件事件分派器、事件处理器
+时间事件(time event):
+**文件事件**
+文件事件是对套接字操作的抽象。
+1、文件事件处理器使用 I/O 多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
+2、当被监听的套接字准备好执行连接应答、读取、写入、关闭等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。
+
+**时间事件**
+主要分为两类:定时事件、周期性事件
+
+
+## 客户端
+服务端采用链表保存所有与服务器连接的客户端。
+1、客户端属性(通用属性):12 个
+2、客户端的创建与关闭:
+
+
+## 服务器
+1、命令请求的执行过程
+2、ServerCron 函数
+3、初始化服务器
+
+
+## 复制
+Redis 中用户可以通过执行 SLAVEOF 命令,让一个服务器去复制另一个服务器。
+旧版复制功能包括:同步、命令传播。
+同步:使用 SYNC 的命令进行同步,在执行 RDB 的持久化过程中,会将新到来的命令缓存,那么,是用什么机制,保证不会在 BGSAVE 命令中将新插入的键写入 RDB 文件中???
+命令传播:被客户端的命令修改后,向从服务器传播指令,以保证数据一致。
+缺点:在断线重连时,需要复制主服务器的所有数据,而是不是更新之后未接受到的数据,会导致效率低下。
+新版复制:将上面耗时的 SYNC 命令拆分为 PSYNC(里面的两种模式,完整重同步,部分重同步)
+部分重同步如何实现?
+1、偏移量:用于记录主从服务器的数据是否一致,还差多少
+2、复制积压缓冲区(默认为 1 M,可以根据需要调整):记录一部分命令到队列中,以备从服务器断线重连执行部分重同步,如果缓冲区中不存在从服务器偏移量之后的命令(offset + 1),那么就需要执行完整重同步。
+3、服务器运行 ID:主从服务器第一次连接时,主服务器发送的,当从服务器断线重连时,需要发送此 ID 确认是否是之前连接的主服务器,如果相同可以执行部分重同步,如果不同则要执行完全重同步。
+
+复制的实现
+1、设置主服务器的地址和端口
+2、建立套接字
+3、发送 PING 命令
+4、身份验证
+5、发送端口信息
+6、同步
+7、命令传播
+
+
+## Sentinel(哨兵)
+哨兵是干什么的?
+Sentinel 系统由多个哨兵实例构成,可以监视任意多个主服务器以及下属所有从服务器。当某个主服务器下线时,哨兵可以将它的某个从服务器升级为新的主服务器继续工作。
+(注意:1、其余从服务器与新的主服务器保持同步,2、如果下线的服务器上线了,则会被作为从服务器继续保持同步)
+
+什么是哨兵?
+哨兵本质上只是一个运行在特殊模式下的 Redis 服务器,所以启动哨兵的第一步就是初始化一个普通的 Redis 服务器。
+
+
+## 集群
+Redis 集群是 Redis 提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。
+节点:一个 Redis 集群通常由多个节点组成。
+槽指派: Redis 集群通过分片的方式来保存数据库中的键值对,整个数据库被分为 16384 个槽,
+
+
+## 发布与订阅
+由多个命令组成:PUBLISH、SUBSCRIBE、UNSBUSCRIBE、PSUBSCRIBE、UNPSUBSCRIBE
+PUBLISH:发布一条消息
+SUBSCRIBE:订阅一个频道
+PSUBSCRIBE:订阅一个模式(可以匹配多个频道)
+
+频道的订阅与退订
+* Redis 将所有频道的订阅关系都保存在服务器状态的 pubsub_channels 字典里面,这个字典的键是某个被订阅的频道,值是一个链表,链表记录了所有订阅此频道的客户端。
+* 订阅:当一个客户端订阅某个频道时,如果字典存在则直接插入到链表末尾,否则新建一个键值对。
+* 退订:与上面相反如果删除后链表为空,则删除该键值对。
+
+模式的订阅与退订
+* Redis 将所有模式的订阅关系都保存在服务器状态的 pubsub_patterns 链表里面,链表中的每个节点都包含一个 pubsub_Pattern 结构,包括具体的订阅模式和订阅了该模式的客户端。
+* 订阅模式:新建一个 pattern 结构,添加到 patterns 链表的末尾。
+* 退订模式:删除链表节点
+
+发布消息(PUBLISH channel message)
+* 将消息 message 发送给所有的订阅者:遍历频道的链表即可
+* 将消息发送给符合 pattern 的订阅者:只要有消息发布都需要来遍历一下
+
+查看订阅信息(PUBSUB)
+* PUBSUB CHANNELS:服务器被订阅的频道
+* PUBSUB NUMSUB xxx:返回频道的订阅者数量
+* PUBSUB NUMPAT:服务器被订阅模式的数量
+
+
+## 事务
+事务将多个命令请求打包,然后一次性、按顺序的执行。
+首先通过命令 MULTI 表示事务开始,然后输入多条命令,最后输入 EXEC 开始执行事务。
+
+* MULTI:将客户端的状态转为事务状态,将发送的命令存入队列
+* EXEC:遍历队列,执行命令,最后将所有的结果返回给客户端
+* WATCH:是一个乐观锁,在 EXEC 执行前,可以监视指定数据库的键是否被修改(别的客户端),如果是则拒绝执行事务。
+* ACID 性质:
+原子性:不支持回滚,会增加复杂度
+一致性:检查三个地方,入队错误:错误的命令不会被入队;执行错误:命令执行错误会返回错误信息;服务器停机:
+隔离性:单线程,并且事务执行时不会中断,因此总是串行的。
+耐久性:由 Redis 的持久化模式决定,当服务器运行在 AOF 持久化模式下且 appendfsync 选项设置为 always 时,事务也具有耐久性。
+
+
+## LUA 脚本
+初始化:八个步骤创建 Lua 环境
+执行 Redis 脚本的伪客户端:
+保存 Lua 脚本的脚本字典:
+
+
+## Lua 排序
+
+
+## 二进制位数组
+
+
+## 慢查询日志
+
+
+
+## 监视器