2 个版本
0.1.0-surreal.2 | 2023年7月22日 |
---|---|
0.1.0-surreal.1 | 2023年6月19日 |
在 数据库接口 中排名 2845
每月下载量 99
被 2 crates 使用
73KB
202 行
TiKV 客户端 (Rust)
本 crate 为 TiKV(>= v5.0.0
)集群提供易于使用的客户端,TiKV 是一个用 Rust 编写的分布式、事务性键值数据库。
本 crate 允许您连接到 TiKV 集群,并使用事务性或原始(简单 get/put 风格,不保证事务一致性)API 访问和更新数据。
TiKV Rust 客户端是一个由 TiKV 作者维护的开源(Apache 2)项目。我们欢迎贡献,更多信息见下文。
请注意,当前版本不适合生产使用 - API 尚未稳定,crate 还未在实际使用中进行彻底测试。
入门
TiKV 客户端是一个 Rust 库(crate)。要在项目中使用此 crate,请将以下依赖项添加到您的 Cargo.toml
[dependencies]
tikv-client = "0.3"
先决条件
rust
>=1.56.1
,需要hashbrown-v0.12.1
使用客户端crate的一般流程是创建一个原始或事务客户端对象(可以进行配置),然后使用客户端对象发送命令,或者用它来创建事务对象。在后一种情况下,事务是通过各种命令构建的,然后提交(或回滚)。
示例
原始模式
use tikv_client::RawClient;
let client = RawClient::new(vec!["127.0.0.1:2379"], None).await?;
client.put("key".to_owned(), "value".to_owned()).await?;
let value = client.get("key".to_owned()).await?;
事务模式
use tikv_client::TransactionClient;
let txn_client = TransactionClient::new(vec!["127.0.0.1:2379"], None).await?;
let mut txn = txn_client.begin_optimistic().await?;
txn.put("key".to_owned(), "value".to_owned()).await?;
let value = txn.get("key".to_owned()).await?;
txn.commit().await?;
由于TiKV客户端提供了一个异步API,您需要使用异步运行时(我们目前仅支持Tokio)。有关完整示例,请参阅getting-started.md。
API摘要
TiKV Rust客户端支持多个抽象级别。使用客户端最方便的方式是通过RawClient
和TransactionClient
。这提供了一个非常高级的API,主要抽象了存储的分布式特性,并为所有协议提供了合理的默认值。此接口可以进行配置,主要是在创建客户端或事务对象时通过Config
和TransactionOptions
结构体进行。使用某些选项,您可以自己接管协议的部分(如重试失败的消息)。
最低级别的抽象是直接创建和发送gRPC消息到TiKV(和PD)节点。`tikv-client-store`和`tikv-client-pd`crate使这比直接使用protobuf定义和gRPC库更容易,但给您相同的控制级别。
在这些抽象级别之间,您可以向TiKV集群发送和接收单个消息,但可以利用库代码执行常见操作,如将数据解析到区域并因此到集群中的节点,或者重试失败的消息。这对于测试TiKV集群或某些高级用例可能很有用。请参阅此API的`client_rust::request
`模块,以及`client_rust::raw::lowering
`和`client_rust::transaction::lowering
`模块以获取创建请求对象的便捷方法。
本文档的其余部分仅描述RawClient
/TransactionClient
API。
重要提示:不建议或支持在同一个数据库上同时使用原始和事务API。
类型
Key
:存储中的键。`String
`和`Vec<u8>
`实现了`Into<Key>
`,因此您可以直接将它们传递到客户端函数中。
Value
:存储中的值;只是`Vec<u8>
``的别名。
KvPair
:一个键(`Key
`)和一个值(`Value
`)的配对。它提供了方便的方法来转换到和从其他类型。
BoundRange
:用于与范围相关的请求,如scan
。它实现了Rust范围上的From
,因此您可以将Rust范围键传递到请求中,例如:client.delete_range(vec![]..)
。
原始请求
请求 | 主要参数类型 | 结果类型 | 值得注意的行为 |
---|---|---|---|
put |
KvPair |
||
get |
Key |
Option<Value> |
|
delete |
Key |
||
delete_range |
BoundRange |
||
scan |
BoundRange |
Vec<KvPair> |
|
batch_put |
Iter<KvPair> |
||
batch_get |
Iter<Key> |
Vec<KvPair> |
跳过不存在的键;不保留顺序 |
batch_delete |
Iter<Key> |
||
batch_scan |
Iter<BoundRange> |
Vec<KvPair> |
请参阅each_limit 参数行为文档。范围顺序被保留。 |
batch_scan_keys |
Iter<BoundRange> |
Vec<Key> |
请参阅each_limit 参数行为文档。范围顺序被保留。 |
compare_and_swap |
Key + 2x Value |
(Option<Value>, bool) |
事务性请求
请求 | 主要参数类型 | 结果类型 | 值得注意的行为 |
---|---|---|---|
put |
KvPair |
||
get |
Key |
Option<value> |
|
get_for_update |
Key |
Option<value> |
|
key_exists |
Key |
bool |
|
delete |
Key |
||
scan |
BoundRange |
Iter<KvPair> |
|
scan_keys |
BoundRange |
Iter<Key> |
|
batch_get |
Iter<Key> |
Iter<KvPair> |
跳过不存在的键;不保留顺序 |
batch_get_for_update |
Iter<Key> |
Iter<KvPair> |
跳过不存在的键;不保留顺序 |
lock_keys |
Iter<Key> |
||
send_heart_beat |
u64 (TTL) |
||
gc |
时间戳 |
bool |
如果PD中最新的safepoint等于参数,则返回true |
开发和贡献
我们欢迎您的贡献!贡献代码是很好的,我们也赞赏提交问题以识别错误和提供反馈,添加测试或示例,以及改进文档。
构建和测试
我们使用标准的Cargo工作流程,例如,使用cargo build
进行构建和使用cargo test/nextest
运行单元测试。您需要使用nightly Rust工具链来构建和运行测试。可以使用nextest来加速ut,首先安装nextest。
cargo install cargo-nextest --locked
运行集成测试或手动使用TiKV集群测试客户端稍微复杂一些。最简单的方法是使用TiUp(>= 1.5)在本地机器上初始化集群
tiup playground nightly --mode tikv-slim
然后如果您想运行集成测试
PD_ADDRS="127.0.0.1:2379" cargo test --package tikv-client --test integration_tests --features integration-tests
创建PR
我们使用标准的GitHub PR工作流程。我们对每个PR运行CI,并要求所有PR在构建时无警告(包括clippy和Rustfmt警告),通过测试,具有DCO签名(在提交时使用-s
,DCO机器人将引导您完成首次PR的DCO协议),并且至少有一个审阅。如果您发现这很困难,请不要担心,在PR上提出问题。
为了在本地运行类似CI的测试,我们建议您在提交PR之前运行cargo clippy
、cargo test/nextest run
和cargo fmt
。有关运行集成测试,请参阅上面,但您可能不需要担心您的第一次几个PR。
请遵循PingCAP的Rust风格指南。所有代码PR应包括新的测试或测试用例。
寻求帮助
如果您需要帮助,无论是寻找可以工作的事情,还是遇到任何技术问题,最简单的方法是通过 internals.tidb.io,这是 TiDB 开发者的论坛。
您也可以在 Slack 上提问。我们监控 tikv-wg slack 上的 #client-rust 频道。
您可以直接在 GitHub 的问题或 PR 中提问;如果没有得到回复,您应该 ping @ekexium 或 @andylokandy。
依赖项
~41MB
~795K SLoC