ristretto提供了SetWithTTL()方法,支持创建key的同时,并设置一个过期时间。
ristretto 利用嵌套的map结构,并结合巧妙的存储方式,实现了对每一个key的过期时间的管理。并能在时间到期后,尽快的删除过期的key,以节省资源开销。

过期时间的存储结构

ristretto采用嵌套的map结构记录key以及对应的过期时间,如下所示:

type shardedMap struct {...expiryMap    *expirationMap  // expirationMap 是全局共享的...
}type expirationMap struct {...buckets map[int64]bucket    //  buckets的value也是map
}type bucket map[uint64]uint64    // bucket 本质上是一个map结构

对于以上结构buckets的key是时间戳。bucket中的key和 value则 分别存储是keyHash和conflictHash值(对于这两个值如何得到的,请参考上一篇文章高性能本地缓存Ristretto(一)——存储策略)。这么干说可能有点懵逼,举个例子,画个图可能更形象。

假如有 key = “ZHH” value= “ZhaoHaihang” 需要缓存,并且要设置过期时间为5秒。通过keyToHash()对key做hash得到keyHash= “666" 和 conflictHash=“888”,并且现在的时间戳为1000。则最终该结构会以如下图的方式存储:

其中,1005为key = “ZHH” value= “ZhaoHaihang” 这条数据的过期时间戳。1005对应的value为bucket2,因此bucket2中的key、value分别为666,888

过期时间的存储策略

仔细考虑可以发现,上面的存储方式可能还有些可优化的地方。我们真的需要将key按每一秒划分bucket吗?如果按每5秒 划分为一个bucket是不是也行呢?

比如,在10秒钟内,每一秒存了1个key。时间戳分别为1000 - 1010,key分别为A-J,每个key的过期时间为5s,则key与之对应的过期时间戳为:

体现在内存中存储结构就变成了如下图所示:

图中,对每一个时间戳除5取整,得到buckets中的key,然后将keyHash 和conflictHash 分别作为bucket的key和value。

具体流程

对大概的存储方式有一定了解后,再结合代码看具体的流程就非常容易了,同时对于key如何过期的就能了解的更清楚。

接下来将以写缓存为例,详细梳理,key的过期时间的存储方式,和删除过期key的方法。

存储key过期时间的流程

  1. 调用SetWithTTL()函数,在写缓存的同时为key设置一个过期时间。以秒为单位。

    图中,参数ttl即为过期时间。并在内部调用setInternal()

  2. setInternal()函数中,对通过ttl 计算key的过期时间戳,并记录在Item中,最终进入setBuf


3. 另外一个协程执行processItems(),从setBuf中取Item,根据不同的操作类型,执行不同的操作。

  1. Set() 中会在增加一条key的过期时间的数据。

  2. add() 先通过 storeBucket() 计算该时间戳应该是哪个bucket,之后将key 和 confict写入bucket就行了。

    storeBucket()中,就是通过将时间戳除5得到一个数值的。

如何删除过期了的key

已经知道了怎么存储过期时间,现在来看看过期的key是怎么被删除的吧。

  1. 首先回到processItems()函数,里面有个定时器,会定时的执行CleanUp() 函数。


该定时器是在初始化的时候就设置好的:

可以发现,定时周期为 bucketDurationSecs / 2,还记得bucketDurationSecs 是多少吗?没错!是5,因此定时周期为2s,即每2秒就会执行一次清理任务。

  1. Cleanup() 通过简单的封装,继续执行cleanup().
  2. 在cleanup() 中,执行最终的删除操作。

cleanupBucket() 返回的是storageBucket() -1 ,即5秒前过期的key,这样就不会误删还没有过期的key。

至此,删除过期key的流程就执行完了。

现在,终于可以明白,为什么要以5秒为一个单位记录key,如果以每一秒,那删除操作的频率会很高,这显然是大可不必的。

链接

高性能本地缓存Ristretto(一)——存储策略

