|NO.Z.00015|——————————|BigDataEnd|——|Hadoop&Redis.V15|——|Redis.v15|缓存过期|淘汰策略.v01|

一、Redis数据结构及过期机制:Redis缓存过期Redis性能高:
### --- 官方数据

~~~     读:110000次/s
~~~     写:81000次/s
~~~     长期使用,key会不断增加,Redis作为缓存使用,物理内存也会满
~~~     内存与硬盘交换(swap) 虚拟内存 ,频繁IO 性能急剧下降
### --- maxmemory

~~~     不设置的场景
~~~     Redis的key是固定的,不会增加
~~~     Redis作为DB使用,保证数据的完整性,不能淘汰 , 可以做集群,横向扩展
~~~     缓存淘汰策略:禁止驱逐 (默认)
~~~     # 设置的场景

~~~     Redis是作为缓存使用,不断增加Key
~~~     maxmemory : 默认为0 不限制
~~~     问题:达到物理内存后性能急剧下架,甚至崩溃
~~~     内存与硬盘交换(swap) 虚拟内存 ,频繁IO 性能急剧下降设置多少?
~~~     与业务有关1个Redis实例,保证系统运行 1 G ,剩下的就都可以设置Redis物理内存的3/4
### --- slaver : 留出一定的内存
~~~     在redis.conf中

[root@linux123 ~]# vim /opt/yanqi/servers/redis/bin/redis.conf
maxmemory 1024mb
~~~     # 命令: 获得maxmemory数

CONFIG GET maxmemory
~~~     设置maxmemory后,当趋近maxmemory时,通过缓存淘汰策略,从内存中删除对象
~~~     不设置maxmemory 无最大内存限制 maxmemory-policy noeviction (禁止驱逐) 不淘汰
~~~     设置maxmemory maxmemory-policy 要配置
二、expire数据结构
### --- expire数据结构

~~~     在Redis中可以使用expire命令设置一个键的存活时间(ttl: time to live),
~~~     过了这段时间,该键就会自动被删除。
### --- expire的使用

~~~     expire命令的使用方法如下: expire key ttl(单位秒)
127.0.0.1:6379> expire name 2               # 2秒失效
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> set name zhangfei
OK
127.0.0.1:6379> ttl name                    # 永久有效
(integer) -1
127.0.0.1:6379> expire name 30              # 30秒失效
(integer) 1
127.0.0.1:6379> ttl name                    # 还有24秒失效
(integer) 24
127.0.0.1:6379> ttl name                    # 失效
(integer) -2
### --- expire原理

typedef struct redisDb {
    dict *dict; -- key Value
    dict *expires; -- key ttl
    dict *blocking_keys;
    dict *ready_keys;
    dict *watched_keys;
    int id;
} redisDb;
~~~     # 上面的代码是Redis 中关于数据库的结构体定义,
~~~     这个结构体定义中除了 id 以外都是指向字典的指针,其中我们只看 dict 和 expires。

~~~     # dict 用来维护一个 Redis 数据库中包含的所有 Key-Value 键值对,
~~~     expires则用于维护一个 Redis 数据库中设置了失效时间的键(即key与失效时间的映射)。
~~~     # 当我们使用 expire命令设置一个key的失效时间时,
~~~     Redis 首先到 dict 这个字典表中查找要设置的key是否存在,
~~~     如果存在就将这个key和失效时间添加到 expires 这个字典表。
~~~     # 当我们使用 setex命令向系统插入数据时,
~~~     Redis 首先将 Key 和 Value 添加到 dict 这个字典表中,
~~~     然后将 Key 和失效时间添加到 expires 这个字典表中。
~~~     # 简单地总结来说就是,
~~~     设置了失效时间的key和具体的失效时间全部都维护在 expires 这个字典表中。
### --- 删除策略

~~~     Redis的数据删除有定时删除、惰性删除和主动删除三种方式。
~~~     Redis目前采用惰性删除+主动删除的方式。
### --- 定时删除

~~~     在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,
~~~     立即执行对键的删除操作。
~~~     需要创建定时器,而且消耗CPU,一般不推荐使用。
### --- 惰性删除

~~~     在key被访问时如果发现它已经失效,那么就删除它。
~~~     调用expireIfNeeded函数,
~~~     该函数的意义是:读取数据之前先检查一下它有没有失效,如果失效了就删除它。
int expireIfNeeded(redisDb *db, robj *key) {
    //获取主键的失效时间 get当前时间-创建时间>ttl
    long long when = getExpire(db,key);
    //假如失效时间为负数,说明该主键未设置失效时间(失效时间默认为-1),直接返回0
    if (when < 0) return 0;
    //假如Redis服务器正在从RDB文件中加载数据,暂时不进行失效主键的删除,直接返回0
    if (server.loading) return 0;
    ...
    //如果以上条件都不满足,就将主键的失效时间与当前时间进行对比,如果发现指定的主键
    //还未失效就直接返回0
    if (mstime() <= when) return 0;
    //如果发现主键确实已经失效了,那么首先更新关于失效主键的统计个数,然后将该主键失
    //效的信息进行广播,最后将该主键从数据库中删除
    server.stat_expiredkeys++;
    propagateExpire(db,key);
    return dbDelete(db,key);
}
### --- 主动删除
~~~     在redis.conf文件中可以配置主动删除策略,默认是no-enviction(不删除)

[root@linux123 ~]# vim /opt/yanqi/servers/redis/bin/redis.conf
# maxmemory-policy noeviction       # 更改为
maxmemory-policy allkeys-lru

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

 

posted on   yanqi_vip  阅读(26)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示