Stream is the new file
作者 | 滕昱(戴爾科技集團 軟件開發(fā)總監(jiān))
隨著5G 網(wǎng)絡、容器云、高性能存儲硬件水平的不斷提高,流處理正在擁有越來越廣泛的市場前景。
各種各樣的設(shè)備傳感器、監(jiān)控攝像頭、移動終端設(shè)備等等無時無刻不在產(chǎn)生著大量的流式數(shù)據(jù)。針對不同的場景,流式數(shù)據(jù)也許會有各式各樣不同的特點,但是對于這些流式數(shù)據(jù)的處理,往往都有實時或者接近于實時的、無邊界連續(xù)不斷的、低延時的共性要求。而這些要求,恰恰就是流處理的基本特點。
僅僅從這些基本特點看,好像流處理早已經(jīng)被實現(xiàn)了。不管是70年代開始興起的規(guī)則引擎,還是基于傳統(tǒng)的關(guān)系型數(shù)據(jù)庫的復雜海量數(shù)據(jù)處理,貌似都符合要求,甚至在編程語言里都既有了對這些處理系統(tǒng)的支持。但是Stonebraker,?etintemel和Zdonik在2005年的論文《The 8 Requirements of Real-Time Stream Processing》中指出,現(xiàn)有的這些系統(tǒng)其實還不能真正滿足流處理的要求,流處理技術(shù)還需要進一步的發(fā)展。
這也是為什么現(xiàn)階段包含F(xiàn)link在內(nèi)的流批一體的大數(shù)據(jù)技術(shù)棧持續(xù)在不停發(fā)展的原因。IDC報告指出,未來的3~5年整個實時數(shù)據(jù)會以驚人的速度增長。那么不管是針對實時數(shù)據(jù)的流處理,還是針對歷史數(shù)據(jù)的批處理,也都需要同步的發(fā)展來滿足時代的要求。
這些流批一體的大數(shù)據(jù)技術(shù)棧的發(fā)展,不光包含F(xiàn)link等處理引擎的進化,也包括存儲領(lǐng)域。那么在存儲領(lǐng)域,針對現(xiàn)代流處理,又有哪些進化和發(fā)展呢?
傳統(tǒng)來說,數(shù)據(jù)往往以文件的形式組織,用文件系統(tǒng)加以管理。
但是,文件接口抽象真的能很好的處理流式的連續(xù)數(shù)據(jù)么?讓我們來看一看。
首先,假設(shè)我們用文件和文件系統(tǒng)來做一個流存儲。把傳感器、用戶日志、用戶輸入這些數(shù)據(jù)注入一個文件中,貌似并沒有什么問題。但是被寫入文件的數(shù)據(jù)必須被持續(xù)不斷的讀取出來。也就是說,持續(xù)不斷被寫入文件的數(shù)據(jù),必須不停的被讀取出來用以處理,這是文件接口和針對連續(xù)數(shù)據(jù)流處理最根本的區(qū)別。
其次,當數(shù)據(jù)量變大的時候,并發(fā)是必須的。我們當然可以利用多個文件實現(xiàn)并發(fā)寫。但這也意味著讀端的應用程序必須追蹤多文件讀。為增加并發(fā)而帶來的多文件讀取的協(xié)調(diào)和追蹤并沒有包含在文件接口的抽象里,所以這對讀應用程序來說,并不是透明的。
第三,如果進一步考慮動態(tài)擴展呢?動態(tài)擴展意味著在程序讀取的過程中再動態(tài)生成新的文件或者合并已有文件以適應新的并發(fā)度。在這種情況下,讀端應用程序需要自己監(jiān)測在讀文件的新增和減少,這是除應用程序本身業(yè)務邏輯之外額外的工作。
第四,數(shù)據(jù)是連續(xù)無邊界的,需要一種標記來記錄當前數(shù)據(jù)的讀取位置。橫跨多個文件去設(shè)計邏輯上全局一致的位置點,進一步增加了應用程序的復雜性。
第五,IOT場景往往需要維護針對同一設(shè)備號的數(shù)據(jù)序列。如果把設(shè)備數(shù)據(jù)當作文件,把設(shè)備號當作key,那么注入端需要key到文件的映射處理并維護在同一key命名空間下的per-key order。同時,讀取端還得做到多文件讀取的負載均衡。這些都是文件和文件系統(tǒng)抽象不能完成,所有的工作都推向了上層應用程序。
第六,對于流處理來說,數(shù)據(jù)的清除往往是從流數(shù)據(jù)的頭開始刪除,先寫入的先刪。文件接口抽象并不能很好的處理這點。
近些年來,業(yè)界其實是廣泛應用了一個中間解決方案,通過messaging系統(tǒng)(比如Kafka)+文件系統(tǒng)的混合抽象方案注入。這解決了部分問題,比如說動態(tài)擴展、注入端的并行問題。但是這不是一個完整的端到端解決方案。實時流計算是走了messaging接口規(guī)避了文件接口的一些問題,但是針對歷史數(shù)據(jù)的批處理還是需要文件接口,這實際上是針對同一數(shù)據(jù)的兩種系統(tǒng)。
所以,對于連續(xù)的流式數(shù)據(jù)的存儲層抽象,我們需要的既不是原來的基于傳統(tǒng)數(shù)據(jù)庫的實現(xiàn),也不是基于messaging系統(tǒng)的轉(zhuǎn)化,而是從頭設(shè)計一個完整的流存儲系統(tǒng)。
那么,這種流存儲的抽象能給上層的計算單元帶來什么樣的好處呢?讓我們來具體看一下。
首先,對于之前提到的messaging系統(tǒng)+文件系統(tǒng),數(shù)據(jù)需要用stream接口進入messaging系統(tǒng),但是可能以文件接口方式讀出,在接口抽象上并不一致。我們需要的流存儲抽象,不管是注入端還是讀取端,都是stream接口,給應用程序統(tǒng)一的抽象。
其次,流存儲抽象需要提供動態(tài)擴展功能。在應用程序看來,它只需要往一個stream里寫入數(shù)據(jù)。至于這個stream抽象怎么基于注入量進行動態(tài)擴展,或者在多路并發(fā)下怎么保證per-key的order,由抽象層內(nèi)部解決,對應用程序完全透明。
第三,在所有情況下,哪怕是動態(tài)擴展過程中,從流存儲抽象層讀出的數(shù)據(jù),具有per-key的order保證。
第四,流存儲抽象能夠在邏輯上提供基于時間的全局一致的位置點,我們稱之為Stream Cut。應用程序依賴于此能夠回放到任意一個位置點,回放或重試業(yè)務邏輯。
計算引擎例如Flink能夠利用流存儲抽象提供的Stream Cut,基于流存儲系統(tǒng)處理的checkpointing功能,實現(xiàn)端到端的exactly-once保證。這在文件抽象接口上,是很難做到的。
除此之外,還有很多其他針對streaming典型場景的的好處,例如原子讀寫,低延時的tail read、事務支持、歷史數(shù)據(jù)truncation等等。
那么,假設(shè)有了這個很好的流存儲抽象出現(xiàn),它能做什么?
我們能夠基于這層抽象,建造更簡單、更清楚的大數(shù)據(jù)的流水線。
海量的連續(xù)流式數(shù)據(jù)注入這個流水線,被保存到流存儲中。以Flink為代表的流批一體的處理單元用流存儲提供的統(tǒng)一接口,包括針對流處理的低延遲的tail read,以及針對批處理的高吞吐的historical read,針對同一份數(shù)據(jù),提供支持exactly-once語義的數(shù)據(jù)處理。一種抽象一套處理,簡化流程。
當然實際中流水線會更加復雜一些。數(shù)據(jù)往往是被寫入Edge端,進行on-the-fly的實時計算處理,比如監(jiān)控攝像頭拍下的圖片圖像的預處理。同時,數(shù)據(jù)也可以被發(fā)送到數(shù)據(jù)中心的私有云或者是公有云上,作更大規(guī)模的準實時的一個計算。這樣的方式,讓大數(shù)據(jù)流水線的開發(fā)變得非常的清楚和簡潔。
Pravega(梵語:high speed)就是在流存儲抽象的需求背景下應運而生的系統(tǒng),具有前面提到的流存儲抽象的所有特點。Pravega是2016年創(chuàng)建開源項目Apache2 License,近期已被加入CNCF。
下面我們就來看看,Pravega是怎么提供以上提到的流存儲抽象的這些屬性的。
首先,對于近期寫入的數(shù)據(jù),Pravega提供低延遲的tail read。同時,Pravega底層由可擴展的軟件定義存儲實現(xiàn),可以支持無限歷史數(shù)據(jù)存儲。并且這些歷史數(shù)據(jù)同樣通過streaming接口讀取,以實現(xiàn)針對歷史數(shù)據(jù)的流處理。其次,Pravega支持動態(tài)擴展。根據(jù)前端流量的大小,Pravega能夠動態(tài)調(diào)整partition的數(shù)量以適應前端流量,對客戶端透明。再次,Pravega提供StreamCut方便客戶獲取基于時間的數(shù)據(jù)分片,用來實現(xiàn)數(shù)據(jù)會放處理功能等。當然,Pravega還支持以streaming接口truncate數(shù)據(jù),從頭讀取歷史數(shù)據(jù)等等。基本上之前提到的相關(guān)特點在Pravega里都能找到相應的功能支持。
那Pravega具體是怎么實現(xiàn)的呢?
當創(chuàng)建一個stream的時候,和其他可擴展系統(tǒng)不同,用戶并不需要指定并發(fā)的個數(shù)。在Pravega內(nèi)部,segment是真正的數(shù)據(jù)存儲單元。一個stream可以擁有一個或多個segment(s)。Pravega通過動態(tài)調(diào)整segment的個數(shù)實現(xiàn)動態(tài)擴展。
所有寫入stream的數(shù)據(jù)都被當作是一串a(chǎn)ppend only的bytes最終寫入segment中。可以是一行l(wèi)og,可以是一張圖片,通過serializer/deserializer決定語義,沒有格式的限制,也沒有必須是小文件的限制。
當stream擁有多個segment的時候,數(shù)據(jù)會并發(fā)寫入這多個segment中。這多個segment將namespace分成同等數(shù)量的key space,寫入的數(shù)據(jù)可以通過綁定routing key,決定自己寫入哪個key space(segment)中。相同routing key的數(shù)據(jù)會被寫入同一個segment中,獲得order保證。比如,傳感器產(chǎn)生的連續(xù)數(shù)據(jù)都可以使用傳感器的設(shè)備號作為routing key,以保證同一傳感器產(chǎn)生的數(shù)據(jù)擁有相同的routing key而被寫入同一個segment,以保證讀取時的時序性。實際上,Pravega的transaction,exactly-once等特性正是基于此實現(xiàn)的。
講了那么多動態(tài)擴展,下面給大家一個具體的例子看看它的實現(xiàn)。假設(shè)系統(tǒng)中創(chuàng)建了一個stream,開始的時候他只有兩個segment。
當注入流量翻倍的時候,Pravega能夠檢測到這點,并且將segment的個數(shù)從2個擴展成4個。這點不需要用戶的任何干預,不需要改變配置、擴展節(jié)點、起停服務等等,所有的都無縫發(fā)生在Pravega內(nèi)部,對用戶透明。
同樣,當注入流量減少時,Pravega也能相應的合并segment,去除不必要的并發(fā)節(jié)省資源使用。
Pravega的這種動態(tài)擴展機制,結(jié)合container化的部署方式,讓Pravega真正實現(xiàn)了cloud-native的分布式可擴展的流存儲系統(tǒng)。
下面是Pravega的架構(gòu)圖。左邊是一個非常抽象的stream,用戶通過Event Stream Writer/Reader通過streaming接口讀寫數(shù)據(jù)。右邊可以分成兩部分,控制面板和數(shù)據(jù)面板。控制面板負責管理和維護stream和segment,比如stream的創(chuàng)建, segment的分配部署,以及segment的動態(tài)擴展等。數(shù)據(jù)面板以segment為單位管理數(shù)據(jù)。寫入segment的數(shù)據(jù)首先會被寫入Durable Log實現(xiàn)數(shù)據(jù)的持久化保護。同時數(shù)據(jù)也會緩存在Streaming Cache中,提供高性能的讀取。所有寫入的數(shù)據(jù)在積攢后會通過優(yōu)化算法打包寫入底層可擴展的Long-term Storage,通過分級存儲保存歷史數(shù)據(jù)。這層Storage只做數(shù)據(jù)存儲功能,對于歷史數(shù)據(jù)的讀取依然通過Pravega的streaming接口提供。數(shù)據(jù)面板除了通過segment來管理用戶數(shù)據(jù)外,也通過Table segment管理自己的metadata數(shù)據(jù)。它同樣支持動態(tài)擴展,避免了很多系統(tǒng)用zookeeper存放metadata是遇到的擴展問題。
好,到此為止,我們應該了解到Pravega確實是符合流存儲抽象的實現(xiàn)。那么隨后的一個問題是,支持了這么多靈活的功能,實現(xiàn)應該很復雜吧。這樣的一個流存儲系統(tǒng),運行起來到底性能會怎么樣呢?畢竟對于實時性要求比較高的流處理來說,性能是至關(guān)重要的。
為了驗證這點,我們把Pravega 0.8部署在AWS標準服務商,用業(yè)界標準的OpenMessaging Benchmark系統(tǒng),對Pravega的性能進行了測試和取樣。完整的結(jié)果在《When speeding makes sense — Fast, consistent, durable and scalable streaming data with Pravega》(https://blog.pravega.io/2020/10/01/when-speeding-makes-sense-fast-consistent-durable-and-scalable-streaming-data-with-pravega/)這篇博客上可以找到。
這里我們截取了其中的一些對Pravega的性能進行一些介紹。
下面這張圖顯示了Pravega在1個segment和16個segment下,隨著注入量的不斷增加,Pravega的性能表現(xiàn)。我們可以看到,Pravega性能針對不同segment并沒有太大區(qū)別,都能夠做到低延時高吞吐。隨著注入量的增大,性能成穩(wěn)定線性變化。足以說明Pravega在性能方面的亮眼穩(wěn)定表現(xiàn)。
此外,我們還和messaging系統(tǒng)(Pulsar)對比了分級存儲的性能。測試中,對于同樣部署在AWS上Pravega和Pulsar,我們用OpenMessaging對兩套系統(tǒng)用相同的注入速度持續(xù)寫入15分鐘,以使兩套系統(tǒng)上有大約100GB的歷史數(shù)據(jù)。然后同時打開讀端讀取數(shù)據(jù),考驗兩套系統(tǒng)對于歷史數(shù)據(jù)讀取的表現(xiàn)。從圖上我們可以看到,Pravega在短短幾分鐘內(nèi)就能夠讀取并消化掉之前的歷史數(shù)據(jù),追趕上前端新的寫入。而Pulsar花費80分鐘依然沒有做到。這也正是Pravega作為一個流存儲系統(tǒng)而不是messaging系統(tǒng)必須具備的優(yōu)勢,對歷史數(shù)據(jù)的存儲和讀寫同樣重要。
對于Pravega引以為傲的動態(tài)擴展機制,我們也給出了相關(guān)測試。在下面的圖示中,測試stream剛開始只有1個segment。在高注入量的持續(xù)注入下,圖示可以看到stream的segment每隔大約10分鐘自動擴展一次,隨著每次擴展,系統(tǒng)延遲降低一次。整個過程完全自動,最終系統(tǒng)會針對注入的數(shù)據(jù)量,達到最佳性能平衡。完美的設(shè)計!
那是不是segment越多越好呢?我們都有類似的經(jīng)驗,segment越多,資源競爭越激烈,系統(tǒng)會出現(xiàn)超負載的情況,性能反而會更糟。那Pravega是這樣的情況么?
我們也做了和Kafka的對比圖。當segment個數(shù)從1漲到10的時候,確實,對于兩套系統(tǒng)來說,segment個數(shù)越多,吞吐率越高。但是顯然,10是峰值,超過以后Kafka如經(jīng)驗預料的一樣,性能開始有了顯著下降。但是Pravega依舊能夠維持峰值的高性能不變。足以說明Pravega的性能在擴展時的穩(wěn)定性。
由上所有的架構(gòu)介紹和性能分析,我們可以看到,Pravega確實是一個合格的企業(yè)級的cloud-native分布式可擴展流式存儲系統(tǒng)。
有了這樣一個系統(tǒng),建造企業(yè)級的流處理系統(tǒng)變得相對簡單。我們就基于Pravega建造了一個可擴展的流批一體的流式搜索系統(tǒng):Pravega Search。
可以把Pravega Search看作是類似于Elasticsearch或者Splunk產(chǎn)品類似的搜索系統(tǒng)。它同樣可以針對注入數(shù)據(jù)創(chuàng)建索引,通過索引查詢提供搜索結(jié)果。但是,Pravega Search考慮流處理的特點,支持針對流數(shù)據(jù)的continuous query。在連續(xù)數(shù)據(jù)的不斷注入時,同時給出實時的計算結(jié)果。這是Elasticsearch所沒有的。
這就是基于流存儲系統(tǒng)Pravega構(gòu)建流處理應用的便捷和優(yōu)勢。在批流一體的流水線上,Pravega stream作為數(shù)據(jù)管道,把上層一個個的計算單元耦合起來。比如圖中所示,用戶數(shù)據(jù)流入Pravega stream后,流入continuous query進行計算,計算結(jié)果數(shù)據(jù)又重新流回Pravega stream不斷套接。同時,不管是針對流處理的continuous query還是基于歷史數(shù)據(jù)的傳統(tǒng)批處理,數(shù)據(jù)只存儲了一份,避免了現(xiàn)在批流一體的大數(shù)據(jù)處理流水線上數(shù)據(jù)在多個不同集群之間重復復置存儲的問題。
綜上所述,隨著流處理的不斷發(fā)展,流存儲系統(tǒng)也從早期的基于傳統(tǒng)數(shù)據(jù)庫,到現(xiàn)在的新型架構(gòu)體系不斷發(fā)展,并且依然擁有廣闊的發(fā)展前景。
在未來流存儲系統(tǒng)的發(fā)展藍圖里,message系統(tǒng)已經(jīng)不能完全滿足技術(shù)發(fā)展對于流存儲系統(tǒng)的所有幻想。Pravega應流存儲系統(tǒng)需求而生,提供純粹的流存儲抽象,旨在促進批流一體的大數(shù)據(jù)流處理系統(tǒng)的發(fā)展。
作為CNCF的大數(shù)據(jù)流處理生態(tài)中的一員,Pravega和其他開源流處理系統(tǒng)例如Flink,必將給大數(shù)據(jù)流處理領(lǐng)域發(fā)展帶來新的色彩,讓我們拭目以待!
活動推薦:
僅需99元即可體驗阿里云基于 Apache Flink 構(gòu)建的企業(yè)級產(chǎn)品-實時計算 Flink 版!點擊下方鏈接了解活動詳情:https://www.aliyun.com/product/bigdata/sc?utm_content=g_1000250506
原文鏈接:https://developer.aliyun.com/article/782707?
版權(quán)聲明:本文內(nèi)容由阿里云實名注冊用戶自發(fā)貢獻,版權(quán)歸原作者所有,阿里云開發(fā)者社區(qū)不擁有其著作權(quán),亦不承擔相應法律責任。具體規(guī)則請查看《阿里云開發(fā)者社區(qū)用戶服務協(xié)議》和《阿里云開發(fā)者社區(qū)知識產(chǎn)權(quán)保護指引》。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,填寫侵權(quán)投訴表單進行舉報,一經(jīng)查實,本社區(qū)將立刻刪除涉嫌侵權(quán)內(nèi)容。總結(jié)
以上是生活随笔為你收集整理的Stream is the new file的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何做一场高质量的分享?
- 下一篇: 云原生数据湖分析DLA 2020年年度总