[后台开发工程师总结系列] 7.Redis简介

Redis

特点

Redis 本质上是一个Key-value类型的内存数据库,很像memcached, 整个数据库在内存中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保护,因为是存内存操作,Redis性能十分出色,每秒可以处理10万次的读写操作,是已知性能最快的DB。

Redis性能出色之处不仅仅是性能,Redis最大魅力是支持多种数据结构,Redis单个value的最大限制是1GB, 而memcached只能保证1MB的数据。Redis 可以用LIST做双向链表实现一个轻量级的高性能消息服务队列。

Redis的主要缺点是数据库容量收到物理内存的限制,不能用做海量数据的高性能读写

redis的好处

  • 速度快,数据存在内存中,类似hashmap, 查找时间复杂度O(1)
  • 支持丰富的数据类型 string、lsit、set、zset、hash
  • 支持事务,操作都是原子性的
  • 丰富的特性,可以用于缓存、消息

memchached 与 Redis 的区别

  • 储存方式,Memched数据都在内存中,断电后会挂掉。Redis有数据的持久性
  • 数据支持类型上:Memcached 对数据类型支持简单,而Redis有复杂的数据类型
  • 底层的模型不同,与客户端的通信协议不同,Redis 直接构建了VM机制

跳跃表

跳跃表是一种有序的数据结构,它在每个节点中维护多个指向其他节点的指针,从而达到快速访问节点的目的。跳跃表支持平均(logN)最坏(N)复杂度的节点查找,还可以通过顺序操作来批量处理节点。

在大部分情况下,跳跃表效率可以和平衡树媲美,而且其实现比平衡树简单,很多程序用跳表代替平衡树。

Redis跳表用zskiplistNode 和 zskiplist 来定义

最左边是一个zskiplit结构,它包含了以下部分:

  • header: 指向跳跃表的头结点
  • tail:指向跳跃表的尾节点
  • level:目前跳表中,层数最大节点的层数
  • length:跳跃表所含节点的数量

而每一个zskiplistNode含有如下结构

  • 层:节点中L1、L2、L3标记各个层。每个层带有两个属性,前进和跨度。
  • 后退指针:指向前一个节点,逆序遍历使用
  • 分值:各个节点中1、2、3都是分值,从小到大排列
  • 各个节点保存了成员对象

Redis的 RDB 和 AOF

Redis是内存数据库,他自己的数据库状态在内存中,如果不想办法从内存保存到磁盘,一旦服务器退出,服务器中的数据库状态也会消失不见。

为了解决这个问题,Redis提供了RDB持久化功能,将内存中的数据保存在磁盘中。

RDB可以手动执行,或根据服务器配置定期执行。

RDB文件的创建命令:SAVE(阻塞)和 BGSAVE(非阻塞)

另外,如果服务器开启了AOF持久化的功能,服务器优先使用AOF还原数据

只有AOF关闭时,才使用RDB来还原数据库状态

RDB是一个压缩的二进制文件。对于不同的键值对,RDB用不同的方式保存。

AOF持久化

除了RDB持久化以外,Redis还提供了 AOF 持久化功能。

与RDB持久化通过保存数据中的键值对记录来记录数据库状态不同,AOF持久化是通过保存Redis服务器记录的写命令来记录数据库状态的。

简单的来说,RDB保存的是 a:1 这个键值对, 而AOF 保存的是write a 1这个命令

  • AOF持久化分为追加、文件写入、文件同步 三个步骤
  • 命令追加

当AOF持久化功能打开时,服务器执行完一个写命令以后,会以协议格式将被执行的命令追加到服务器状态的 aof_buf 缓冲区末尾。

  • AOF文件的写入与同步

Redis的服务进程是一个事件循环,这个事件循环中文件事件负责接收客户端的命令请求,以及向客户端发送命令,而时间事件就是想servercron这样定时函数

为了提高文件的写入效率,现代操作系统中用户调用write函数写文件时常常将其保存到一个缓冲区中,等到缓冲区被填满时、或者超过了指定的时限后,才真正的将缓冲区数据写入磁盘

这种写法虽然高效,但是也为写入数据带来了安全性问题,因为如果计算机发生停机,缓冲区数据会消失。为此系统提供了Fsync函数,强制写缓冲区数据

AOF持久化的效率和安全性 取决于appendfsync 当其为always时, 服务器在每个事件循环都将缓冲区写入文件,并同步AOF文件。everysec 每个事件循环都写文件,但是1s同步一次 no 每个事件循环写文件,同步等待系统决定

执行 BGwriteaof 命令时, Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建AOF文件期间,记录服务器所有的写命令。当子进程完成创建新的AOF工作后,服务器会将重写缓冲区中的内容追加到AOF文件末尾,使得AOF 保存数据库状态一致。最后用新的AOF文件完成AOF文件的重写操作。