数据库

作者: 简书徐小耳 | 来源:发表于2018-12-06 13:41 被阅读1次

redis.h文件中 redisServer结构包含一个db数组

db数组中的每一项都是一个redis.h文件中的 redisDb结构,每个redisDb就是一个数据库

  • redisServer中的dbnum决定了数据库的数量,默认为16个


    image.png

切换数据库

  • 每个redis客户端都有自己对应的目标数据库
  • 默认都选择0号数据库,但是可以通过执行select命令来切换,比如select 2就是选择2号数据库
  • redisClient结构的db属性记录了当前客户端的目标数据库,该属性是指向redisDb结构的指针


    image.png

数据库键空间

  • 我们成一个db中的dict字典为键空间。
  • 键空间和用户所见的数据库是直接对应的


    image.png
  • 如下图分别展示了键值是list hashtable,string的三种形态
  • 整个db 就是一个dict(A),A中的key是我们常写的key 其职能是字符串对象,value 则可以是五种对象


    image.png

读写键空间时的维护操作

  • 当我们对DB进行读写操作时候还会进行一些额外的操作
  • 在读取一个键之后(读写操作都需要读取键),服务器会根据键是否存在来更新服务器键空间命中(hit)次数和不命中(miss)次数,我们分别可以在keyspace_hits和keyspace_misses查看
  • 在读取一个键之后,服务器会更新键的LRU,该值用来计算键的空闲时间
  • 在读取一个键之后,如果发现该键已经过期,那么服务器会先删除这个过期键,然后才执行余下的其他操作。
  • 如果有客户端使用了watch命名监视某个键,那么服务器对监视的键进行修改后会将这个键标记为脏(dirty),从而让食物程序注意到这个键已经被修改过
  • 每次修改一个键之后,都会对dirty键计数器自增1,这个计数器会触发服务器的持久化和赋值操作
  • 如果服务器开启了数据库通知功能,那么对键进行修改后,服务器将会按照配置发送相应的数据库通知

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

  • expire或者pexpire 都可以以秒或者毫秒为精度为某个键设置生存时间(TIME TO LIVE TTL),服务器会在指定时间自动删除生存时间为0的键
  • setex 可以设置一个字符串键的同时设置一个过期时间,但是其只限于字符串键(对于其他的list或者hash等不适合)

expire(生存时间,秒) pexpire(生存时间毫秒) expireat (过期时间 ,秒)pexpireat(过期时间,毫秒数) 都可以设置键的生存时间(键可以存在多久)或者过期时间(什么时候删除)

  • 过期时间都是 保存的unix的时间戳,而生存时间都是保存的秒数或者毫秒数

上面前三个指令都是依赖pexpireat实现的

image.png

redisDb结构的expires字典保存了数据库中所有键的过期时间,我们称呼这个为过期字典

  • 过期字典的键是一个指针,这个指针指向键空间中的某个键对象(即指向key)
  • 过期字典的值是一个 long long 类型的整数,这个整数保存了键所指向的数据库键的过期时间--毫秒精度的unix时间戳
image.png image.png
  • TTL命令可以秒为单位返回键的剩余生成时间,PTTL则以毫秒返回,主要原理就是去过期字典获取过期时间然后减去当前时间

  • persist 命令可以移除一个键的过期时间,该命令在过期字典中查找给定的键,并删除该key和valvue

  • redis 检测过期键的步骤如下:检测key是否存在过期字典中,检测所要查找的key的时间戳与当前时间进行对比

过期键删除策略

  • 定时删除:对内存最友好,通过定时器,定时删除,减少内存占用策略,但是对于cpu不好(因为线程总是要占用cpu执行),造成吞吐量和响应时间不高。创建一个定时器需要用到redis服务器中的时间事件(类似我们一个socket事件),那么每个键都需要一个定时器,导致时间事件以无序列表存储,查找一个事件的时间复杂度N,这就导致效率不高。

  • 惰性删除:对于cpu最好(使用该key才检测是否过期),但是对于内存不友好。如果我们不使用该key 可能存在内存泄漏

  • 定期删除:定期执行一次删除过期键的操作,但是频率和时长需要考虑,不能太频繁 也不能太低

  • redis 使用惰性删除和定期删除

  • 惰性删除依靠expireIfNeeded函数实现,读写数据库前都需要调用该函数,如果键过期就删除否则不做处理。

