Rust China Conf 2020 参会感想

Stella981
• 阅读 623

前言

2020 年 12 月 26、27 日,来自五湖四海的 Rustacean 相聚深圳,参加第一届 Rust China 大会。不同领域的开发者、高校老师/学生在此畅聊 Rust 的使用经验,下面笔者就回顾、总结此次参会的收获,让更多的读者一起享受这次饕餮盛宴。

这次 Rust China 的 topic 数量非常多,由于笔者从事的领域存在局限,因此不会涉及到所有的 topic 内容,感兴趣的读者可以通过文末附录的链接,自行阅读自己感兴趣的 topic。

Rust 语言

Rust 异步和并发浅谈

Speaker 通过分析 async-task 这个 library 的实现和大家分享了在 Rust 最新的异步接口上面,如何构建一个线程安全的、api 友好的 Executor。

Rust China Conf 2020 参会感想

异步任务的多线程 Executor

该 Topic 提到实现 future 中的 Waker 是需要注意的一些规则,但是之前作为使用者往往不会注意到的:

  • wake 之间调用的并发操作需要保证只会压入 pending task 到执行队列一次。

  • wake 调用和 poll 之间的并发需要确保在 poll 期间不会将 pending task 压入队列。

  • waker 的过期问题:由于每次调用 poll 传递的 waker 可能是不同的,所以需要每次 poll 都需要将 waker 更新到 Reactor,确保能够正确地唤醒 Task。

除此之后,该 Topic 还提到了在异步任务中一些常见的同步手段的实现细节,包括:Mutex、Oneshot、WaitGroup 这几种的具体实现,有兴趣的读者可以阅读附录的链接中的 slide 查看详细的实现介绍。

经验教训-使用 Rust  构建去中心关键任务系统

Speaker 是来自 NEAR 的 co-funder,在这个 topic 中讲述了一些他们在构建系统的过程中的一些工程经验,不少都是值得学习的:

  • 每一个模块需要至少两个 owner,相关代码的合并,必须得到至少一个人的同意。

  • 对于任何一个 PR,需要提供 test plan,在 test plan 符合规则之前,不会进行 review。

  • 去中心化的服务,对于协议的兼容性需要做好前后兼容(定义兼容为,前向兼容一个版本),兼容性测试、使用 Borsh 完成序列化的兼容、引入 nightly protocol 从而可以允许 unstable code 合并到 master。

  • 对于平时 PR 关联的 CI 需要保证提供非常快速的反馈,因此对于 test,需要作出区分,利用 Rust 的 feature 特性,来保证给开发者的快速反馈,对于完整的 CI 可以选择在特定的时候运行。

Rust 2021

Rust team 的成员也给大会分享了下 Rust 2021 的一些计划,包括基金会的一些进展,以及即将 stable 的一些特性,其中重点介绍了 const generic 确定会在 2021 年 stable。这还是挺令人兴奋的,毕竟 const generic 在泛型编程里也是个比较常用的特性,可算盼到了。这对于将数组作为泛型参数或者实现一些 collections 库时就很有用。一个例子就是要给数组实现一个 trait 时,没有 const generic ,那你只能挨个地给从 1 到若干大小的数组 impl 一次这个 trait ,非常麻烦,标准库里也有这样的例子:

