redis使用了单线程架构和I/O多路复用模型实现高性能的内存数据库。
- 纯内存访问。
- 采用epoll模式进行io操作,是基于事件驱动的io多路复用技术。
- 单线程避免了多线程切换和竞态产生的消耗。
内部编码:int 8字节的长整型 embstr 小于等于39个字节 raw 大于39个字节
ziplist linkedlist
lpush+lpop =Stack栈
lpush+rpop=Queue队列
lpsh+ltrim=Capped Collection有限集合
lpush+brpop=Message Queue 消息队列
ziplist hashtable
intset hashtable
ziplist skiplist
持久化:
- 快照存储(RDB),当前进程数据生成快照写入硬盘中。
- 追加文件(AOF),以独立日志的方式记录每次写命令,重启时再执行AOF文件中的命令。解决了实时性
RDB:
- 可以通过 bgsave命令创建一个快照 ,redis会调用一个fork(系统创建进程的函数,返回一个父进程和子进程)进程来创建一个子进程(内存数据过大时,创建子进程耗费时间就越长,占用大量虚拟内存,导致性能降低)负责写入快照,父进程继续处理请求。
- 可以通过save 命令开始创建快照,期间不响应(停顿时间长)任何请求,不会创建子进程,速度块。
- 若配置了save 60 1000 则当满足距离上一次成功生成快照后60秒内有1000次写入,会自动触发bgsave命令。
- 当遇到shutdown nosave|save或term信号时会执行一个save命令,阻塞所有客户端,不接受任何请求,执行完save后关闭redis服务器。
2067:S 21 Apr 2020 08:52:11.407 # User requested shutdown... 先发送命令
2067:S 21 Apr 2020 08:52:11.407 * Calling fsync() on the AOF file. fsync写入aof
2067:S 21 Apr 2020 08:52:11.407 * Saving the final RDB snapshot before exiting. 持久化rdb
2067:S 21 Apr 2020 08:52:11.409 * DB saved on disk 将rdb文件保存再磁盘
2067:S 21 Apr 2020 08:52:11.409 * Removing the pid file.
2067:S 21 Apr 2020 08:52:11.409 # Redis is now ready to exit, bye bye...
会丢失最近一次快照之后更改的所有数据------是否可以丢失这一部分数据。
AOF:
将被执行的写命令写到AOF文件的末尾,记录数据发生的变换。重启时需要从头到尾执行AOF文件包含的所有命令就可恢复记录的数据集。像磁盘写文件时:写的内容--》内存缓冲---》再到硬盘,同步阻塞(sync)写入---同步操作会阻塞到指定的文件写入硬盘为止,执行后,即使系统崩溃,也不会造成影响。直接写入的是协议格式。
-
always:每个写命令都要同步写入磁盘,(redis处理命令时会受到硬盘性能的限制)降低速度。
-
everysec:每秒执行一次同步,显示地将多个写命令同步到磁盘
-
no:操作系统决定何时同步。
长时间后AOF文件会越来越大,同时还原数据执行文件里的命令所用时间也越来越长。可通过bgrewriteaof命令重写aof文件,去掉冗余的命令,使得文件尽可能的小。bgrewriteaof命令同样会创建一个子进程去负责aof文件的重写,存在创建子进程而导致的性能和内存占用问题,当aof文件足够大时,重写时会导致操作系统挂起时间过长。