爲什麼我們從 Pony 轉向 Rust?

01 背景

我們的小團隊着手構建下一代流處理框架,目標是極高的可擴展性、性能和彈性的內存狀態。根據經驗,我們覺得 Apache Storm、Apache Spark 等常用的解決方案並沒有針對很多場景進行優化,比如需要處理大量數據,或者需要非常低的延遲。此外,現有的 Apache 工具依賴於 Java —— 特別是 JVM —— 很難獲得可預測的、非常低延遲的結果(也不適合現代數據科學算法和工作流)。我們相信我們可以做得更好——處理更多數據、更快、成本更低。

我們很清楚,用 Java 構建另一個分佈式計算框架不是好的解決方案。我們在 Python 中構建了一個初始原型來測試一些想法,但我們甚至在開始之前就知道,由於各種性能、靈活性和可擴展性原因,一旦我們開始構建實際框架,Python 就不可能了。

那麼如果不是 Java,也不是 Python,我們應該選擇什麼語言呢?我們知道我們將編寫性能密集、高度併發的代碼。我們考慮過 C++、Pony[1] 和 Rust[2]。從純粹的性能角度來看,C 或 C++ 將是一個不錯的選擇。但是,根據過去的經驗,我們知道用 C/C++ 構建高度分佈式的數據處理應用程序並非易事 [3]。我們排除了 C++,因爲我們希望在內存和併發方面有更好的安全保證。

如果我們選擇 Rust,我們將需要構建自己的運行時來處理併發。另一方面,Pony 是一種具有強大內存和併發安全保證的語言,還具有高性能、基於 actor 的運行時。我們認爲這將是快速行動並構建可靠、高性能系統的最佳方式。我們的賭注爲我們軟件的早期迭代帶來了回報。儘管與 Rust 一樣,Pony 也有學習曲線,但我們發現一旦通過它,該語言使併發編程變得容易,並消除了我們過去處理過的所有類型的錯誤。而且因爲我們不必構建併發運行時,我們能夠非常快速地專注於我們的核心領域。Pony 還提供了一個基於 actor 的併發垃圾收集器,旨在避免長時間的 “Stop The World” 暫停。這很關鍵,因爲我們的目標是非常低、可預測的尾部延遲 [4]。

事實證明,對於我們圍繞我們的最初目標而言,Pony 是一種很棒的語言。它幫助我們快速解決難題,而無需從頭開始構建併發運行時,並使我們能夠實現雄心勃勃的性能目標。

然而,與此同時,數據科學和機器學習繼續呈爆炸式增長,我們發現客戶對部署機器學習模型的興趣遠遠超過了對更傳統的流處理數據算法的需求。隨着對 MLOps 的日益關注,Rust 變得更合適。與 Pony 一樣,它也爲我們提供了安全性和性能,但更大的庫生態系統對我們的 MLOps 工作至關重要。

02 轉向 Rust

當我們開始關注 MLOps 時,情況已經發生了變化。一方面,Rust 在短時間內取得了很大的進步。例如,對於併發運行時,我們現在有 Tokio[5]。另一方面,Rust 有強大的庫生態系統。Pony 也在進步,但社區規模較小,作爲一家小型初創公司,我們最好不必解決核心領域之外的問題,尤其是低級集成方面的問題。在 Rust 的 ML 方面有很多發展,自從進入這個領域以來,這對我們來說是最有價值的。

我們通過一些實驗開始過渡,以瞭解我們將如何使用 Rust 解決我們現有的一些問題。我們的第一個實驗之一是重寫一個爲客戶構建的專用 HTTP 服務器。這使我們能夠測試語言的體驗。來自 Pony 的愛好者,對了解 Rust 的異步編程特別感興趣。

對這項早期工作的結果感到滿意,工程團隊開始深入學習 Rust 並圍繞其範式構建我們的平臺。來自 Pony 的我們已經習慣於仔細考慮內存安全,所以我們已經準備好處理 Rust 的借用檢查器,這對許多新的 Rustaceans 來說可能是一個艱鉅的挑戰。

使用 Rust 一段時間後,我們對結果非常滿意。作爲像 Pony 一樣類型安全的語言,有一些重要的優勢。我們可以快速推進我們的代碼庫,知道編譯器會在它們成爲運行時問題之前捕獲一整類錯誤。借用檢查器使我們免於花費數小時或數天的時間來尋找數據競爭。

03 Rust 的好處

我們新的基於 Rust 的平臺最近每秒處理數百萬次推理複雜的廣告定位模型,平均延遲爲 5 毫秒,每年的基礎設施成本爲 13 萬美元。從客戶的角度來看,這是一個巨大的成功。

更重要的是,我們希望訪問更大的庫生態系統的願望得到了滿足。我們目前正在使用 TensorFlow 和 ONNX 等開源庫來運行 ML 模型。這些庫使用 Rust 的 FFI 來包裝底層的 C 實現。如果我們自己編寫這些系統的基本包裝器,我們就需要數週的開發時間,並且需要數月的時間才能使它們達到我們可以放心地將它們發送給客戶的健壯狀態。如果我們需要使用它們,我們可以使用大量其他庫。這使我們能夠專注於提供平臺的業務目標,該平臺使在生產中快速部署和運行機器學習模型變得簡單。

除了豐富的可用庫之外,我們還受益於 Rust 的成熟度和高採用率。我們知道正在構建一個設計良好且經過良好測試的語言,並且我們可以訪問一個大型社區,這將保證未來的持續支持。這讓我們能夠將所有的工程精力集中在幫助客戶解決他們的問題上。社區創建了各種各樣的工具,包括 IDE、替代編譯器、分析工具和新的目標平臺。所有這些工具都使開發高質量軟件變得更加容易。

我們已經調整了我們的入職流程,包括閱讀 “The Rust Programming Language”、“The Rustonomicon” 和關於 Rust 異步運行時的文章。儘管 Rust 的使用比 Pony 更廣泛,但仍有很多優秀的程序員還沒有學會它,所以我們希望確保我們有一種方法讓他們在入門過程中跟上進度。

我們很高興有機會與 Pony 結合。它是一種偉大的語言,幫助我們達到了今天的水平。我們鼓勵任何對新編程思想感興趣的讀者花一些時間閱讀本文,因爲我們認爲即使你從未在生產中使用它,你也會學到一兩件事。我們的工程價值觀之一 [6] 是 “適合工作的工具”,在這個階段,Rust 是滿足我們需要的工具。我們對使用它感到興奮,並正在迅速增強和改進我們的產品。

04 關於 Rust 和 Pony 的一些進一步說明

原文鏈接:https://www.wallaroo.ai/blog-posts/wallaroo-move-to-rust

參考資料

[1]

Pony: https://ponylang.io/

[2]

Rust: https://www.rust-lang.org/

[3]

非易事: https://blog.wallaroolabs.com/2018/02/how-we-built-wallaroo-to-process-millions-of-messages/sec-with-microsecond-latencies/

[4]

可預測的尾部延遲: https://blog.wallaroolabs.com/2018/03/performance-testing-a-low-latency-stream-processing-system/

[5]

Tokio: https://github.com/tokio-rs/tokio

[6]

工程價值觀之一: https://www.wallaroo.ai/engineering-values

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/9m7R1Ed7pHOADRaYvoV1BQ