Redis壶中天-数据库

数据库的基本内容

数据库、RDB、AOF、事件

本文所使用的Redis版本为3.2.8

数据库

服务器中的数据库

redisServer中的db数组保存服务器中的所有数据库,每个数据库都用一个redisDb结构表示。

切换数据库

默认情况下,客户端的目标数据库的index为0,如下选择2号数据库进行存储:

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> set msg "yrq"
OK
127.0.0.1:6379> get msg
"yrq"
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> get msg
(nil)
127.0.0.1:6379[2]> set msg "hello world"
OK
127.0.0.1:6379[2]> get msg
"hello world"

键空间

redisDb中的dict字典保存数据库中的所有键值对,也称键空间。

键值对的CURD操作

1
2
3
4
5
6
7
8
127.0.0.1:6379> set msg "hello"
OK
127.0.0.1:6379> del msg
(integer) 1
127.0.0.1:6379> set msg "hallo"
OK
127.0.0.1:6379> get msg
"hallo"

键的生存或过期时间

使用expire命令可以设置键的过期时间,值可以为秒数或unix时间戳。

1
2
3
4
5
6
7
8
127.0.0.1:6379> set name "yrq"
OK
127.0.0.1:6379> expire name 10
(integer) 1
127.0.0.1:6379> get name
"yrq"
127.0.0.1:6379> get name
(nil)

使用ttl和pttl命令查看剩余的生存时间,使用persist命令移除过期时间。

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> set msg "hello"
OK
127.0.0.1:6379> expire msg 2000
(integer) 1
127.0.0.1:6379> ttl msg
(integer) 1993
127.0.0.1:6379> pttl msg
(integer) 1986927
127.0.0.1:6379> persist msg
(integer) 1
127.0.0.1:6379> ttl msg
(integer) -1

redisDb中的expires字典保存了数据库中所有键的过期时间,当键过期时Redis服务器会采用惰性删除和定期删除结合的方式清理过期键。

RDB

RDB机制会将当前的数据库状态保存到一个文件中,是一种持久化机制。rdb文件用于保存和还原redis服务器所有数据库中的所有键值对数据。

创建与载入

执行save或bgsave命令时redis会将数据库状态保存进rdb文件中,不会包含已过期的键。

  1. 直接保存 - save
    save命令执行时redis服务器会被阻塞,当save正在执行时,所有客户端发送的请求都被会阻塞

    1
    2
    127.0.0.1:6379> save
    OK
  2. 子进程保存 - bgsave
    bgsave命令执行时会使用子进程进行rdb文件的创建与保存操作,当bgsave正在执行时,redis服务器可以继续处理客户端发送的命令请求

    1
    2
    127.0.0.1:6379> bgsave
    Background saving started
  3. 载入
    在rdb文件的载入过程中,会一直处于阻塞状态。启动redis服务器时,若开启了RDB功能则载入rdb文件。

设置保存条件

假设保存条件如下:

1
2
3
save 900 1
save 300 10
save 60 10000

只要满足这三个条件中的一条就会自动执行bgsave命令:

  • 服务器在900秒内对数据库进行了至少1次修改
  • 服务器在300秒内对数据库进行了至少10次修改
  • 服务器在60秒内对数据库进行了至少10000次修改

文件结构

一个完整的rdb文件通常包含这几个部分:

  • REDIS - ‘REDIS’字符串
  • db_version - 整数字符,表示rdb文件版本
  • database - 包含一个或多个数据库与其中的键值对数据
  • EOF - 常量,标志rdb文件正文结束
  • check_sum - rdb文件校验和

AOF

AOF(Append Only File)是另一种持久化机制,它是通过保存redis服务器执行的写命令来记录数据库状态的。

持久化过程

  1. 命令追加
    当数据库执行写命令后,会以协议格式将写命令存入服务器状态的aof_buf缓冲区
  2. 写入与加载
    在redis服务器的每个事件循环进程中,都会执行一个flushAppendOnlyFile函数。

    appendfsync值对flushAppendOnlyFile函数行为的影响:

    • always - 将缓冲区内容写入并同步到AOF文件
    • everysec - 将缓冲区内容写入到AOF文件中,每超过1秒钟都会对AOF文件进行一次同步
    • no - 将缓冲区内容写入AOF文件,不同步

载入与还原

  1. 服务器启动载入程序
  2. 创建伪客户端
  3. 从AOF文件中分析并读取出写命令
  4. 使用伪客户端执行被读出的写命令
  5. 重复执行步骤3和4,直到aof文件中的所有写命令被执行

重写

为了解决随着服务器运行时间流逝而产生的AOF文件体积膨胀问题,提供了AOF文件的重写功能,可以过滤掉冗余的写入命令,缩小文件体积。

重写实现

AOF重写并不读取、分析现有AOF文件,而是直接读取服务器当前的数据库状态。

若旧的AOF文件中保存有对某一个键的多个操作,则重写时通过读取数据库中这个键的值,使用一条命令记录键值对,代替之前的多条命令。

后台重写

若直接用aof_rewrite函数会造成服务器的阻塞,在重写期间无法接受客户端的命令请求,需要一种使用子进程的后台重写实现。

bgwriteaof命令是后台重写命令,执行时服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间保存服务器执行的所有写命令。当子进程完成AOF文件的创建时会将重写缓冲区中的写命令追加到AOF文件末尾,使新旧AOF文件保存的数据库状态一致,以新替旧,完成重写。

事件

Redis服务器是一个事件驱动的程序,需要处理的事件分为两类:文件事件和时间事件

文件事件

Redis服务器通过套接字与客户端进行连接,文件事件就是服务器对套接字操作的抽象。服务器与客户端的通信会产生其他文件,而服务器通过监听并处理这些事件来完成一系列网络通信操作。

文件处理器是给予Reactor模式实现的网络通信程序,由以下几个部分组成:

  1. 套接字
  2. I/O多路复用程序
  3. 文件事件分派器
  4. 事件处理器

文件事件分为读事件和写事件。

事件处理器中包含处理多种不同网络通信需求的处理器:连接应答处理器、命令请求处理器、命令回复处理器等。

时间事件

Redis服务器中的一些操作需要在给定的时间点执行,而时间事件就是服务器对这类定时操作的抽象。

时间事件分为定时事件和周期事件,定时事件只在指定的时间到达一次,周期时间每隔一段时间到达一次。

一个时间事件都由id(全局唯一id)、when(UNIX时间戳)和timeProc(时间事件处理器)三部分组成。

参考

文章目录
  1. 1. 数据库
    1. 1.1. 服务器中的数据库
    2. 1.2. 切换数据库
    3. 1.3. 键空间
    4. 1.4. 键的生存或过期时间
  2. 2. RDB
    1. 2.1. 创建与载入
    2. 2.2. 设置保存条件
    3. 2.3. 文件结构
  3. 3. AOF
    1. 3.1. 持久化过程
    2. 3.2. 载入与还原
    3. 3.3. 重写
      1. 3.3.1. 重写实现
      2. 3.3.2. 后台重写
  4. 4. 事件
    1. 4.1. 文件事件
    2. 4.2. 时间事件
  5. 5. 参考
|