Golang Go语言中开源自己的分布式缓存方案

发布于 1周前 作者 wuwangju 来自 Go语言

Golang Go语言中开源自己的分布式缓存方案

最近整理了一下自己的分布式缓存方案,主要是内存+redis 二级缓存,支持多机同步,目前已经在线上投入使用,经过百万日活的验证。

内存部分是采用的是 sync.Map, 读取缓存的时候先从内存读,如果未读到则去读 redis,如果 redis 未读到,则根据定义的加载函数加载到 redis 和内存。

缓存有 lazy 模式,为了避免缓存被击穿,可以设置 lazy 模式,缓存数据存活的时间更久,但是每次读取的时候依然会判断数据是否是最新的,不是最新的话会异步加载更新。

通过 redis 的 Publish/Subscribe 功能,实现缓存的分布式更新,目前仅实现删除同步。

项目地址 https://github.com/seaguest/cache

欢迎大家批评指正!


更多关于Golang Go语言中开源自己的分布式缓存方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

18 回复

Gopher, Follow 了~

更多关于Golang Go语言中开源自己的分布式缓存方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


多机内存中的数据也会同步?


这个不会,所有机器共享 redis,各自维护自己的内存缓存。
通过 Delete 可以删除所有机器中指定 key 的缓存,可以保障下次该 key 被访问时是最新的数据。

高并发情况下 subscribe 可以保证数据一致么?

正在考虑,直接集成 dragonboat,废了 redis,以实现写少读多场景下的高性能缓存,并真正解决缓存层的强一致问题。


这个之前测过 1000 并发的,主要是读。如果写不是很频繁的话,理论上应该没什么问题。



我这个是轻量级的缓存,主要是以读为主。
更新的话,目前是直接写数据库,然后删除对应的缓存,下次访问缓存未命中直接查询数据库就可得到最新的数据。

我好像也写过一个来着,本机加了一个超时控制,redis 做业务锁控制读写,所以并发还是受限于 redis

可以试试 Redis 新版本的客户端缓存,就不用业务自己写缓存

#8 缓存更新是不是用 Cache Aside Pattern 更好
https://coolshell.cn/articles/17416.html



是的,目前采取的就是这个策略,只不过加了内存->redis 两层。
更新目前直接操作数据库,然后调用 Delete 使其失效。

我也做了一套类似的解决方案,使用 checksum 解决了多节点内存数据不一致的问题~

1000 并发是不是少了一点。。。



这个只是我之前的测试数据,可以更高。
性能的瓶颈在于请求 DB 的相关逻辑以及 redis 的处理能力,如果 DB 查询没什么问题,redis 单机 10 万 QPS 应该都不是问题。

不错,学习下

在Golang(Go语言)生态系统中,开源分布式缓存方案是一个备受关注的话题。Go语言以其高效的并发处理能力、简洁的语法和强大的标准库,非常适合构建高性能的分布式系统,包括分布式缓存。

对于开源的分布式缓存方案,Redis和Memcached是两个非常流行的选择,尽管它们并非直接用Go语言编写,但Go语言有丰富的客户端库支持,使得在Go项目中集成这些缓存系统变得非常方便。

然而,如果你希望在Go语言生态中寻找一个更贴近的开源分布式缓存解决方案,可以考虑以下一些项目:

  1. Groupcache:由Google开发的一个简单的分布式缓存系统,它使用Go语言编写,并支持自动失效和内存管理等特性。

  2. Badger:一个快速的键值存储,由Dgraph团队开发。虽然它主要用于持久化存储,但也可以用作分布式缓存的一部分,提供高性能的读写操作。

  3. GCache:一个用Go语言编写的本地缓存库,虽然它本身不是分布式缓存,但可以通过集群部署和适当的同步机制实现分布式缓存的功能。

在选择和使用这些开源方案时,建议根据项目的具体需求、性能要求以及团队的熟悉程度来决定。同时,也需要注意开源项目的维护情况和社区支持,以确保所选方案的可靠性和长期可用性。

总的来说,Go语言生态中不乏优秀的开源分布式缓存方案,选择适合自己项目的方案将有助于提高系统的性能和可靠性。

回到顶部