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

本文将主要讲述Ristretto的存储策略的实现方式。

题外话:Ristretto 意为“意式特浓咖啡”,感觉在跟java实现的”caffine(咖啡因)“叫板,HAHAHA。。。咯

确定存储结构

golang中的map是非并发安全的,要实现并发安全,有三种常用策略:加锁,sync.Map, 分片字典。对于三种策略有如下的分析:

加锁:要缓存的数据,绝对是频繁访问的数据,加锁必然影响性能,失去了缓存的意义,所以加锁是下策。

sync.Map:sync.Map 内部通过两个map+锁(本质上还是缓存+锁),实现了并发安全,但是对于读写都多的场景,性能依然堪忧,此乃中策。

分片字典:分片字典的是将数据散列在多个map中,尽量降低数据出现竞态的概率。对于其中每一个map还是采用加锁策略。在读多写多的场景中,也有较好的表现,此乃上策。

Ristretto中的分片字典

为了实现并发安全且高性能的存储需求,Ristretto使用了分片字典策略。

在Ristretto中与存储有关的数据结构,如下(省略了部分信息):

type shardedMap struct {shards       []*lockedMap  // map类型的slice。共256个...
}type lockedMap struct {sync.RWMutex                // 每个分片的map,包含独立的锁data         map[uint64]storeItem // ...
}type storeItem struct {     // map 中存储的数据类型key        uint64conflict   uint64value      interface{}...
}

新增一个Key

以 key为string, value 为结构体为例:

key :=  "ZHH"
value := PeosonInfo{FallName : "ZhaoHaihang",Phone : "13112341234",Age : 18,Addres : "XXXXX",}

整体流程:

key 先经过keyToHash()得到 keyHash 和conflictHash,通过keyHash %256 确定该key应该存在哪一个lockedmap中, 存之前先判断key是不是已经在里面,如果已经在了走更新逻辑,否则走新增逻辑。

详细流程:

结合代码看详细的流程是最清晰的。

  1. 首先调用cache.go中的Set()函数:

其中参数cost表示存储该key的代价,可暂时忽略
2. 接着内部调用了SetWithTTL():

其中参数ttl为该key的过期时间,可暂时忽略。(Ristretto是支持设置key的过期时间的,有关过期策略的具体实现,准备放在下一篇文章,敬请期待)

3. 继续调用setInternal():

onlyUpdata仅作为一个功能开关,只与更新有关,可暂时忽略。
keyToHash()得到的两个值,可以简单看作是两种hash函数得到的值,第二个是为了解决哈希冲突存在的。图中… 表示一些不涉及主要逻辑的省略 (ps:对于两个key,使用两种哈希函数的得到相同结果的概率是极低的)。

4. 在初始化时,会启动一个协程执行processItems()函数。在函数中不断从第三步中提到的setBuf取数据,并根据操作类型执行相应的逻辑。新增的逻辑为c.store.Set()


5. 接着来到store.go中的Set()函数:

Set() 主要用于根据keyToHash获得的keyHash,并通过取模确定Key应该在具体的哪一个LoackedMap。其中numShards为常量=256。即整个shards中包含256个LoadckedMap。

此处要注意区分几个key不同的含义,不要混淆。


6. 最后来到lockedMap的Set()函数:
此处是最终写操作执行的地方。
同时此处有个问题:刚才说在第三步中updata函数已经判断了一次key是否存在,为何这里要再次判断?
答:在并发的情况下,刚才判断的结果,已经不能保证是最新的结果了。无法保证是不是有其他协程抢先写了一条数据,所以要加锁后,再次判断。

最后,如果能明白插入操作是怎么运行的 ,相信对于明白读、更新、删除的流程就非常容易了,也大致是这个过程,这里就不再赘述了。

写在最后:本人能力有限,如果有错误之处,还望各位及时指正,谢谢!

高性能本地缓存Ristretto(一)——存储策略相关推荐

  1. 高性能本地缓存Ristretto(二)——过期策略

    ristretto提供了SetWithTTL()方法,支持创建key的同时,并设置一个过期时间. ristretto 利用嵌套的map结构,并结合巧妙的存储方式,实现了对每一个key的过期时间的管理. ...

  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. 【微信小程序3】本地缓存:一次性存储多个对象值

    一.缓存介绍 每个微信小程序都有自己的本地缓存.同一个微信用户,同一个小程序 storage 上限为 10MB.localStorage 以用户维度隔离,同一台设备上,A 用户无法读取到 B 用户的数 ...

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

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

  7. ehcache缓存原理_干掉GuavaCache:Caffeine才是本地缓存的王

    话说,中间件的选择上,Spring(SpringBoot)一直是业界的风向标.比如Spring一直使用「Jackson」,而没有使用Gson和fastjson.SpringBoot2.0默认数据库连接 ...

  8. Java本地缓存框架系列-Caffeine-1. 简介与使用

    Caffeine 是一个基于Java 8的高性能本地缓存框架,其结构和 Guava Cache 基本一样,api也一样,基本上很容易就能替换. Caffeine 实际上就是在 Guava Cache ...

  9. Java8本地缓存Caffeine

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

最新文章

  1. 调用另一个python文件中的代码
  2. C++读取配置文件的写法
  3. openfire修改服务器名称方法
  4. .NET Core中异常过滤器ExceptionFilter的使用介绍
  5. [HDU 4666]Hyperspace[最远曼哈顿距离][STL]
  6. Mr.J--C语言经典编程100例
  7. D3 BarChart
  8. 免费手机电脑同屏神器——Mirroid
  9. 7.20 - 每日一题 - 408
  10. android 磁贴布局,拼图酱 - 通过布局、磁贴、滤镜等元素重新组合照片,充满乐趣 - Android 应用 - 图像 - 【最美应用】...
  11. X86 CPU 漏洞 Meltdown 原理及google攻击代码
  12. oracle dbms_lob trim,DBMS_LOB
  13. vs 的 tfs 账号更改
  14. 【C语言程序设计】基本算术运算
  15. 解决Dmaven.multiModuleProjectDirectory system propery is not set. Check M2_HOME错误
  16. GOPATH 与工作空间
  17. 舒尔特注意力训练网页版
  18. 启动mysql报错:mysql.service: Service hold-off time over, scheduling restart
  19. 统一数据交换(UDX)
  20. Android实现联动下拉框

热门文章

  1. c语言sscanf函数和结构体,C语言sprintf与sscanf函数 -电脑资料
  2. java面向对象(封装、重载、构造、继承)
  3. afrog的安装与使用
  4. 线性关系和非线性关系异或与非线性关系
  5. 2021-06-28国外调查问卷真的赚钱吗
  6. java jodd框架介绍及使用示例
  7. 淘宝客运营推广技巧方法有哪些?
  8. 小学生机器人编程是学的什么
  9. Go+ 发布 weekly release: v0.7.3
  10. 今天公开猎头顾问业绩过百万的秘密,谷露猎头系统3.0版谍报速递