Redis 入门介绍

1、什么是Redis?

Redis是一个高可用的key-value内存数据库。value可以支持多种类型。包括字符串(string)、链表(list)、集合(set)、有序集合(zset sorted set)和哈希(hash)。类似于java中的HashMap也是key-value,value可以存放多种数据结构。

Redis是内存数据库,并且是key-value类型,没有复杂的关系。所以读取与存入比mysql这种传统的关系型数据库快。

相比于memcached内存数据库,它可以通过RDB或AOF的方式将内存数据存入磁盘空间,达到数据的持久化。并且Redis也可以通过主从复制,哨兵,集群等方式实现高可用。

2、Redis数据库

2.1 Redis数据库

Redis默认有16个数据库。

redisServer结构中保存着一个redisDb数组,int dbnum 保存着数据库数量。dbnum默认是16。

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

每个数据库对应一个redisDb结构,redisDb结构中的dict字典(键空间)保存了改数据库的所有的键值对 。

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

切换数据库select 1
当客户端切换到1号数据库时,数据结构示意图:

《Redis 入门介绍》 image.png

切换数据库select 2
当客户端切换到2号数据库时,数据结构示意图:

《Redis 入门介绍》 image.png

2.2 数据库建空间示意图

  • alphabet 是一个列表键,键的名字是字符串’alphabet’,键的值是一个包含三个元素的列表对象。
  • book是一个哈希表键,键的名字是字符串’book’,键的值是一个包含三个元素的哈希表对象。
  • message是一个字符串键,键的名字是字符串’message’,键的值是一个字符串对象’hello world’

    《Redis 入门介绍》 image.png

2.3 数据库操作

执行命令set date "2013.12.1"
添加一个新键值对到数据库,就是将键值对添加到对应数据库(redisDb)的字典(dict)中

《Redis 入门介绍》 date

删除book键del book

《Redis 入门介绍》 del

更新message键set message "blah blah"

《Redis 入门介绍》 set

取值alphabet lrange alphabet 0 -1

《Redis 入门介绍》 lrange

清空数据库flushdb
针对数据库本身的redis命令,基本上都是针对redisDb的字典(dict)进行操作。

2.4 键生存时间及过期策略

设置键过期时间,可以以秒或者毫秒精度

命令描述
expire <key> <ttl>设置键key的生存时间为ttl 秒
pexpire <key> <ttl>设置键key的生存时间为ttl 毫秒
expireat <key> <timestamp>设置键key的过期时间为timestamp所指定的秒数时间戳
pexpireat <key> <timestamp>设置键key的过期时间为timestamp所指定的毫秒数时间戳

expire test 5 :设置key test过期时间为5秒以后
pexpire test 6000 :设置key test过期时间为6000毫秒以后
expireat test 1377333100 :设置key test过期时间为1377333100
pexpireat test 1377333100000 :设置key test过期时间为1377333100000

实际上expire,pexpire ,expireat 三个命令都是使用pexpireat 命令实现的,redis会将其他类型的过期时间最终都转化为毫秒时间戳保存。

过期时间的保存

redisDb结构的expires字典保存了数据库中的所有键的过期时间,称为过期字典。
过期字典的key为指针,指向键空间的某个键对象。
过期字典的value为long long 整数,保存着过期时间戳-毫秒精度的unix时间戳。

struct redisDb{
     //过期字典,保存着键的过期时间
    dict *expires ;
}

《Redis 入门介绍》 expires

为了展示方面,图示中的键空间与过期字典会出现两次alphabet及book对象,实际中,键空间的key与过期字典的key指向的是同一个键对象,不会出现重复对象。

过期键的删除策略
删除策略描述优点缺点
定时删除设置键的过期时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作及时删除过期键,释放内存过期键数量较大时,会创建大量定时器,占用相当一部分cpu时间,不采用
惰性删除放任过期键不管,当获取键时,判断是否过期,过期的话,就删除掉,未过期,返回该键不用创建定时器,不占用cpu时间过期键会占用大量内存,导致数据积压
定期删除每隔一段时间,程序对数据库进行一次检查,删除过期键,至于删除多少过期键,检查多少个数据库,有算法决定是前两种策略的折中方案,既能比较及时释放内存,又能不占用大量cpu时间难点在于确定操作执行的时长和频率,既不能让删除操作执行太频繁而占用cpu时间,又不能执行太少,浪费内存
Redis服务器使用了惰性删除及定期删除两种策略。

惰性删除:所有读写Redis命令在执行之前都会调用expireIfNeeded函数对输入键进行检查。expireIfNeeded就像一个过滤器,将过期键删除。

《Redis 入门介绍》 expireIfNeeded

定期删除:redis的周期性函数serverCron会在规定时间内多次遍历各个数据库,从数据库的expires字典中随机检查一部分键的过期时间,并删除其中的过期键。

RDB对过期键的处理

生成RDB文件
savebgsave命令只会对未过期的键进行保存操作,保存至rdb文件。

载入RDB文件
如果服务器以主服务器模式运行,那么载入RDB文件时,不会将过期键导入。
如果服务器以从服务器模式运行,那么载入RDB文件时,会将过期键导入,等主服务器同步数据时,再删除掉过期数据。

AOF对过期键的处理

AOF文件写入
当服务器以AOF持久化模式运行时,对于未被删除的过期数据,AOF不会因为过期键产生任何影响。
对于已被删除的数据,程序会像AOF追加(append)一条DEL命令,来显示地记录该键已被删除。

AOF重写
在执行AOF重写的过程中,程序会对数据库中的键进行检查,已过期的键不会被保存至重写后的AOF文件中。

复制对过期键的处理

当服务器运行在复制模式下,从服务器的过期删除动作由主服务器控制。
主服务器在删除一个过期键时,会向从服务器发送一个DEl命令,告知从服务器删除过期键
从服务器执行客户端发送的命令时,即使碰见过期键也不会将过期键删除,而是会继续像处理未过期键一样进行处理。
从服务只有接收到主服务器的DEl命令,才会删除过期键。

    原文作者:心中翼
    原文地址: https://www.jianshu.com/p/26bf010d10f9
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