高性能本地缓存Ristretto(二)——过期策略相关推荐

  1. 高性能本地缓存Ristretto(一)——存储策略

    Ristretto是Dgraph基于golang实现的一个高性能的本地缓存库.特点是高命中率,高吞吐量,可自定义存储成本,支持一些自定义回调函数,并提供了较多的统计信息. 本文将主要讲述Ristret ...

  2. 高性能本地缓存Ristretto(三)——淘汰策略

    之前提到过,缓存即 存储 和 淘汰策略.一个好的淘汰策略,对于提升命中率起着至关重要的作用.一般常用的淘汰策略有,LRU.LFU.TinyLFU以及Window-TinyLFU (讲解LRU.LFU. ...

  3. Java高性能本地缓存框架Caffeine

    文章目录 Java高性能本地缓存框架Caffeine 如何使用 缓存加载 手动加载 自动加载 手动异步加载 自动异步加载 过期策略 基于大小 基于时间 基于引用 Caffeine.weakKeys() ...

  4. 「GoCN酷Go推荐」高性能内存缓存 ristretto

    背景 ristretto 是 dgraph 团队开源的一款高性能内存缓存库,旨在解决高并发场景下的缓存性能和吞吐瓶颈.dgraph 专攻的方向是高性能图数据库,ristretto 就是其图数据库和 K ...

  5. 转:基于AOP实现Ibatis的缓存配置过期策略

    一.上篇回顾 自从上次<网站性能优化之应用程序缓存-中篇>得到不少园友的支持和鼓励,并且提出了不错的思路来实现我们中篇中提到的缓存策略,那么我将会结合.NET 本身内置 的AOP的方式来跟 ...

  6. Java8本地缓存Caffeine

    文章目录 一.Caffeine介绍 1.缓存介绍 2.Caffeine介绍 二.Caffeine基础 1.缓存加载策略 1.1 Cache手动创建 1.2 Loading Cache自动创建 1.3 ...

  7. 本地缓存王者,Caffeine 保姆级教程!给力...

    缓存(Cache)在代码世界中无处不在.从底层的CPU多级缓存,到客户端的页面缓存,处处都存在着缓存的身影.缓存从本质上来说,是一种空间换时间的手段,通过对数据进行一定的空间安排,使得下次进行数据访问 ...

  8. 干掉GuavaCache:Caffeine才是本地缓存的王

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入新技术 话说,中间件的选择上,Spring(SpringBoot)一直是业 ...

  9. 干掉 GuavaCache:Caffeine 才是本地缓存的王

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 话说,中间件的选择上,Spring(SpringBoot ...

最新文章

  1. java的final修饰_java final 修饰符详解
  2. 使用Levmar的L-M算法拟合曲线
  3. java mysql 二级缓存_深入理解MyBatis中的一级缓存与二级缓存
  4. Android开发笔记(四十九)异步任务处理AsyncTask
  5. iOS 使用iPhone配置实用工具 创建桌面快捷方式
  6. debain下装memcached
  7. 自定义linux桌面,教您6个自定义Ubuntu桌面的步骤
  8. opencv--轮廓拟合函数 boundingRect(),minAreaRect(),minEnclosingCircle(),fitEllipse(),fitLine()
  9. 惠而浦将斥资30亿美元收购艾默生电气旗下爱适易;高通和格芯签署一项长期制造协议 | 美通企业日报...
  10. C++蜜蜂的爬行路线
  11. Vue3使用路由及配置vite.alias简化导入写法
  12. 极智AI | 一文看懂昇腾达芬奇架构计算单元
  13. 如何做好基于地图的数据可视化?
  14. 多投影完美拼接——边缘融合投影技术
  15. c语言不用strcpy复制字符串,c语言程序(二十三)——字符串复制(不使用strcpy()函数)...
  16. 微信开发者工具 网络连接失败
  17. kafka基础入门(4):kafka消费者
  18. EBS 修改系统名称
  19. html——标签分类
  20. android数据库降级_Android 数据库版本降低时的操作

热门文章

  1. 云原生--k8s基础管理命令(二)
  2. 计算网络节点的平均度
  3. hcie 论述-mpls lsp
  4. 华清远见第一周学习体会
  5. 小程序开发之瀑布流布局
  6. syntax error, expect {, actual error, pos 1, fastjson-ve
  7. ETCD数据库源码分析——Cluster membership changes日志
  8. Big Mart Sales:预测销售结果 |Python
  9. 网络安全--keytool CA签名SSL证书(收费)
  10. 有生之年,被FCoin坑到底?