1 个不稳定版本
0.1.0 | 2023年11月26日 |
---|
#7 在 #shard
在 groupcache 中使用
23KB
345 行
groupcache
这是将一个流行的分布式缓存库从 Go groupcache 迁移到 Rust 的版本。
groupcache 是一个分布式缓存和缓存填充库,通常用作多个情况下 memcached 节点池的替代品。它通过键进行分片来选择哪个节点负责该键。
与原始实现的比较
- 使用 Rust 实现,因此速度极快。但实际上,我还没有进行过任何严肃的基准测试。
- 没有实现组(这让我怀疑
groupcache
的名称是否仍然合理)。- 如果需要这样的功能,可以通过根据键前缀有不同的
ValueLoader
实现,在库的顶部实现。 - 然而,在这种情况下,所有指标都会一起汇总,并且无法为每个组定制缓存。这可能是未来版本中需要考虑的事情。
- 如果需要这样的功能,可以通过根据键前缀有不同的
- 服务发现 API 略有不同
- 与原始实现相比,API 允许添加和移除节点,而不是一次性添加所有节点(从而使先前添加的节点无效)。
- 仍然没有实现 CAS、增减操作,但支持缓存失效。
- 必须小心处理来自
hot_cache
的过时值,请参阅Options
的文档。
- 必须小心处理来自
与 memcached 的比较(来自原始仓库)
与 memcached 一样,groupcache
通过键进行分片来选择哪个节点负责该键。与 memcached 不同,groupcache
-
不需要运行一组单独的服务器,从而大大减少了部署/配置的麻烦。groupcache 既是客户端库也是服务器。它连接到自己的节点,形成一个分布式缓存。
-
带有缓存填充机制。而 memcached 只说“抱歉,缓存未命中”,通常会导致大量来自无界数量的客户端(这已导致几次有趣的故障)的数据库(或任何)负载,groupcache 协调缓存填充,以确保整个复制进程集中的单个进程中的一个加载操作填充缓存,然后多路复用加载的值到所有调用者。
-
不支持版本值。如果键
"foo"
的值是"bar"
,则键"foo"
必须始终是"bar"
。没有缓存过期时间,也没有显式的缓存淘汰。因此,也没有CAS、增加/减少操作。这也意味着groupcache.... -
... 支持将超级热门项自动镜像到多个进程中。这可以防止memcached热点,即机器的CPU和/或NIC因非常热门的键/值而过载。
-
目前仅适用于Go。我不太可能将代码移植到任何其他语言。
加载过程
简而言之,对 Get("foo")
的 groupcache 查找如下所示
(在运行相同代码的N台机器中的一台机器#5)
-
"foo"
的值是否在本地内存中,因为它非常热门?如果是,则使用它。 -
"foo"
的值是否在本地内存中,因为对等方#5
(当前对等方)拥有它?如果是,则使用它。 -
在我的N个对等方中,我是键
"foo"
的所有者吗?(例如,它是否一致哈希到5?)如果是,则加载它。如果其他调用者通过相同的过程或通过来自对等方的RPC请求进入,它们将阻塞等待加载完成并获得相同的答案。如果不是,则通过所有者是所有者的对等方进行RPC并获取答案。如果RPC失败,则仅在本地加载(仍然具有本地重复抑制)。
示例
- 有一个示例展示了如何在k8s上部署一个简单的axum服务器的同时运行groupcache,请参阅 examples/kubernetes-service-discovery。
文档
请参阅 https://docs.rs/groupcache 和 https://docs.rs/groupcache/struct.Groupcache.html
依赖关系
~4.5–6.5MB
~108K SLoC