热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用towergRPC

使用towergRPC,Go语言社区,Golang程序员人脉社

在 TiKV 里面,我们使用的是 grpc-rs,这是我们自己维护的一个 Rust gRPC 库,主要是使用 Future 这个特性,封装了 Google 的 C gRPC,对外提供了一套易于使用的同步编程的接口。

但 grpc-rs 并不是 pure Rust,而且 C gRPC 的性能其实并不好,加上在生产环境中碰到过几次 C gRPC panic,我们一直有打算完全拥抱 Rust 社区,用一个纯 Rust 的 gRPC 实现(以前也想过自己造轮子,但发现坑太大,就算了)。现阶段,有两个现成的,一个是 grpc-rust,而另一个则是 tower-grpc。grpc-rust 在最开始我们开发 grpc-rs 的时候,尝试过一段时间,不过接上去之后异常的不稳定,所以放弃了,后来也一直没有尝试,现在不知道改善了没有。

而 tower-grpc,虽然是一个非常新的实现,现在也不完善,但可以算是根正苗红了。首先它是 Rust 社区里面知名的几个开发者一起做的,譬如 mio 的作者carllerche,hyper 的作者 seanmonstar,另外它基于 tokio,这也可能是 Rust 网络编程的一个规范。所以如果我们能尽早的拥抱 tower-grpc,我们就可以跟 Rust 社区结合的更加紧密,帮助完善 tower 以及 tokio 相关的生态。

现阶段,对于 Protobuf,TiKV 使用的是 rust-protobuf,而 tower-grpc 使用的是 prost,所以我们并不能很容易的完全迁移到 tower 进行测试,主要是要把 TiKV 里面大量的使用 rust-protobuf 的代码改成使用 prost,这个其实是一个非常重的体力活。

不过还是可以先尝试一下的,使用 tower-grpc 还是比较简单的。首先,当然编译 TiKV 的 gRPC 协议,在 kvproto 里面,我们先 clone 下来,创建一个 tower 的目录:

git clone https://github.com/pingcap/kvproto.git cd kvproto mkdir tower

然后参考 Cargo.toml,创建出 Cargo.toml,不过这里需要注意,我使用的是 rustc 1.29.0-nightly (4f3c7a472 2018-07-17) 这个版本的,所以并不能编译 tower-grpc,需要显示的将 tower-grpc 的代码 clone 下来,在 tower-grpc/src/lib.rs 里面显示的加上:

#![feature(extern_prelude)] #![feature(crate_in_paths)]

才能编译通过,所以这里,我们自己的 Cargo 文件使用的是本地的 tower-grpc。然后创建一个 build.rs

