#bigtable #request #google #google-service #client #protobuf #grpc

bigtable_rs

一个非常简单的Rust语言Google Bigtable客户端库

19次发布

0.2.10 2024年4月14日
0.2.9 2024年3月26日
0.2.6 2023年11月18日
0.2.5 2023年2月21日
0.1.4 2021年2月6日

#810 in Web编程

Download history 741/week @ 2024-04-28 815/week @ 2024-05-05 737/week @ 2024-05-12 944/week @ 2024-05-19 744/week @ 2024-05-26 1041/week @ 2024-06-02 902/week @ 2024-06-09 937/week @ 2024-06-16 719/week @ 2024-06-23 731/week @ 2024-06-30 991/week @ 2024-07-07 683/week @ 2024-07-14 825/week @ 2024-07-21 929/week @ 2024-07-28 1027/week @ 2024-08-04 969/week @ 2024-08-11

3,785 每月下载量
3 crates 中使用

MIT 许可证

290KB
3.5K SLoC

bigtable_rs

一个用于与Google Bigtable 数据API V2 操作的简单Rust库。

ci_badge Crates.io Documentation Crates.io

免责声明 - 可能已准备好投入生产使用

此库可能已准备好投入生产使用。任何贡献或帮助都将非常感激。

我有了构建此类客户端的想法,并从其他人那里得到了一些反馈,请参见 此处,并从此处移植代码(感谢 @mvines)。

读取行解析 逻辑是通过将Google的Java客户端 测试代码json测试用例 作为原始输入进行移植来测试的。

简介

当前的想法是使这个库非常轻量,您可以根据 Google Bigtable V2 protobuf模式 组装请求,并通过 tonic gRPC over HTTP/2 发送请求。因此,用户可以创建任何类型的Bigtable请求,并使用此客户端与Bigtable服务进行通信。

包含在仓库中的编译后的Bigtable API proto作为Rust代码,因此用户无需再次从proto编译。

此库将解析来自Bigtable的返回行值。

支持Bigtable的接口

对于其他gRPC API/方法,可以直接使用gRPC客户端,并通过构建Protobuf消息(已编译为rs文件并包含在此处)来组装与Bigtable服务交互所需的请求。

gcp_auth被使用,它支持

  • 应用程序默认凭证
  • 通过Google服务账户密钥json文件进行连接认证(通过设置环境参数GOOGLE_APPLICATION_CREDENTIALS=path/to/key.json
  • 通过从gcloud元数据服务器获取令牌来检索默认服务账户

您可以使用库如下

[dependencies]
bigtable_rs = "0.2.10"
tokio = { version = "1.0", features = ["rt-multi-thread"] }
env_logger = "0.11.1"

文档在crate.io。请参阅示例文件夹以获取更多示例。以下示例演示了如何进行键范围扫描

use bigtable_rs::bigtable;
use bigtable_rs::google::bigtable::v2::row_filter::{Chain, Filter};
use bigtable_rs::google::bigtable::v2::row_range::{EndKey, StartKey};
use bigtable_rs::google::bigtable::v2::{ReadRowsRequest, RowFilter, RowRange, RowSet};
use env_logger;
use std::error::Error;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    env_logger::init();

    let project_id = "project-id";
    let instance_name = "instance-1";
    let table_name = "table-1";
    let channel_size = 4;
    let timeout = Duration::from_secs(10);

    let key_start: String = "key1".to_owned();
    let key_end: String = "key4".to_owned();

    // make a bigtable client
    let connection = bigtable::BigTableConnection::new(
        project_id,
        instance_name,
        true,
        channel_size,
        Some(timeout),
    )
        .await?;
    let mut bigtable = connection.client();

    // prepare a ReadRowsRequest
    let request = ReadRowsRequest {
        table_name: bigtable.get_full_table_name(table_name),
        rows_limit: 10,
        rows: Some(RowSet {
            row_keys: vec![], // use this field to put keys for reading specific rows
            row_ranges: vec![RowRange {
                start_key: Some(StartKey::StartKeyClosed(key_start.into_bytes())),
                end_key: Some(EndKey::EndKeyOpen(key_end.into_bytes())),
            }],
        }),
        filter: Some(RowFilter {
            filter: Some(Filter::Chain(Chain {
                filters: vec![
                    RowFilter {
                        filter: Some(Filter::FamilyNameRegexFilter("cf1".to_owned())),
                    },
                    RowFilter {
                        filter: Some(Filter::ColumnQualifierRegexFilter("c1".as_bytes().to_vec())),
                    },
                    RowFilter {
                        filter: Some(Filter::CellsPerColumnLimitFilter(2)),
                    },
                ],
            })),
        }),
        ..ReadRowsRequest::default()
    };

    // calling bigtable API to get results
    let response = bigtable.read_rows(request).await?;

    // simply print results for example usage
    response.into_iter().for_each(|(key, data)| {
        println!("------------\n{}", String::from_utf8(key.clone()).unwrap());
        data.into_iter().for_each(|row_cell| {
            println!(
                "    [{}:{}] \"{}\" @ {}",
                row_cell.family_name,
                String::from_utf8(row_cell.qualifier).unwrap(),
                String::from_utf8(row_cell.value).unwrap(),
                row_cell.timestamp_micros
            )
        })
    });

    Ok(())
}


尝试示例代码

要开始开发或测试上述示例代码,如果您尚未安装,请安装cbt工具,然后启动一个本地测试Bigtable实例并插入一些测试数据,如下所示

# at one terminal, start a bigtable insatnce locally
. start_bigtable_local.sh

# at another terminal, load some data into it
. start_load_table_local.sh

然后使用以下命令运行示例

BIGTABLE_EMULATOR_HOST=localhost:8086 RUST_LOG=bigtable_rs=trace cargo run --bin simple_read

如果您看到与Google身份验证或gcp项目找不到相关的错误,请记住设置环境参数BIGTABLE_EMULATOR_HOST=localhost:8086,以便让示例客户端连接到本地模拟器。

要针对真实Bigtable实例运行

GOOGLE_APPLICATION_CREDENTIALS=<path_to_key>/service_account_key.json cargo run --bin simple_read

或者,如果您想使用您的gcloud auth login身份验证,只需运行客户端而不需要任何特殊环境设置

cargo run --bin simple_read

请参阅examples文件夹以获取更多示例。

开发

克隆此存储库,如果需要,请检出子模块

cd googleapis
git submodule init
git submodule update

然后检出bigtable_rs/src/build.rs以更新Google protos

运行测试

cargo test -- --nocapture
rustup component add llvm-tools-preview
cargo install grcov
mkdir -p target/coverage/html

CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' cargo test

grcov . --binary-path ./target/debug/deps/ -s . -t html --branch --ignore-not-existing --ignore '../*' --ignore "/*" --ignore "bigtable_rs/src/google/*" --keep-only "bigtable_rs/src/*" -o target/coverage/html

依赖项

~20–33MB
~640K SLoC