Rust中的高吞吐量流处理

作者 | Noz
编译 | 王瑞平
本篇文章主要介绍了Rust中流处理的概念、方法和优化 。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序 。
最后,作者介绍了如何通过测量空闲和阻塞时间来优化流处理程序的性能,并将这些内容同步至Twitter和blog 。

Rust中的高吞吐量流处理

文章插图
图片
此外,作者还提供了一些其它方面的优化建议,例如:
  • 在实际系统中,应考虑将线程固定至CPU内核上或使用一种版本的绿色线程减少上下文切换 。
  • 在处理流时,通常需要为结果分配内存 。内存分配是昂贵的,所以,在以后的文章中,作者将会介绍一些优化内存分配的好方法 。
首先,分别介绍下在同步和异步Rust中的流特质 。
一、同步和异步Rust中的流特质在同步Rust中,流核心抽象是Iterator 。它提供了在序列中产生项的方法并在它们之间进行阻塞,然后,通过将迭代器传递给其它迭代器的构造函数完成组合 。这使我们可以毫不费力地将事物连接在一起 。
在异步Rust中,流核心抽象是Stream 。它的行为与Iterator非常相似;但是,它并不是在每个项之间产生的阻塞,而是允许其它任务在阻塞等待时运行 。
在异步Rust与同步Rust中,Read和Write分别对应AsyncRead和AsyncWrite 。这些特质表明:未解析的字节通常直接来自10层(例如,来自套接字或文件) 。
Rust中的高吞吐量流处理

文章插图
图片
Rust流吸收了其它语言所具备的最佳功能;例如,它们能通过利用Rust特质系统回避Node.js的Duplex流中出现的遗留问题,也能同时实施背压和惰性迭代,大大提升了效率 。最重要的是,Rust流允许使用相同类型的异步迭代 。
未来,关于Rust流还有很多值得关注之处,尽管仍有一些问题亟待解决 。
二、总体概括:什么是流处理?现在,也许你已经了解到了同步和异步Rust中的流特质,下面再来介绍下什么是“流处理” 。
“流处理”是一种重要的大数据处理手段,其主要特点是处理的数据是源源不断且实时到来的 。
在不同规模的科技公司中,流处理通常被用于分析和处理具体事件,且常被应用于分布式系统 。
有些领域确实会大量使用“流处理”手段,包括:视频处理和高频交易 。我们也能够借此寻找到新型区块链之中的架构灵感 。因为,区块链需要处理交易和元数据流等 。
如今,你可以租用具有100多个CPU的内核、100GB内存、多个GPU和100Gbps带宽的AWS实例,还无需拥有一个节点的分布式系统 。
现在,让我们了解下流处理在Rust编程中的应用:
三、举个例子:计算10亿个数字的哈希程序现在,让我们写一个用来计算10亿个数字的SHA512和BLAKE3哈希程序吧!你可以想象:数字代表交易、分析事件或价格信号 。散列法可用来表示对这些输入的任意转换 。
如下是单线程解决方案程序:
Rust中的高吞吐量流处理

文章插图
图片
当我在带有专用CPU和16核的Digital Ocean上用发布模式运行此程序时,只需6分钟多一点 。
Rust中的高吞吐量流处理

文章插图
图片
1.通道现在,让我们用“流处理”来重写这个程序 。与在单个循环中执行散列不同,我们将设置一个线程管道并行执行散列,然后收集结果 。
在两个线程之间发送数据的本地流被称为通道 。我们的新程序将生成四个线程 。生成器线程将生成数字并同时将它们发送至两个不同的哈希线程 。散列线程将读取这些数字,分别对它们进行散列,然后将它们的输出发送给结果线程,下图是它的架构:
Rust中的高吞吐量流处理

文章插图
图片
我们也将使用标准库中的mpsc通道发送和接收数据 。mpsc可用来表示“多生产者-单消费者”,代表你可以从多个线程向通道发送数据,但是,只有一个管道能够输出数据 。虽然我们不会使用这个多制作人功能,但是了解这一点很重要 。
它仍是一个相当简单的程序:
Rust中的高吞吐量流处理

文章插图
图片
输出结果如下:
Rust中的高吞吐量流处理


推荐阅读