extern crate tower_grpc_build; fn main() { tower_grpc_build::Config::new() .enable_server(true) .enable_client(true) .build(&["../proto/tikvpb.proto"], &["../proto", "../include"]) .unwrap_or_else(|e| panic!("protobuf compilation failed: {}", e)); // Same for pdpb.proto and other proto files }

在随便的创建个 src/lib.rs 文件,然后 cargo build,生成的 proto 相关的 rs 文件会放在类似 target/debug/build/tower-9000a2ba77585c7e/out 的目录下面,现在可以先手动 copy 出去使用,后面其实不需要这么麻烦。

对于生成的文件,譬如 metapb.rs,类似这样

#[derive(Clone, PartialEq, Message)] pub struct Cluster { #[prost(uint64, tag="1")] pub id: u64, /// max peer count for a region. /// pd will do the auto-balance if region peer count mismatches. /// /// more attributes...... #[prost(uint32, tag="2")] pub max_peer_count: u32, }

它并不能直接 import 使用,需要在外面再次 include,如下

pub mod metapb { include!("proto/metapb.rs"); }

然后我们再次创建一个工程,参考 client.rs,我们弄一个自己的 TiKV client,给 TiKV 发送 raw_put 命令:

pub fn main() { let _ = ::env_logger::init(); let uri: http::Uri = format!("http://127.0.0.1:20161").parse().unwrap(); let h2_settings = Default::default(); let mut make_client = client::Connect::new(Dst, h2_settings, DefaultExecutor::current()); let say_hello = make_client.make_service(()) .map(move |conn| { use tikvpb::client::Tikv; use tower_http::add_origin; let cOnn= add_origin::Builder::new() .uri(uri) .build(conn) .unwrap(); Tikv::new(conn) }) .and_then(|mut client| { use kvrpcpb::{Context, RawPutRequest}; use metapb::{RegionEpoch, Peer}; let ctx = Context{ region_id: 2, region_epoch: Some(RegionEpoch{ conf_ver: 1, version: 1, }), peer: Some(Peer{ id: 3, store_id: 1, is_learner: false, }), term: 6, priority: 0, isolation_level: 0, not_fill_cache: false, sync_log: false, handle_time: false, scan_detail: false, }; client.raw_put(Request::new(RawPutRequest { context: Some(ctx), key: b"a".to_vec(), value: b"123".to_vec(), cf : "default".to_string(), })).map_err(|e| panic!("gRPC request failed; err={:?}", e)) }) .and_then(|response| { println!("RESPOnSE= {:?}", response); Ok(()) }) .map_err(|e| { println!("ERR = {:?}", e); }); tokio::run(say_hello); }

上面我们强制操作了 Region 2,通过 pd-ctl 以及 tikv-ctl 这两个工具可以得到相关的 region 信息,然后执行,得到如下输出:

RESPOnSE= Response { http: Response { status: 200, version: HTTP/2.0, headers: {"content-type": "application/grpc", "grpc-accept-encoding": "identity,deflate,gzip", "accept-encoding": "identity,gzip"}, body: RawPutResponse { region_error: None, error: "" } } }

证明操作成功了,我们通过 tikv-ctl 在 TiKV 上面查询相关的数据:

tikv-ctl --host 127.0.0.1:20161 print -k za value: 123

发现 key a 的值为 123,写入成功。这里需要注意,在 TiKV 里面,所有 key 都会增加前缀 “z” 写入,所以这里我们是 “za”。

可以看到,使用 tower-grpc 是非常容易的,我们也在仔细考虑这个事情 https://github.com/tikv/tikv/issues/3951,如果你对这块感兴趣,欢迎联系我们。


推荐阅读
  • C++程序员视角下的Rust语言
    自上世纪80年代初问世以来,C就是一门非常重要的系统级编程语言。到目前为止,仍然在很多注重性能、实时性、偏硬件等领域发挥着重要的作用。C和C一样&#x ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • CentOS7.8下编译muduo库找不到Boost库报错的解决方法
    本文介绍了在CentOS7.8下编译muduo库时出现找不到Boost库报错的问题,并提供了解决方法。文章详细介绍了从Github上下载muduo和muduo-tutorial源代码的步骤,并指导如何编译muduo库。最后,作者提供了陈硕老师的Github链接和muduo库的简介。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • MACElasticsearch安装步骤及验证方法
    本文介绍了MACElasticsearch的安装步骤,包括下载ZIP文件、解压到安装目录、启动服务,并提供了验证启动是否成功的方法。同时,还介绍了安装elasticsearch-head插件的方法,以便于进行查询操作。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 本文介绍了在多平台下进行条件编译的必要性,以及具体的实现方法。通过示例代码展示了如何使用条件编译来实现不同平台的功能。最后总结了只要接口相同,不同平台下的编译运行结果也会相同。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了StartingzookeeperFAILEDTOSTART相关的知识,希望对你有一定的参考价值。下载路径:https://ar ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • VSCode快速查看函数定义和代码追踪方法详解
    本文详细介绍了在VSCode中快速查看函数定义和代码追踪的方法,包括跳转到定义位置的三种方式和返回跳转前的位置的快捷键。同时,还介绍了代码追踪插件的使用以及对符号跳转的不足之处。文章指出,直接跳转到定义和实现的位置对于程序员来说非常重要,但需要语言本身的支持。以TypeScript为例,按下F12即可跳转到函数的定义处。 ... [详细]
  • node.jsurlsearchparamsAPI哎哎哎 ... [详细]
author-avatar
林小秋
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有