macro_rules! array_impls {    ($($N:literal)+) => {        $(            #[unstable(feature = "const_generic_impls_guard", issue = "none")]            impl<T> LengthAtMost32 for [T; $N] {}        )+    }}array_impls! {     0  1  2  3  4  5  6  7  8  9    10 11 12 13 14 15 16 17 18 19    20 21 22 23 24 25 26 27 28 29    30 31 32}

存储

Rust 在存储领域的应用是笔者重点关注的一块,而会上也有好几个分享是跟存储领域相关的,下面会总结并分享一下相关的 topic。

用 Rust 实现用户态高性能存储

该 topic 提及了提高存储性能的一些手段,思路十分清晰,主要分为软件手段和硬件手段两个方面做了性能提升。

软件手段

首先是软件层面,主要有两块:

  • 自行实现 IO 调度,规避内核性能瓶颈。内核带来的很重要的一个开销就是上下文切换带来的等待时间,和现在高端 NVMe SSD 一次 IO 访问的时间已经相差不大,与其通过系统调用操作文件系统,还不如直接访问存储设备。目前他们是使用了 rust 的 async 特性,自己去做 IO 的调度,同时也使用了 io_uring 的技术来做系统调用的异步化,避免上下文切换的等待。

  • 他们认为内存不再是紧缺资源,此外他们还认为 80% 的 IO 访问集中在 20% 的数据上面,因此他们决定充分利用内存来构建高效缓存(简单粗暴但是有效)。

硬件手段

另外就是硬件层面了,主要也是两块:

  • 利用好非易失内存(Intel Optane)。

  • 利用片上系统(可编程硬件),把一些 CPU 操作 offload 到硬件上。

Rust China Conf 2020 参会感想

计算机操作执行时间对比

另外分享中还探讨了下 Rust 用于硬件编程的可行性以及 Rust 特性对硬件编程的一些帮助,比如内存安全、溢出检查等等。印象深刻的一点是他们项目把 Rust 编译器的一些非常严格的规约检查也都开启了,包括禁止简单的整数加减等操作,算是把溢出等各种检查做到了极致(虽然写代码的时候会很痛苦),而事实上不少 bug 就是因为没考虑溢出等问题导致的,而且有时候排查起来也十分困难,这一点不得不令人佩服。

基于 Rust 构建高性能新型开源数据仓库

这个是前段时间号称速度倍杀 clickhouse 的 TensorBase 的作者做的分享,不过由于时间比较紧张,很多东西没有展开讲,这里总结一下一些提到的有意思的点。

First Principle

关于系统设计原则上,作者提到了一个 First Principle 原则,不基于任何现有的前提假设去做事情,简单来说就是不要想当然。这个原则对于做优化的时候还是有一定启发的,因为往往想当然地去做优化不一定能得到最优解。

内部实现

分享对于内部实现原理,只是做了粗略的介绍,很多组件没有做详细的展开。

  • Unified RA(Relational Algebra): 作者设计的只有少数算子的原语(map,union/agg,join,sort/top),利用这几种算子来完成 sql 核心功能的推导和优化。

  • JIT based whole-system optimization:整个系统的设计和优化也是围绕 JIT 来做性能优化,根据查询生成相应的 c 代码,最后再编译并执行,这样整个数据库其实就相当于 sql 到 c 的编译器和执行器。

  • ......(其他的特点没有详细展开,有兴趣的读者可以根据其 slide 自行理解)

Benchmark

从作者的 benchmark 来看,性能还是很不错的。不过从目前 TensorBase 已经开源出来的部分来看,这部分的工作应该还没完成或者公开出来。笔者认为这个项目要真正可用应该还要一段时间,而且完全基于 JIT 来做查询,如何处理编译带来的开销,是否能应对用户复杂的查询场景还是要打个问号的。

Rust China Conf 2020 参会感想

TensorBase BenchMark 结果

使用 Rust 构建高性能时序数据库 CeresDB

这个也是笔者所在团队进行分享的 topic,围绕了如何在蚂蚁集团内部高吞吐的场景下,构建一个高性能的时序数据库,重点分享了在构建过程中的一些值得分享的经验和对未来技术的展望。

该 topic 设计的分享经验主要包括如下几点:

  • 利用时序场景下的写入按照时间有序的特性,构建出对于 LSM 友好的编码,从而降低 Compaction 代价,减小写放大,提升写入性能。

  • 通过减少线程切换,采用向量化的方式进行查询,从而降低在查询高吞吐的场景下系统的负载,提升整体的查询性能。

  • 利用时序领域用户查询往往更关注最新的数据的特性,定制内存时序数据库,从而降低查询耗时、提升查询吞吐。

MadFS:小巧精悍的分布式文件系统

Speaker 主要分享了利用 Rust 打造的 OS -- rCore 以及 MadFS,rCore 其实在中文 Rust 社区里面已经是比较有名的了,就暂不赘述了,这里主要介绍一下 MadFS,这个是在 IO500 中获得排名第一的文件系统。

Rust China Conf 2020 参会感想

IO500 排名

MadFS 原理上借鉴了 GekkoFS ,整体上是个去中心化的文件系统,文件分块存储,并且按照路径哈希到节点上,文件块直接存本地磁盘,元数据存储在本地的 RocksDB 里,节点间通信使用了 ucx (Unified Communication X),底层应该是通过 RDMA 来做到高速通信。虽然在分享中 Speaker 说这是个为跑分而生的系统,不过在应用场景上感觉和 GekkoFS 类似,同样可以应用在超算上作为一个临时文件系统,整个系统是可以快速部署的,并且性能强悍,可以在一个超算作业提交后,直接实例化一套对应的文件系统给相应的作业使用,从而提供高吞吐的读写。

Rust China Conf 2020 参会感想

MadFS 的软件架构以及依赖

其他

云计算中的 Rust 和 WASM

Rust 语言除了本身比较适合系统编程,抱上 wasm 这个大腿也是令 Rust 能够在 serverless 领域大展身手的重要原因之一。SecondState 这家公司在他们的分享中提到,在云上运行无服务或者微服务应用, WASM + WASI 的技术组合相比 Docker 有着更多的好处:

  • 冷启动速度更快,相较于 Docker 可以快 100 倍。

  • 执行速度更快(借助 AOT),相较于 Docker 可以快 10%-50%。

  • 拥有更小的体积更小,Docker 动辄几百 MB 以上。

  • 拥有更现代的安全模型,提高更佳的安全性。

上面提到的 WASI 其实就是 WebAssembly Systems Interface,也就是在 WASM 中提供了操作系统的接口,那么有了 WASI 的话,WASM + WASI 自然就可以和 Docker 一争高下。

Rust 对于 WASM 良好的支持正是他们选择使用 Rust 的一大原因。笔者认为, WASM + WASI 在服务端领域的应用后面会是一个技术风口,把程序编译成 WASM 分发和交付,可以更进一步地屏蔽掉执行环境的差异,而且还可以基于 AOT 等技术提高执行效率。关于这个,分享里一个令人印象最深刻的点,就是基于 AOT 和 WASM ,他们的虚拟机可以取得比 Docker + Native 更高的性能。

Rust China Conf 2020 参会感想

SSVM vs Docker

Rust China Conf 2020 参会感想

Rust 系统编程在 StratoVirt 中的实践

目前已经可以看到 Rust 在云计算领域的一些应用,主要集中在虚拟化和 serverless 方面。华为在会上分享了他们基于 Rust 开发的 hypervisor StratoVirt ,主要面向云数据中心,底层基于 KVM ,上层使用 Rust 实现了轻量化的虚拟主板。

Speaker 提到了系统编程的一些特点以及他们选择 Rust 的原因主要就是内存安全以及高性能,而笔者觉得还可以加上一点,就是能够很方便的通过 ffi 和 C 代码互调,比如他们也提到 StartoVirt 也链接了好几个 c 库。

Rust China Conf 2020 参会感想

StratoVirt 架构图

Rust 可信编程在华为

在这次大会上,华为提供了不少 topic 的分享,可以看出华为对于 Rust 是非常重视的,来自华为的可信编程团队分享了他们在公司内部在 Rust 编程语言上面的一些探索和研究:

  • 使用 Rust TXL 这个技术,将现存的大量的 C/C++ 代码平滑、可信地转换成 Rust 代码,相较于社区的自动转化(比如 c2rust.com),可以转化出更加优雅的 Rust 代码(比如更少的 unsafe 代码)。

  • 编写 Rust 编码规范,包括 Safe 和 Unsafe 的两个部分。

  • 对于社区的代码分析工具(Tokei 和 Geiger)进行了相应的贡献,这两个工具可以帮助团队进行代码分析,不仅包括代码组成比例的基本分析,还能进行代码安全度的分析。

  • 智能化代码学习,对于现有的算法进行分析,可以帮助开发人员进行 C/C++ 的过渡,把 C/C++ 的成熟的模型可以引入到 Rust 中来,通过提示、补全等 IDE 的功能帮助开发人员写出更好的 Rust 代码。

Rust China Conf 2020 参会感想

华为对 Rust 语言和技术的探索

高性能 Rust tracing 库设计

PingCAP 是 Rust 社区里面非常知名的公司了,这次大会他们分享了他们的高性能 tracing 库的设计,其中将他们高性能 timer 实现的部分很精彩:为了保证每个 span 的创建开销足够小(小于 20ns),他们没有使用 std 的 Instant 来计时,而是使用 cpu 的 TimestampCouter register (tsc) 来计时,当然这么做了之后,就需要做一些额外的工作来保证多核下 tsc 计时结果的一致性。

Rust China Conf 2020 参会感想

Minitrace 创建 span 的 benchmark 结果

除此之外对于 tracing 结果的收集也采用了通过 threadlocal 进行 batch 化处理进行优化,避免频繁的调用 channel 发送引起的代价,这样的优化也是一个不错的分享点,整体可以看出 PingCAP 团队在极致性能方面的追求是令人钦佩的。

总结

Rust 在 2010 年问世以来,到 2020 年正好十年,尽管相比其他大多数语言,Rust 显得十分年轻,但通过上面的议题来看,Rust 已经在各个领域展露头脚。而且,社区内也有很多开发者尝试用 Rust 重写古老的 C/C++ 项目,比如 GPG/Curl/Emacs 等。

虽然 Rust 的学习曲线相比其他大部分语言要陡峭,但无疑 Rust 降低了系统开发的成本,Java/Python/Go 之类的程序员在与编译器斗争后,都可以写出安全、健壮的系统软件,相信后面会有越来越多的企业/开发者去“吃螃蟹”🦀️🦀️🦀️。。

最后因为篇幅所限和笔者的知识领域局限,还有很多有趣的 topic 并没有在本文中提到,有兴趣的读者可以在附录中的链接自行寻找自己感兴趣的部分,另外作出说明,本文中涉及到的专业图片都是来自大会各个演讲嘉宾的 slides。

最后的最后,我们是蚂蚁智能监控技术中台下的存储团队,我们正在使用 Rust/Go/Java 构建高性能、低成本具备实时分析能力的新一代时序数据库,欢迎加入我们,联系邮箱(jiachun.fjc@antgroup.com)。

Rust China Conf 2020 参会感想

附录

  1. Rust China slides 链接:https://github.com/rustcc/RustChinaConf2020

  2. Rust China 视频回放链接:https://www.bilibili.com/video/BV1Yy4y1e7zR

本文分享自微信公众号 - 蚂蚁智能运维(gh_a6b742597569)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这