#缓存 #性能 #服务 #数据结构

rmemstore

rmemstored 客户端

1 个不稳定版本

0.1.1 2024 年 8 月 12 日

网页编程 中排名第 1600

Download history 118/week @ 2024-08-10

每月下载量 118

Apache-2.0

28KB
417 代码行

rmemstore

快速、类型感知的数据结构缓存。

关于

rmemstore 类似于您可能使用过的其他缓存,如 redis,但它有一些不同之处。rmemstore 的主要目标是成为类型安全、快速且作为数据结构缓存有用的。

当然,实用性是一个持续的过程,因为功能的发展需要时间。但是,rmemstore 是一个类型感知的数据结构存储,这意味着您可以存储映射的映射 - 服务器知道这意味着什么。

现在它已经很快了。当需要淘汰时,rmemstore 使用新的筛子淘汰策略。在 10:1 的读:写比例下,2 个线程在 11 年前的英特尔 i5 服务器上能够每秒超过 330 万次操作。即使在被推到淘汰的情况下。

rmemstore 基于 "安全" Rust 代码构建。它不依赖于微妙的技巧来获得速度。它确实使用了标准库,如出色的 tokio,它可能使用了暗黑魔法,但它们是可靠的。

rmemstore 使用裸 TCP - 没有应用框架。您的网卡向或从 rmemstored 服务器发送的每个 0 和每个 1 都有一个直接的目的。当有合适的替代品时,发明一个新的看似可移植的线协议是一种模糊的虚荣练习。考虑到这一点,rmemstore 使用 protosockets,这是上述虚荣与实用主义之间的折衷。

协议

指向 rmemstored 的 TCP 流是一系列标准、长度分隔的协议缓冲区 rmemstore.Rpc 结构。这些消息携带一个 ID,而 rmemstored 使用该 ID 响应 - 可能是无序的。它是一个多线程、多路复用的服务器。您可以在网络和 CPU 能力的限制下尽可能快地发送尽可能多的数据。

rmemstored 流出的 TCP 流是一系列标准、长度分隔的协议缓冲区 rmemstore.Response 结构。这些消息携带初始化响应的 Rpc 的 ID。每个 rmemstore.Rpc 都有一个相应的 rmemstore.Response

入站和出站流都是:varint message varint message[...]. 消息前的 varint 是消息的长度。因此,一旦你读取了 varint 的字节和长度,你就有了完整的消息。

语言

Rust

你可以查看 rmem,了解如何使用客户端。使用方法简化为3行。

let mut configuration = rmemstore::ClientConfiguration::new();
let client = configuration.connect(args.host.to_string()).await?;
client.put("some key", "some value").await?;

你还可以放置字典

client.put(
    "some key",
    HashMap::<&str, &str>::from_iter([
        ("hello", "world")
    ]),
).await?;

或字符串和字典的字典,只要你愿意

client
    .put(
        "some key",
        HashMap::<&str, MemstoreValue>::from_iter([
            (
                "hello",
                MemstoreValue::String {
                    string: "world".to_string(),
                },
            ),
            (
                "nested",
                MemstoreValue::Map {
                    map: HashMap::from_iter([(
                        "inner".to_string(),
                        MemstoreValue::String {
                            string: "values".to_string(),
                        },
                    )]),
                },
            ),
        ]),
    )
    .await?;

Bash

你可以使用 rmem 来放置和获取。

对于字符串,输出会更简洁。

$ rmem put foo `{"string": "some value"}`
$ rmem get foo
some value

对于映射,交互会有一些冗长,但它是有类型的!

$ rmem put foo '{"map": {"bar":{"map":{"baz":{"string": "haha"}, "other": {"string": "verbose"}}, "outer": {"string": "another"}}}}'
$ rmem get foo
{
  "bar": {
    "map": {
      "baz": {
        "string": "haha"
      },
      "other": {
        "string": "verbose"
      }
    }
  }
}

Python

不想使用 Rust?任何能够通过 tcp 发送和接收协议缓冲区编码字节的工具或语言都可以使用 rmemstored。请参阅 example-python,了解另一种语言中的示例。请注意,由于 Python 没有公开 protobuf varint 编码器,Python 会有些痛苦。

依赖项

~4–15MB
~169K SLoC