redis-数据库

355 阅读5分钟

数据库

Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集群就没有数据库的概念。 Redis是一个字典结构的存储服务器,而实际上一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。这与我们熟知的在一个关系数据库实例中可以创建多个数据库类似,所以可以将其中的每个字典都理解成一个独立的数据库。

每个数据库对外都是一个从0开始的递增数字命名,Redis默认支持16个数据库(可以通过配置文件支持更多,无上限),可以通过配置databases来修改这一数字。客户端与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT命令更换数据库,如要选择1号数据库:

redis> SELECT 1
OK
redis [1] > GET foo
(nil)

数据库键空间

Redis 是一个键值对(key-value pair)数据库服务器, 服务器中的每个数据库都由一个 redis.h/redisDb 结构表示, 其中, redisDb 结构的 dict 字典保存了数据库中的所有键值对, 我们将这个字典称为键空间(key space):

typedef struct redisDb {

    // ...

    // 数据库键空间,保存着数据库中的所有键值对
    dict *dict;

    // ...

} redisDb;

键过期策略

redisDb结构的expries字典保存了数据库所有的键过期时间,我们称这个字典为过期字典: 过期字典的键是一个指针,这个指针指向键空间中的某个键对象(也即是某个数据库键)。 过期字典的值是一个 long类型的整数,这个整数保存饿键所指向的数据库键的过期时间,一个毫秒精度的UNIX时间戳。看下图是带有过期的时间的存储机构。其中过期字典的键其实是一个指针,对应同一个内存存储。

过期键的删除策略是定期删除策略+惰性删除策略 惰性删除的策略如下图:

定期删除策略: 过期键的定期删除策略由redis.c/activeExpireCycle函数实现,每当Redis的服务器周期性操作 redis.c/serverCron 函数执行时,activeExpireCycle函数就会被调用,它在规定的时间内,分多次遍历服务器中的各个数据库,从数据库的expires字典中随机检查一部分的过期时间,并删除其中过期键。 函数每次运行时,都从一定数量的数据库中取出一定数量的随机键进行检查,并删除其中的过期键。

AOF,RDB和复制功能对过期键的处理

生成RDB文件,执行SAVE和BGSAVE命令时,程序会直接忽略过期的键。 载入RDD文件时 1.服务器以主服务器运行时,载入RDB会直接忽略过期的键 2.服务器以从服务器运行时,载入RDB不出来过期键,但是主同步的从服务器时,数据将 最终保存一致。 生成AOF文件时类型,AOF都是追加的命令,当过期时,会在AOF中追加DEL命令。当AOF重写时,是以数据当时的状态重写,则过期的键会直接被忽略。 复制时,主服务器会主动删除过期的数据,然后同步从服务器。从服务器只是读取。

subscribe 命令监听数据库的通知。

详情可以看命令 重点:

  • Redis 服务器的所有数据库都保存在 redisServer.db 数组中, 而数据库的数量则由 redisServer.dbnum 属性保存。
  • 客户端通过修改目标数据库指针, 让它指向 redisServer.db 数组中的不同元素来切换不同的数据库。
  • 数据库主要由 dict 和 expires 两个字典构成, 其中 dict 字典负责保存键值对, 而 expires 字典则负责保存键的过期时间。 因为数据库由字典构成, 所以对数据库的操作都是建立在字典操作之上的。
  • 数据库的键总是一个字符串对象, 而值则可以是任意一种 Redis 对象类型, 包括字符串对象、哈希表对象、集合对象、列表对象和有序集合对象, 分别对应字符串键、哈希表键、集合键、列表键和有序集合键。
  • expires 字典的键指向数据库中的某个键, 而值则记录了数据库键的过期时间, 过期时间是一个以毫秒为单位的 UNIX 时间戳。
  • Redis 使用惰性删除和定期删除两种策略来删除过期的键: 惰性删除策略只在碰到过期键时才进行删除操作, 定期删除策略则每隔一段时间, 主动查找并删除过期键。
  • 执行 SAVE 命令或者 BGSAVE 命令所产生的新 RDB 文件不会包含已经过期的键。
  • 执行 BGREWRITEAOF 命令所产生的重写 AOF 文件不会包含已经过期的键。
  • 当一个过期键被删除之后, 服务器会追加一条 DEL 命令到现有 AOF 文件的末尾, 显式地删除过期键。
  • 当主服务器删除一个过期键之后, 它会向所有从服务器发送一条 DEL 命令, 显式地删除过期键。
  • 从服务器即使发现过期键, 也不会自作主张地删除它, 而是等待主节点发来 DEL 命令, 这种统一、中心化的过期键删除策略可以保证主从服务器数据的一致性。
  • 当 Redis 命令对数据库进行修改之后, 服务器会根据配置, 向客户端发送数据库通知。