小编带你了解Redis内部是运作机制
Redis数据库的结构:
typeof struct redisDb{ int id ; // 数据库的id dict *dict ; // 保存着该数据库的所有键值对 也被称为键空间 dict *expires ; // 保存着键的过期时间 ….. } redisDb ; Redis 是一个键值对 字典表,同样Redis数据库存储形式也是键值对 字典表 键是字符串 值可以是字符型、list 列表、 hash、集合以及 有序集合其中之一
Redis 数据库增、删、改、查等操作的键空间操作:
新增:
Redis会在键空间字典中增加一个键-值对,其中键为一个字符串,值为任意一个值类型。
删除:
Redis会在键空间字典中删去对应键的键-值对
更新:
Redis会在键空间字典中释放之前对应键的值对象,并让键指向新的值对象
查询:
Redis会在键空间字典中查询对应键的值对象:
键不存在,返回NULL
键存在,且类型正确,返回正确的值
键存在,但类型不正确,返回类型错误
其他操作:
除了上面展示的键值操作之外,还有很多针对数据库本身的命令,也是通过对键空间进行处理 来完成的:
FLUSHDB 删除键空间中的所有键值对
RANDOMKEY 从键空间中随机返回一个键
DBSIZE 返回键空间中键值对的数量
EXISTS 检查给定键是否存在于键空间中
RENAME 在键空间中,对给定键进行改名
键的过期时间
在Redis数据库中,所有键的过期时间都保存在RedisDb结构体的expires字典中,其中键为一个指向dict 字典(键空间)里某个键的指针,值为改建的过期时间,用long long型表示。
Redis 有四个命令可以设置键的生存时间(可以存活多久)和过期时间(什么时候到期):
EXPIRE 以秒为单位设置键的生存时间;
PEXPIRE 以毫秒为单位设置键的生存时间;
EXPIREAT 以秒为单位,设置键的过期 UNIX 时间戳;
PEXPIREAT 以毫秒为单位,设置键的过期 UNIX 时间戳。
虽然有那么多种不同单位和不同形式的设置方式,但是 expires 字典的值只保存“以毫秒为单 位的过期 UNIX 时间戳” ,这就是说,通过进行转换,所有命令的效果最后都和 PEXPIREAT 命令的效果一样。
过期键的清除
定时清除:
在创建KEY的时候创建一个定时任务,在KEY到期时定时任务会被触发,第一时间清除过期KEY。
此种操作对内存最友好,不会有垃圾数据占用内存情况存在
缺点是会造成很大的服务器负载,特别是CPU负载高的时候,CPU很大一部分负载用在了删除不必要的KEY上了
惰性清除:
放任键空间的键不管,每次查询KEY的时候先去校验KEY是否过期,过期则删除,不过期则正常返回相应的VALUE。
此种操作对CPU最友好,这种策略仅限于当前KEY,相关不必要的KEY不会造成CPU负载
缺点是:容易造成内存空间浪费,特别是当系统中存在大量过期KEY且很少被用到,这十分影响非常依赖于内存大小Redis的性能
定期删除:
由定时脚本cron定时对expires的键扫描判断是否有过期的KEY存在,如存在,将其删除掉。
这是一种折中方案,既不会过多消耗CPU,又可以定时清楚惰性删除忽略到的不必要的内存消耗
Redis采用的“惰性清除”和“定期清楚”相结合的方式,其中定期删除模式是在规定的时间限制内,尽 可能地遍历各个数据库的 expires 字典,随机地检查一部分键的过期时间,并删除其中的过期键。