zoukankan      html  css  js  c++  java
  • redis的过期策略

      最近把内存淘汰策略和过期策略搞混了。。。。

      Redis的过期策略就是指当Redis中缓存的key过期了,Redis是怎么处理的

      Redis的过期策略有三种:

      • 定时删除

          在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作,并释放过期键占用的内存。

          优点:对内存友好

          缺点:对CPU时间非常不友好

      • 惰性删除

          只有当访问到一个key时,才会检查key有没有过期,过期则删除,返回-1;没有过期则返回该键。

          优点:对CPU时间非常友好

          缺点:对内存非常不友好(存在键过期,但是一致没有访问到,则会一直存在内存中)

      • 定期删除

          每隔一段时间,程序对数据库进行一次检查,删除里面的过期key,至于要删除那些数据库的过期key,则由算法决定。

          定期删除策略每隔一段时间执行一次删除过期键的操作,并通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响,同时通过定期删除过期键,也有有效的减少了因为过期键带来的内存浪费。

      Redis使用的是惰性删除和定期删除。

    • 惰性删除的实现

        Redis对所有读写数据库的命令在执行前,都会调用expiredIfNeeded对键进行检查。如果输入的键已经过期,那么将输入键从数据库中删除;否则不做任何处理。

    • 定时删除

        过期键的定时删除是由activeExpireCycle函数实现的,每当Redis服务器的周期性操作serverCron函数执行时,activeExpiredCycle函数就会被调用,它在规定的时间内,分多次遍历服务器中的各个数据库,从数据库的expires字典中随机检查一部分键的过期时间,并删除其中的过期键。

        在csdn上面找了一段activeExpireCycle的伪代码

    #默认每次检查的数据库数量
    DEFAULT_DB_NUMBERS = 16
    #默认每个数据库检查的键数量
    DEFAULT_KEY_NUMBERS = 20
    #全局变量,记录检查进度
    current_db = 0
    def activeExpireCycle():
        # 初始化要检查的数据库数量
        # 如果服务器的数据库数量比 DEFAULT_DB_NUMBERS 要小
        # 那么以服务器的数据库数量为准
        if server.dbnum < DEFAULT_DB_NUMBERS:
            db_numbers = server.dbnum
        else:
            db_numbers = DEFAULT_DB_NUMBERS
        # 遍历各个数据库
        for i in range(db_numbers):
            # 如果current_db 的值等于服务器的数据库数量
            # 这表示检查程序已经遍历了服务器的所有数据库一次
            # 将current_db 重置为0 ,开始新的一轮遍历
            if current_db == server.dbnum:
                current_db = 0       
            # 获取当前要处理的数据库
            redisDb = server.db[current_db] 
            # 将数据库索引增1 ,指向下一个要处理的数据库
            current_db += 1 
            # 检查数据库键
            for j in range(DEFAULT_KEY_NUMBERS):
                # 如果数据库中没有一个键带有过期时间,那么跳过这个数据库
                if redisDb.expires.size() == 0: break
                #随机获取一个带有过期时间的键
                key_with_ttl = redisDb.expires.get_random_key()
                # 检查键是否过期,如果过期就删除它
                if is_expired(key_with_ttl):
                    delete_key(key_with_ttl)
                # 已达到时间上限,停止处理
                if reach_time_limit(): return

         activeExpireCycle的处理过程是,每次遍历指定的db数,和每次查询的key的数,如果当前Redis的db_num数量大于默认的db数,则指定的db数为redis的db_num,并且遍历某个db时,会判断当前db有没有键设置过期时间,如果没有一个键设置了过期时间,那么跳过当前数据库;如果当前数据库中的过期key占key的填充率不足1%,则也跳过该数据库;如果当前数据库设置过期时间的key数小于默认的需要查询的key数,则设置当前数据库需要查询的key的数目为当前数据库的过期key的数目,否则随机获取一个带有过期键的key,判断key是否过期,过期则删除,并且进行广播,告诉从库删除,并将del操作写如果aof。    

          

  • 相关阅读:
    android 核心组件( 1 ) 常用布局, adapter, handler, UI
    Android 提高篇 6 之MediaPlayer
    Windows下获取Android系统源码
    Android入门学习笔记之人机用户界面
    Android的三种网络联接方式(URL / HttpURLConnection | HttpClient | InetAddress )
    界面开发的推荐色值, dip,px,pt,sp 的区别
    Android 提高 5 SurfaceView绘图容器的基本使用
    一些腾讯笔试题目
    Android提高篇2 之 Service就是后台程序
    Android提高篇1 之 BroadcastReceiver 应用程序间通信的手段
  • 原文地址:https://www.cnblogs.com/chenyang920/p/13551242.html
Copyright © 2011-2022 走看看