第九章 数据库

9.1 服务器中的数据库

redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中,db数组的每个项都是一个redis.h/redisDb结构,dbnum属性决定应该创建多少个数据库:

typedef struct redisServer{ 
  //一个数组,保存着服务器中的所有数据库
  redisDb *db;

  //服务器的数据库数量
  int dbnum;
}

9.2 切换数据库

客户端可以通过select命令来切换目标数据库。

9.3 数据库键空间

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

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

添加、删除、更新、取值操作之外,还有很多针对数据库本身的redis命令,也是通过对键空间进行处理来完成。

读写键空间时的维护操作

当使用redis命令对数据库命令进行读写时,服务器不仅会对键空间进行指定的读写操作,还会执行一些额外的维护操作,其中包括:

  • 在读取一个键之后,服务器会根据键是否存在来更新服务器的键空间命中(hit)次数或键空间不命中(miss)次数,这两个值可以在info stats命令的keyspace_hits属性和keyspace_misses属性中查看。
  • 在读取一个键之后,服务器会更新键的LRU时间,这个值可以用于计算键的闲置时间,使用Object idletime<key>命令可以查询键key的闲置时间。
  • 如果服务器在读取一个键时发现该键已经过期,那么服务器会先删除这个过期键,然后才执行余下的其他操作。
  • 如果有客户端使用Watch命令监视了某个键,那么服务器在对被监视的键进行修改之后,会将这个键标记为脏(dirty),从而让事务程序注意到这个键已经被修改过。
  • 服务器每次修改一个键之后,都会对脏(dirty)键计数器的值增1,这个计数器会触发服务器的持久化以及复制操作。
  • 如果服务器开启了数据库通知功能,那么在对键进行修改之后,服务器将按配置发送相应的数据库通知。

9.4 设置键的生存时间或过期时间

通过Expire命令或者Pexpire命令,客户端可以以秒或者毫秒经度为数据库中的某个键设置生存时间(Time to Live,TTL),在经过指定的秒数或者毫秒数之后,服务器就会自动删除生存时间为0的键。 TTL命令和PTTL命令接受一个带有生存时间或者过期时间的键,返回这个键的剩余生存时间。

9.4.1 设置过期时间

Redis有四个不同的命令可以用于设置键的生存时间或过期时间:

  • Expire <key> <ttl>命令用于将键key的生存时间设置为ttl秒。
  • PExpire <key> <ttl>命令用于将键key的生存时间设置为ttl毫秒。
  • ExpireAT <key> <timestamp>命令用于将键key的过期时间设置为timestamp所指定的秒数时间戳。
  • PExpireAT <key> <timestamp>命令用于将键key的过期时间设置为timestamp所指定的毫秒数时间戳。

9.5 过期键删除策略

过期键如何被删除,有以下三种不同的策略:

  • 定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。
  • 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
  • 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。

三种策略的优缺点

  • 定时删除占用太多CPU时间,影响服务器的响应时间和吞吐量,但是对内存是最友好的;
  • 惰性删除浪费太多内存,有内存泄露的危险,但是对CPU时间是最友好的;
  • 定时删除策略是前两种策略的一种整合折中,需要合理地设置删除操作的执行时长和执行频率。

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

9.7.1 生成RDB文件

在执行Save命令或者BgSave命令创建一个新的RDB文件时,程序会对数据库中的键进行检查,已过期的键不会被保存到新创建的RDB文件中。

9.7.2 载入RDB文件

  • 如果服务器以主服务器模式运行,那么在载入RDB文件时,程序会对文件中的键进行检查,未过期的键会被载入到数据库中,而过期键则会被忽略,所以过期键对载入RDB文件的主服务器不会造成影响。
  • 如果服务器以从服务器模式运行,那么在载入RDB文件时,文件保存的所有键都载入到数据库中。

9.7.3 AOF文件写入

当服务器以AOF持久化模式运行时,如果数据库中的某个键已经过期,但它还没有被惰性删除或定期删除,那么AOF文件不会因为这个过期键而产生任何影响。

当被惰性删除或定期删除之后,程序会向AOF文件追加一条Del命令,来显示地记录该键已被删除。

9.7.5 复制

当服务器运行在复制模式下时,从服务器的过期键删除动作由主服务器控制:

  • 主服务器在删除一个过期键之后,会显式地向所有服务器发送一个DEL命令,告知从服务器删除这个过期键;
  • 从服务器在执行客户端发送的读命令时,即使碰到过期键也不会将过期键删除,而是继续像处理未过期的键一样处理过期键。
  • 从服务器只有在接到主服务器发来的DEL命令之后,才会删除过期键。

9.8 数据库通知

客户端可以通过订阅给定的频道或者模式,来获知数据库中键的变化,以及数据库中命令的执行情况。

results matching ""

    No results matching ""