3. Redis 服务和数据库

75 阅读2分钟

一个Reids服务由多个Redis数据库组成。 redis的数据库实际上是一个dict

Redis 服务 数据结构

typedef struct redisServer {
    ....
    redisDb *db;//数组,保存服务中的所有数据库
    
    int dbnum;//服务器中数据库数量,由配置文件的database决定
    ....
}


typedef struct redisDb {
    ...
    dict *dict;
    dict * expires;//失效时间数据库
}

切换数据库

每一个redis客户端连接服务的时候,redis都会生成 一个redisClient 结构体来记录客户端的相关信息。

typedef struct redisClient {
    ...
    redisDb *db;//当前使用的数据库
    ...
}

执行select 1 ,实际上就是切换db指针指向的对象

数据库的kv

k始终为redisString对象

v为实际存储的redis对象.例如 lPush l1 v1,则存储的对象是redis_list.

过期

命令

  1. expire k ttl:多少s后失效
  2. expireat k timestamp:在什么时间点失效
  3. pexpire k ttl:多少ms后失效
  4. pexpireat k timestamp

实际上都是调用pexpireat命令.其他的命令会做一系列的转化.

过期时间实际上是使用一个dict * expires map保存的

删除

  1. 惰性删除:过期后不立即删除,而是等到访问或者其他操作的时候在判断是否过期然后在进行删除.

  2. 定期(限定每次执行删除操作的时间)删除:如何保证删除是全部遍历,而不是饿死某些键?使用一个数据库记录当前正常处理的数据库序号.本质上就是按顺序删除的。

    1. redis周期性调用redis.c/serverCron函数

    2. serverCron会调用activeExpireCycle函数

      1. 使用全局变量curent_db记录当前处理的数据库,从0开始,每调用一次后curent_db+1,直到和数据库总数相等的时候,重新从0开始
      2. 每次执行删除操作的时候,从当前数据库随机选择一定个数的key,判断其是否失效,如果失效就执行删除操作。(这个会不会和用户重新设置有效期的操作并发?)
  3. 惰性删除和定期删除也会写AOF文件

  4. 从服务器不会执行惰性删除,目的是为了主从数据完全一致。