一、持久化
□ 何为持久化
□ 为什么要做持久化
□ 持久化方式?
1.将数据写入磁盘(RDB)
2.将操作记录写入磁盘(AOF)
□ RDB持久化
□ 手动触发RDB
SAVE:执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。
BGSAVE:指定bgsave命令期间,Redis会在后台异步执行RDB,此时Redis仍然可以响应客户端请求。
□ 自动触发RDB
□ 调用周期函数(serverCron),默认每100毫秒执行一次。
□ 检查save选项所设置的条件。
□ 执行bgsave命令。
值1 | 值2 | |
save | 900 | 1 |
save | 300 | 10 |
save | 60 | 10000 |
条件1 | 条件2 | |
save | (时间段)<=900s | (Redis的变化次数)>=1 |
save | (时间段)<=300s | (Redis的变化次数)>=10 |
save | (时间段)<=60s | (Redis的变化次数)>=10000 |
□ dirty计数器和lastsave属性
◇ dirty记录了自上次bgsave后,redis被修改的次数(包括写入、删除、更新等操作)。
◇ lastsave属性是一个时间戳,记录上一次成功执行bgsave命令的时间。
□ RDB配置
参数 | 值 | 作用描述 |
rdbcompression | yes | 导出的rdb文件是否压缩 |
rdbchecksum | yes | 导入rbd恢复数据时,检查rdb的完整性 |
save | ...... | ...... |
dbfilename | dump.rdb | 导出来的rdb文件名 |
dir | ./ | rdb的放置路径 |
□ AOF持久化
□ AOF概念
AOF(append only file)持久化是通过保存Redis服务器所执行的写命令来记录数据库的状态。
□ RDB与AOF的区别
RDB | AOF | |
1 | 保存的是键值对数据。 | 保存的是操作记录。 |
2 | 只能保存某一时刻的数据,无法做到实时持久化 | 可以实时持久化 |
3 | 加载RDB数据文件速度快 | 加载AOF文件,需先创建伪客户端,将AOF中的指令执行一遍。 |
□ AOF持久化的过程
□ AOF写入同步策略
同步策略由appendfsync参数决定,该参数有三个选项值:always、everysec、no。
◇ always:Redis服务器在每个事件循环中都将AOF缓冲区中的数据写入AOF文件中,且执行一次AOF文件同步操作
◇ evenrysec:Redis服务器在每个事件循环都将AOF缓冲区中的数据写入AOF文件中,且每秒执行一次AOF文件同步操作。
◇ no:Redis服务器在每个事件循环都将AOF缓冲区中的数据写入AOF文件中,但不执行同步fsync方法,由操作系统决定何时同步。
□ AOF文件的载入与数据还原
□ AOF配置
参数 | 值 | 作用 |
appendonly | yes|no | |
appendfsync | always|everysec|no | |
appendfilename | appendonly.aof | |
dir | ./ |
□ AOF重写
为了解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写(rewrite)功能。通过该功能,Redis可以创建一个新的AOF文件来替代现有的AOF文件。新旧两个AOF文件所保存的Redis状态相同,但是新的AOF不会包含任何浪费空间的冗余命令,所以新AOF文件的体积通常比旧AOF文件的体积要小得很多。
□ AOF重写的实现原理
AOF文件重写并不需要对现有的AOF文件进行任何读取、分析或者写入操作,而是通过读取服务器当前的数据库状态,把内存中的数据逆化成命令写入aof日志里。
□ AOF后台重写
AOF重写函数会进行大量的写入操作,调用该函数的线程将被长时间阻塞,Redis决定将AOF重写程序放到子进程里执行,这样可以同时达到两个目的:
○ 子进程进行AOF重写期间,Redis进程可以继续处理客户端命令请求。
○ 子进程带有父进程的内存数据拷贝副本,可以在避免使用锁的情况下,保证数据的安全性。
○ AOF文件重写时的服务器进程和子进程
○ 在子进程进行AOF重启期间,Redis接收客户端命令,会对现有数据库状态进行修改,从而导致数据当前状态和重写后的AOF文件所保存的数据库状态不一致。
□ AOF重写配置
◇ no-appendfsync-on-rewrite yes:# 正在导出rdb快照的过程中,要不要停止同步aof
◇ auto-aof-rewrite-percentage 100 # aof文件大小比起上次重写是的大小,增长率100%时,重写
◇ auto-aof-rewarite-min-size 64mb # aof文件,至少超过64M时,重写
二、事务
□ 事务的概述
事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。
□ 事务的实现
□ 事务的三个阶段
1.事务开始(MULTI)
2.命令入队
3.事务执行(EXEC、DISCARD)
□ 事务的操作
□ WATCH
时间 | 客户端A | 客户端B |
T0 | SET age 30 | |
T1 | WATCH age | |
T2 | MULTI | |
T3 | SET age 35 | |
T4 | GET age | |
T5 | EXEC |
WATCH是一个乐观锁,它可以在EXEC命令执行之前,监视数据库的键,并在EXEC命令执行时,检查被监视的键是否已经被修改过,如果被修改,服务器将拒绝执行事务,并返回(nil)。
□ 事务操作注意事项
□ 事务中命令格式输错
◇ 事务会被销毁,事务中的所有命令都不执行。
□ 事务执行时报错
◇ 事务中的正确命令会被执行,错误的命令不会被执行
三、数据的删除
□ 时效性数据结构
□ 设置键的时效性或过期时间
◇ expire、expireat、pexpire、pexpireat
□ 键的状态
a. n:剩余的存活时间
b. -1:永久有效数据
c. -2:键不存在(未定义、被删除、过期)
□ 过期键的删除策略
□ 为什么对过期键盘的删除要讲究策略呢?
□ 定时删除
在设置键的过期时间的同时,会创建一个定时器,让定时器在键的过期时间来临时,立即执行删除操作。
□ 优点
◇ 可快速释放内存
□ 缺点
1.需要大量定时器
2.占用CPU资源
□ 惰性删除
放任过期键不管,但每次获取键时,会检查键是否过期。
1.如果过期就删除
2.未过期则返回数据
□ 优点
节省cpu资源
□ 缺点
占用内存
□ 两种策略缺陷
1.定时删除占用太多cpu,影响系统响应时间
2.惰性删除浪费太多内存,存在内存泄漏风险。
□ 定期删除
1.定期遍历数据库(hz)
2.遍历过期键。
3.删除部分过期键。
□ 逐出算法
□ 内存管理
Redis向内存中插入数据时,会调用函数freeMemoryIfNeeded()查看是否有足够内存:
1.足够:则插入数据。
2.不足:Redis要删除一些数据清理内存空间。
□ redis中存在的数据
1.永久数据
2.未到期的时效性数据
3.过期数据
□ 检测全库数据(server.db[i].dict)
1.allkeys-lru:挑选最近最久未使用的数据淘汰
2.allkeys-lfu:挑选最近使用次数最少的数据淘汰
3.allkeys-random:任意选择数据淘汰
□ 检测未到期的时效性数据(server.db[i].expires)
1.volatile-lru:挑选最近最久未使用的数据淘汰
2.volatile-lfu:挑选最近使用次数最少的数据淘汰
3.volatile-ttl:挑选将要过期的数据淘汰
4.volatile-random:任意选择数据淘汰
□ 相关配置
参数 | 作用描述 |
maxmemory | 默认值为0,表示不限制。建议为物理内存的70%-80%。 |
maxmemory-samples | 每次选取待删除数据的个数 |
maxmemory-polocy | 逐出策略 |
四、高并发模型
□ IO基础
1.应用程序如何从(硬盘、网卡)设备读取数据的?
□ IO模型
□ 阻塞IO
□ 非阻塞IO
□ IO多路复用
□ 三种IO模型对比
□ Redis高并发总结
□ 单线程每秒万级别处理能力的原因?
1.Redis是内存数据库,这是处理高并发访问的重要基础。
2.Redis采用I/O多路复用技术,单线程可以处理多个客户端请求。
3.单线程避免了线程切换产生的消耗。
4.Redis采用单线程模型,在使用的时候,要注意不要使用O(N)级别的命令,免得系统资源被占用,从而拖慢整个系统。