image.png
  • 定期删除策略通过activeExpireCycle函数实现,每次redis的服务器周期性操作serverCron函数,而serverCron则调用activeExpireCycle,其主要是在规定时间内分多次遍历服务器中的各个数据库,从数据库中的expire字典中随机检查一部分键的过期时间,并删除
image.png

RDB 对过期键进行处理

  • 生成RDB:已经过期的键不会被保存到RDB文件
  • 载入RDB: 如果服务器是主服务器,则在载入RDB文件时候,对于已经过期的键会忽略,而若是从服务器则不会忽略,但是因为主从服务器在进行数据同步,从服务器的数据库就会被情况

AOF对过期键进行处理

  • AOF文件写入: 如果是以AOF的形式运行,但是该键就算过期但是没有被删除,还是会写入文件,如果被删除后AOF 会在文件中追加一条DEL命令,来显示记录该键删除
  • AOF 重写: 程序会对数据库文件中的key进行检查,已经过期的不会被保存到重写后的AOF文件

复制

  • 当处于复制模式,从服务器的过期键删除动作由主服务器控制
  • 主服务器删除一个过期键,会显示低向从服务器发送一个DEL命令
  • 从服务器遇到读命令,读到过期键也不会删除
  • 从服务器收到主服务器DEL命令才删除过期键
  • 这样的好处可以保持主从数据的一致性(比如从服务检测到过期键删除,而主服务器没有检测到,那么主从就不一致了)

通知分为 键空间通知和键事件通知,前者可以监控一个key执行了哪些命令,后者可以监控一个命令被哪些键执行了

相关文章

  • MySQL数据库day01

    系统数据库 ​​​ 创建数据库 ​​​ ​​​ ​​​ ​​​ 查看所有数据库 使用数据库 修改数据库 删除数据库...

  • 数据库操作

    创建数据库: 选择数据库: 查看数据库: 修改数据库: 删除数据库:

  • Ubuntu操作mysql数据库命令

    一、连接数据库 连接本地数据库 退出数据库 二、操作数据库 创建数据库 显示数据库 删除数据库 连接数据库 查看状...

  • 4-14

    创建数据库 createdatabase数据库名称; 删除数据库 dropdatabase数据库名称; 查看数据库...

  • [后端开发] Mysql学习笔记

    1.0 数据库 创建数据库 查看所有数据库 删除数据库 切换数据库名 查看正在使用的数据库 2.0 数据库表 创...

  • 2020最新最全数据库系统安全

    数据库标识与鉴别 数据库访问控制 数据库安全审计 数据库备份与恢复 数据库加密 资源限制 数据库安全加固 数据库安...

  • 2020-01-05 sql基本概念

    数据库用来储存数据。 数据库的种类大致有:层次数据库、关系数据库、面向对象数据库、XML数据库、键值数据库。 关系...

  • Mysql数据库基本操作

    连接数据库 退出数据库 查看数据库版本 显示数据库时间 查看当前使用的数据库 查看所有数据库 数据库备份 导入数据...

  • mysql命令行操作

    准备 登陆 数据库操作 查看现有数据库 创建数据库 删除数据库 查看数据库 使用数据库 查看当前数据库 表操作 新...

  • 1.7.1 MySQL数据库学习

    1. 数据库命令行学习 进入数据库 创建数据库 查看数据库列表 删除数据库 使用数据库 查看当前数据库 2. 表 ...

网友评论

      本文标题:数据库

      本文链接:https://www.haomeiwen.com/subject/pjiicqtx.html