Redis设计与实现之数据库
数据库的存储
数据库保存在 server.h/redisServer结构的redisDb *db中
, 其结构如下:
redisServer中,存储了一个数据库列表, 在服务启动时, 会根据 dbnum
大小决定创建多少个数据库, dbnum大小有服务器配置的 database选项
决定, 默认值为 16
数据库的定义
代码定义在: server.h/redisDb
1 |
|
切换数据库
每个 redis 客户端都有自己的目标数据库, 每个客户端读取数据库写入或者读取命令时,目标数据库回程问这些命令的操作对象.
默认情况下, redis客户端目标数据库为 0 号数据库, 但是客户端可以通过 SELECT
命令来切换数据库
下图演示了数据库切换的操作:
在服务器内部, 客户端 client(server.h/client)
结构的 db
属性,记录了客户端当前的目标数据库, 这个属性是一个指向 redisDb结构的指针
1 |
|
client.db
只想的就是 server.db
中的一个元素, 而被指向的元素, 就是客户端的目标数据库.
通过修改 client.db 的指针, 让它指向服务器中不同的数据库, 从而实现切换目标数据库的功能 , 这就是 SELECT 指令的实现原理
拓展思考
假设我们当前有16个数据库, 当前已经向 id = 15 的数据库中写入了数据, 此时出于种种原因, 调整 databases = 8 , 重启服务会发生什么呢?
此问题分三个场景
作为纯内存缓存数据库使用
因为时纯内存的数据库, 重启时, 会清空全部数据, 再次启动时,不会有任何影响, 但是如果客户端未升级, 选择的数据库 >= 8, 此时客户端会报错
开启了持久化
若开启了持久化, 由于服务启动时会从持久化文件恢复数据, 则会产生数据无法恢复的情况, 进而导致服务无法启动
, 具体报错如下:
缩减数量的同时,关闭持久化
在缩减database数量同时,关闭数据持久化,作为内存缓存使用,又会怎么样?
如果 未删除之前持久化的文件dump.rdb, 则服务依旧无法启动, 报错信息同 开启了持久化
的场景
如果删除了持久化的文件, 则服务可以正常启动, 场景同 作为纯内存缓存数据库使用