發(fā)布于:2021-01-21 10:38:08
0
178
0
在這篇文章中,我們將介紹有關Java8流、Hadoop、ApacheSpark、Quasar光纖和反應式編程方法的一些您需要了解的知識,并幫助您保持循環(huán),特別是在您不經(jīng)常使用它們的情況下。這不是未來,而是現(xiàn)在。
我們在處理什么?
在談到并發(fā)性時,描述當前問題的一個好方法是回答幾個問題以更好地理解它:
這是一項數(shù)據(jù)處理任務嗎?如果是的話,它能被分解成獨立的作品嗎?
操作系統(tǒng)、JVM和代碼之間的關系是什么?(本機線程與輕量級線程)
涉及多少臺機器和處理器?(單核與多核)
讓我們逐一分析一下,找出每種方法的最佳用例。
1.從線程池到并行流
在單機上進行數(shù)據(jù)處理,讓Java負責線程處理。
在Java8中,我們引入了新的流API,它允許對數(shù)據(jù)流應用聚合操作,如過濾、排序或映射。流允許的另一件事是在應用.parallelStream()時在多核機器上進行并行操作——使用Java7中引入的Fork/Join框架在線程之間分割工作。Java6的一個演變java.util.concurrency在庫中,我們遇到了創(chuàng)建和處理工作線程池的ExecutorService。
Fork/Join也構建在ExecuterService之上,與傳統(tǒng)線程池的主要區(qū)別在于它們如何在線程之間分配工作,從而支持多核機器。通過一個簡單的ExecuterService,您可以完全控制工作線程之間的工作負載分配,確定線程要處理的每個任務的大小。另一方面,在Fork/Join中,有一個工作竊取算法,可以抽象線程之間的工作負載處理。簡而言之,這允許將大型任務劃分為較小的任務(分叉),并在不同的線程中進行處理,最終合并結果—平衡線程之間的工作。然而,這不是一個銀彈。
有時平行流甚至會減慢你的速度,所以你需要好好想想。將.parallelStream()添加到方法中可能會導致瓶頸和速度減慢(在我們運行的這個基準測試中大約慢了15%),細線穿過線程的數(shù)量。假設我們已經(jīng)運行了多個線程,并且在其中一些線程中使用了.parallelStream(),向池中添加了越來越多的線程。這很容易變成超出我們的核心所能處理的,并且由于增加了上下文切換而減慢了一切。
底線:并行流在一臺機器上抽象處理線程,在核心之間分配工作負載。但是,如果您想有效地使用它們,請務必記住硬件不會產(chǎn)生超出您的機器所能處理的線程數(shù)。
2.apachehadoop和apachespark
重型起重:跨多臺機器的大數(shù)據(jù)處理。
接下來是多臺機器、數(shù)PB的數(shù)據(jù)和類似于從twitter或重型機器學習算法中提取所有提到Java的推文的任務。說到Hadoop,重要的是要采取另一個步驟并考慮更廣泛的框架及其組件:Hadoop分布式文件系統(tǒng)(HDFS)、資源管理平臺(YARN)、數(shù)據(jù)處理模塊(MapReduce)以及Hadoop所需的其他庫和實用程序(Common)。除此之外,還有其他可選工具,如運行在HDFS(HBase)之上的數(shù)據(jù)庫、查詢語言平臺(Pig)和數(shù)據(jù)倉庫基礎設施(Hive)等。
這就是apachespark作為一個新的數(shù)據(jù)處理模塊介入的地方,它以內存性能和使用快速執(zhí)行的彈性分布式數(shù)據(jù)集(RDDs)而聞名,不像Hadoop MapReduce那樣高效地使用內存(和磁盤)操作。Databricks發(fā)布的最新基準測試顯示,Spark在對PB級數(shù)據(jù)進行排序時比Hadoop快3倍,而使用的節(jié)點則少10倍。
Hadoop的經(jīng)典用例是查詢數(shù)據(jù),而Spark則以其快速運行的機器學習算法而聞名。但這只是冰山一角,正如Databricks所說:“Spark使Hadoop集群中的應用程序在內存中的運行速度提高了100倍,甚至在磁盤上運行時也提高了10倍”。
底線:Spark是Hadoop生態(tài)系統(tǒng)中的新星。有一種常見的誤解,認為我們談論的是一些不相關或相互競爭的東西,但我相信我們在這里看到的是框架的演變。
3.類星體纖維
將本機線程中斷為虛擬輕量級線程。
我們已經(jīng)有機會運行Hadoop,現(xiàn)在讓我們回到單機。事實上,讓我們進一步放大標準的多線程Java應用程序,并將重點放在單個線程上。就我們而言,HotSpot JVM線程與本機OS線程是一樣的,只持有一個線程并在其中運行“虛擬”線程是fibres的全部內容。Java沒有本機的光纖支持,但不用擔心,平行宇宙的類星體讓我們得到了覆蓋。
Quasar是一個開源JVM庫,它支持fibers(也稱為輕量級線程),還充當Actor框架,稍后我將提到它。上下文切換是游戲的名字。由于我們受到內核數(shù)量的限制,一旦本機線程數(shù)量增加,我們就會承受越來越多的上下文切換開銷。解決這一問題的一種方法是使用支持“多線程”的單線程進行光纖傳輸。看起來像是Threadception的病例。
光纖也可以看作是線程池的一種演變,它避免了我們在并行流中遇到的線程過載的危險。它們使擴展線程變得更容易,并允許大量并發(fā)的“輕”線程。它們不是用來替換線程的,應該用于相對頻繁地阻塞的代碼,就像它們充當真正的異步線程一樣。
底線:Parallel Universe為Java中的并發(fā)提供了一種新的方法,雖然還沒有達到v1.0,但絕對值得一試。
4.參與者和反應式編程
使用Java處理并發(fā)的其他模型。
在反應宣言中,新的運動被描述為4個原則:反應、彈性、彈性和信息驅動。這基本上意味著快速、容錯、可擴展和支持無阻塞通信。
讓我們看看阿克卡演員是如何支持這一點的。為了簡化事情,可以把參與者想象成具有某種狀態(tài)和某種行為的人,通過交換發(fā)往對方郵箱的消息來進行交流。作為一個整體,應該為每個應用程序創(chuàng)建一個Actor系統(tǒng),其層次結構將任務分解為更小的任務,這樣每個Actor最多只有一個監(jiān)控Actor。參與者可以處理任務,將任務進一步分解并委托給另一個參與者,或者在失敗的情況下,將任務升級到其主管。無論哪種方式,消息都不應該包含行為或共享可變狀態(tài),每個參與者都有自己的獨立狀態(tài)和行為。
這是從大多數(shù)開發(fā)人員習慣的并發(fā)模型的范例轉變。我們在這里討論的前三個主題中的進化有點偏離了。雖然它的起源可以追溯到70年代,但直到最近幾年,它的復興才開始受到關注,以更好地適應現(xiàn)代應用需求。平行宇宙的類星體也支持Actor,基于它的輕量級線程。實現(xiàn)上的主要區(qū)別在于光纖/輕量級線程。
底線:采用Actor模型可以減少對線程池的管理,而將其留給工具箱。興趣的復興來自于應用程序今天處理的問題,即具有更多內核的高度并發(fā)系統(tǒng)。
結論
我們已經(jīng)介紹了四種使用并行或并行算法解決問題的方法,其中最有趣的方法是解決當今的挑戰(zhàn)。希望這有助于激發(fā)您的興趣,更好地了解今天并發(fā)的熱門話題。
除了線程池之外,現(xiàn)在有一種趨勢,就是將這一點負責任地委托給語言及其工具—將開發(fā)人員的資源集中在發(fā)布新功能上,而不是花費無數(shù)的時間來解決競爭條件和鎖。
Java/Scala開發(fā)人員?Takipi檢測代碼中的所有異常和錯誤,并告訴您它們發(fā)生的原因。只需1分鐘即可安裝:請嘗試Takipi。