两个服务器之间怎么传输大量数据速度快 java socket_一口气说出Kafka为啥这么快?...
在過(guò)去的幾年里,軟件架構(gòu)領(lǐng)域發(fā)生了巨大的變化。人們不再認(rèn)為所有的系統(tǒng)都應(yīng)該共享一個(gè)數(shù)據(jù)庫(kù)。
圖片來(lái)自 Pexels
微服務(wù)、事件驅(qū)動(dòng)架構(gòu)和 CQRS(命令查詢的責(zé)任分離 Command Query Responsibility Segregation)是構(gòu)建當(dāng)代業(yè)務(wù)應(yīng)用程序的主要工具。
除此以外,物聯(lián)網(wǎng)、移動(dòng)設(shè)備和可穿戴設(shè)備的普及,進(jìn)一步對(duì)系統(tǒng)的近實(shí)時(shí)能力提出了挑戰(zhàn)。
首先讓我們對(duì)“快”這個(gè)詞達(dá)成共識(shí),這個(gè)詞是多方面的、復(fù)雜的、高度模糊的。一種解釋是把”延遲、吞吐量和抖動(dòng)“作為對(duì)“快”的衡量指標(biāo)。
還有,比如工業(yè)應(yīng)用領(lǐng)域,行業(yè)本身設(shè)置了對(duì)于“快”的規(guī)范和期望。所以,“快”在很大程度上取決于你的參照體系是什么。
Apache Kafka 以犧牲延遲和抖動(dòng)為代價(jià)優(yōu)化了吞吐量,但并沒(méi)有犧牲,比如持久性、嚴(yán)格的記錄有序性和至少一次的分發(fā)語(yǔ)義。
當(dāng)有人說(shuō)“Kafka 速度很快”,并假設(shè)他們至少有一定的能力時(shí),你可以認(rèn)為他們指的是 Kafka 在短時(shí)間內(nèi)分發(fā)大量記錄的能力。
Kafka 誕生于 LinkedIn,當(dāng)時(shí) LinkedIn 需要高效地傳遞大量信息,相當(dāng)于每小時(shí)傳輸數(shù) TB 的數(shù)據(jù)量。
在當(dāng)時(shí),消息傳播的延遲被認(rèn)為是可以接受的。畢竟,LinkedIn 不是一家從事高頻交易的金融機(jī)構(gòu),也不是一個(gè)在確定期限內(nèi)運(yùn)行的工業(yè)控制系統(tǒng)。Kafka 可用于近實(shí)時(shí)系統(tǒng)。
注意:“實(shí)時(shí)”并不意味著“快”,它的意思是“可預(yù)測(cè)的”。具體來(lái)說(shuō),實(shí)時(shí)意味著完成一個(gè)動(dòng)作具有時(shí)間限制,也就是最后期限。
如果一個(gè)系統(tǒng)不能滿足這個(gè)要求,它就不能被歸類為”實(shí)時(shí)系統(tǒng)“。能夠容忍一定范圍內(nèi)延遲的系統(tǒng)被稱為“近實(shí)時(shí)”系統(tǒng)。從吞吐量的角度來(lái)說(shuō),實(shí)時(shí)系統(tǒng)通常比近實(shí)時(shí)或非實(shí)時(shí)系統(tǒng)要慢。
Kafka 在速度上有兩個(gè)重要的方面,需要單獨(dú)討論:
- 與客戶端與服務(wù)端之間的低效率實(shí)現(xiàn)有關(guān)。
- 源自于流處理的并行性。
服務(wù)端優(yōu)化
日志的存儲(chǔ)
Kafka 利用分段、追加日志的方式,在很大程度上將讀寫(xiě)限制為順序 I/O(sequential I/O),這在大多數(shù)的存儲(chǔ)介質(zhì)上都很快。人們普遍錯(cuò)誤地認(rèn)為硬盤很慢。
然而,存儲(chǔ)介質(zhì)的性能,很大程度上依賴于數(shù)據(jù)被訪問(wèn)的模式。同樣在一塊普通的 7200 RPM SATA 硬盤上,隨機(jī) I/O(random I/O)與順序 I/O 相比,隨機(jī) I/O 的性能要比順序 I/O 慢 3 到 4 個(gè)數(shù)量級(jí)。
此外,現(xiàn)代的操作系統(tǒng)提供了預(yù)先讀和延遲寫(xiě)的技術(shù),這些技術(shù)可以以塊為單位,預(yù)先讀取大量數(shù)據(jù),并將較小的邏輯寫(xiě)操作合并成較大的物理寫(xiě)操作。
因此,順序 I/O 和隨機(jī) I/O 之間的性能差異在閃存和其他固態(tài)非易失性介質(zhì)中仍然很明顯,不過(guò)它們?cè)谛D(zhuǎn)存儲(chǔ),比如固態(tài)硬盤中的性能差異就沒(méi)有那么明顯。
記錄的批處理
順序 I/O 在大多數(shù)存儲(chǔ)介質(zhì)上都非常快,可以與網(wǎng)絡(luò) I/O 的最高性能相媲美。在實(shí)踐中,這意味著一個(gè)設(shè)計(jì)良好的日志持久化層能跟上網(wǎng)絡(luò)的讀寫(xiě)速度。事實(shí)上,Kafka 的性能瓶頸通常并不在硬盤上,而是網(wǎng)絡(luò)。
因此,除了操作系統(tǒng)提供的批處理外,Kafka 的客戶端和服務(wù)端會(huì)在一個(gè)批處理中積累多個(gè)記錄——包括讀寫(xiě)記錄,然后在通過(guò)網(wǎng)絡(luò)發(fā)送出去。
記錄的批處理可以緩解網(wǎng)絡(luò)往返的開(kāi)銷,使用更大的數(shù)據(jù)包,提高帶寬的效率。
批量壓縮
當(dāng)啟用壓縮時(shí),對(duì)批處理的影響特別明顯,因?yàn)殡S著數(shù)據(jù)大小的增加,壓縮通常會(huì)變得更有效。
特別是在使用基于文本的格式時(shí),比如 JSON,壓縮的效果會(huì)非常明顯,壓縮比通常在 5x 到 7x 之間。
此外,記錄的批處理主要作為一個(gè)客戶端操作,負(fù)載在傳遞的過(guò)程中,不僅對(duì)網(wǎng)絡(luò)帶寬有積極影響,而且對(duì)服務(wù)端的磁盤 I/O 利用率也有積極影響。
便宜的消費(fèi)者
不同于傳統(tǒng)的消息隊(duì)列模型,當(dāng)消息被消費(fèi)時(shí)會(huì)刪除消息(會(huì)導(dǎo)致隨機(jī) I/O),Kafka 不會(huì)在消息被消費(fèi)后刪除它們——相反,它會(huì)獨(dú)立地跟蹤每個(gè)消費(fèi)者組的偏移量。
可以參考 Kafka 的內(nèi)部主題 __consumer_offsets 了解更多。同樣,由于只是追加操作,所以速度很快。消息的大小在后臺(tái)被進(jìn)一步減少(使用 Kafka 的壓縮特性),只保留任何給定消費(fèi)者組的最后已知偏移量。
將此模型與傳統(tǒng)的消息模型進(jìn)行對(duì)比,后者通常提供幾種不同的消息分發(fā)拓?fù)洹?/p>
一種是消息隊(duì)列——用于點(diǎn)對(duì)點(diǎn)消息傳遞的持久化傳輸,沒(méi)有點(diǎn)對(duì)多點(diǎn)功能。
另一種是發(fā)布訂閱主題允許點(diǎn)對(duì)多點(diǎn)消息通信,但這樣做的代價(jià)是持久性。在傳統(tǒng)消息隊(duì)列模型中實(shí)現(xiàn)持久化的點(diǎn)對(duì)多點(diǎn)消息通信模型需要為每個(gè)有狀態(tài)的使用者維護(hù)專用消息隊(duì)列。
這將放大讀寫(xiě)的消耗。消息生產(chǎn)者被迫將消息寫(xiě)入多個(gè)消息隊(duì)列中。另外一種選擇是使用扇出中繼,扇出中繼可以消費(fèi)來(lái)自一個(gè)隊(duì)列中的記錄,并將記錄寫(xiě)入其他多個(gè)隊(duì)列中,但這只會(huì)將延遲放大點(diǎn)。
并且,一些消費(fèi)者正在服務(wù)端上生成負(fù)載——讀和寫(xiě) I/O 的混合,既有順序的,也有隨機(jī)的。
Kafka 中的消費(fèi)者是“便宜的”,只要他們不改變?nèi)罩疚募?只有生產(chǎn)者或 Kafka 的內(nèi)部進(jìn)程被允許這樣做)。
這意味著大量消費(fèi)者可以并發(fā)地從同一主題讀取數(shù)據(jù),而不會(huì)使集群崩潰。添加一個(gè)消費(fèi)者仍然有一些成本,但主要是順序讀取夾雜很少的順序?qū)懭搿?/p>
因此,在一個(gè)多樣化的消費(fèi)者系統(tǒng)中,看到一個(gè)主題被共享是相當(dāng)正常的。
未刷新的緩沖寫(xiě)操作
Kafka 性能的另一個(gè)基本原因是,一個(gè)值得進(jìn)一步研究的原因:Kafka 在確認(rèn)寫(xiě)操作之前并沒(méi)有調(diào)用 fsync。ACK 的唯一要求是記錄已經(jīng)寫(xiě)入 I/O 緩沖區(qū)。
這是一個(gè)鮮為人知的事實(shí),但卻是一個(gè)至關(guān)重要的事實(shí)。實(shí)際上,這就是 Kafka 的執(zhí)行方式,就好像它是一個(gè)內(nèi)存隊(duì)列一樣——Kafka 實(shí)際上是一個(gè)由磁盤支持的內(nèi)存隊(duì)列(受緩沖區(qū)/頁(yè)面緩存大小的限制)。
但是,這種形式的寫(xiě)入是不安全的,因?yàn)楦北镜某鲥e(cuò)可能導(dǎo)致數(shù)據(jù)丟失,即使記錄似乎已經(jīng)被 ACK。
換句話說(shuō),與關(guān)系型數(shù)據(jù)庫(kù)不同,僅寫(xiě)入緩沖區(qū)并不意味著持久性。保證 Kafka 持久性的是運(yùn)行幾個(gè)同步的副本。
即使其中一個(gè)出錯(cuò)了,其他的(假設(shè)不止一個(gè))將繼續(xù)運(yùn)行——假設(shè)出錯(cuò)的原因不會(huì)導(dǎo)致其他的副本也出錯(cuò)。
因此,無(wú) fsync 的非阻塞 I/O 方法和冗余的同步副本組合為 Kafka 提供了高吞吐、持久性和可用性。
客戶端優(yōu)化
大多數(shù)數(shù)據(jù)庫(kù)、隊(duì)列和其他形式的持久性中間件都是圍繞全能服務(wù)器(或服務(wù)器集群)和瘦客戶端的概念設(shè)計(jì)的。
客戶端的實(shí)現(xiàn)通常被認(rèn)為比服務(wù)器端簡(jiǎn)單得多。服務(wù)器會(huì)處理大部分的負(fù)載,而客戶端僅充當(dāng)服務(wù)端的門面。
Kafka 采用了不同的客戶端設(shè)計(jì)方法。在記錄到達(dá)服務(wù)器之前,會(huì)在客戶端上執(zhí)行大量的工作。
這包括對(duì)累加器中的記錄進(jìn)行分段、對(duì)記錄鍵進(jìn)行散列以得到正確的分區(qū)索引、對(duì)記錄進(jìn)行校驗(yàn)以及對(duì)記錄批處理進(jìn)行壓縮。
客戶端知道集群元數(shù)據(jù),并定期刷新元數(shù)據(jù)以跟上服務(wù)端拓?fù)涞母摹_@讓客戶端更準(zhǔn)確的做出轉(zhuǎn)發(fā)決策。
不同于盲目地將記錄發(fā)送到集群并依靠后者將其轉(zhuǎn)發(fā)到適當(dāng)?shù)墓?jié)點(diǎn),生產(chǎn)者客戶端可以直接將寫(xiě)請(qǐng)求轉(zhuǎn)發(fā)到分區(qū)主機(jī)。
類似地,消費(fèi)者客戶端能夠在獲取記錄時(shí)做出更明智的決定,比如在發(fā)出讀查詢時(shí),可以使用在地理上更接近消費(fèi)者客戶端的副本。(該特性是從 Kafka 的 2.4.0 版本開(kāi)始提供。)
零拷貝
一種典型的低效方式是在緩沖之間復(fù)制字節(jié)數(shù)據(jù)。Kafka 使用由生產(chǎn)者、消費(fèi)者、服務(wù)端三方共享的二進(jìn)制消息格式,這樣即使數(shù)據(jù)塊被壓縮了,也可以不加修改地傳遞數(shù)據(jù)。
雖然消除通信方之間的數(shù)據(jù)結(jié)構(gòu)差異是重要的一步,但它本身并不能避免數(shù)據(jù)的復(fù)制。
Kafka 使用 Java 的 NIO 框架,特別是 java.nio.channels.FileChannel 的 transferTo() 方法,在 Linux 和 UNIX 系統(tǒng)上解決了這個(gè)問(wèn)題。
此方法允許字節(jié)從源通道傳輸?shù)浇邮胀ǖ?#xff0c;而不需要將應(yīng)用程序作為傳輸中介。
了解 NIO 的不同之處,請(qǐng)思考傳統(tǒng)的方法會(huì)怎么做,將源通道讀入字節(jié)緩沖區(qū),然后作為兩個(gè)獨(dú)立的操作寫(xiě)入接收器通道:
File.read(fileDesc,?buf,?len);?Socket.send(socket,?buf,?len);?可以用下圖來(lái)表示:
雖然這副圖看起來(lái)很簡(jiǎn)單,但是在內(nèi)部,復(fù)制操作需要在用戶態(tài)和內(nèi)核態(tài)之間進(jìn)行四次上下文切換,并且在操作完成之前要復(fù)制四次數(shù)據(jù)。
下圖概述了每次步驟的上下文切換:
詳細(xì)說(shuō)明:
- 初始的 read() 方法導(dǎo)致上下文從用戶態(tài)切換到內(nèi)核態(tài)。文件被讀取,它的內(nèi)容被 DMA(Direct Memory Access 直接存儲(chǔ)器訪問(wèn))引擎復(fù)制到內(nèi)核地址空間中的緩沖區(qū)。這與代碼段中使用的緩沖區(qū)是不同的。
- 在 read() 方法返回之前,將數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到用戶空間緩沖區(qū)。此時(shí),我們的應(yīng)用程序可以讀取文件的內(nèi)容了。
- 隨后的 send() 方法將切回到內(nèi)核態(tài),將數(shù)據(jù)從用戶空間緩沖區(qū)復(fù)制到內(nèi)核地址空間——這一次是將數(shù)據(jù)復(fù)制到與目標(biāo)套接字相關(guān)聯(lián)的另一個(gè)緩沖區(qū)中。在后臺(tái),由 DMA 引擎接管,異步地將數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到協(xié)議棧。send() 方法在返回之前不會(huì)等待這個(gè)操作完成。
- send() 方法調(diào)用返回,切回用戶態(tài)。
盡管用戶態(tài)與內(nèi)核態(tài)之間的上下文切換效率很低,而且還需要進(jìn)行額外的復(fù)制,但在許多情況下,它可以提高性能。
它可以充當(dāng)預(yù)讀緩存,異步預(yù)讀取,從而提前運(yùn)行來(lái)自應(yīng)用程序的請(qǐng)求。但是,當(dāng)請(qǐng)求的數(shù)據(jù)量遠(yuǎn)遠(yuǎn)大于內(nèi)核緩沖區(qū)的大小時(shí),內(nèi)核緩沖區(qū)就成為了性能瓶頸。
不同于直接復(fù)制數(shù)據(jù),而是迫使系統(tǒng)在用戶態(tài)和內(nèi)核態(tài)之間頻繁切換,直到所有數(shù)據(jù)都被傳輸。
相比之下,零拷貝方法是在單個(gè)操作中處理的。前面例子中的代碼可以改寫(xiě)為一行代碼:
fileDesc.transferTo(offset,?len,?socket);?下面詳細(xì)解釋說(shuō)明是零拷貝:
在這個(gè)模型中,上下文切換的數(shù)量減少到一個(gè)。具體來(lái)說(shuō),transferTo() 方法指示塊設(shè)備通過(guò) DMA 引擎將數(shù)據(jù)讀入讀緩沖區(qū)。
然后,將數(shù)據(jù)從讀緩沖區(qū)復(fù)制到套接字緩沖區(qū)。最后,通過(guò) DMA 將數(shù)據(jù)從套接字緩沖區(qū)復(fù)制到 NIC 緩沖區(qū)。
因此,我們將復(fù)制的數(shù)量從 4 個(gè)減少到 3 個(gè),并且其中只有一個(gè)復(fù)制操作涉及到 CPU。我們還將上下文切換的數(shù)量從 4 個(gè)減少到 2 個(gè)。
這是一個(gè)巨大的改進(jìn),但還不是查詢零拷貝。在運(yùn)行 Linux 內(nèi)核 2.4 或更高版本時(shí),以及在支持 gather 操作的網(wǎng)卡上,可以進(jìn)一步優(yōu)化。
如下圖所示:
按照前面的示例,調(diào)用 transferTo() 方法會(huì)導(dǎo)致設(shè)備通過(guò) DMA 引擎將數(shù)據(jù)讀入內(nèi)核緩沖區(qū)。
但是,對(duì)于 gather 操作,讀緩沖區(qū)和套接字緩沖區(qū)之間不存在復(fù)制。相反,NIC被賦予一個(gè)指向讀緩沖區(qū)的指針,連同偏移量和長(zhǎng)度。在任何情況下,CPU 都不涉及復(fù)制緩沖區(qū)。
文件大小從幾 MB 到 1GB 的范圍內(nèi),傳統(tǒng)拷貝和零拷貝相比,結(jié)果顯示零拷貝的性能提高了兩到三倍。
但更令人印象深刻的是,Kafka 使用純 JVM 實(shí)現(xiàn)了這一點(diǎn),沒(méi)有本地庫(kù)或 JNI 代碼。
避免垃圾回收
大量使用通道、緩沖區(qū)和頁(yè)面緩存還有一個(gè)額外的好處——減少垃圾收集器的工作負(fù)載。
例如,在 32 GB RAM 的機(jī)器上運(yùn)行 Kafka 將產(chǎn)生 28-30 GB 的頁(yè)面緩存可用空間,完全超出了垃圾收集器的范圍。
吞吐量的差異非常小(大約幾個(gè)百分點(diǎn)),但是經(jīng)過(guò)正確調(diào)優(yōu)的垃圾收集器的吞吐量可能非常高,特別是在處理短生存期對(duì)象時(shí)。真正的收益在于減少抖動(dòng)。
通過(guò)避免垃圾回收,服務(wù)端不太可能遇到因垃圾回收引起的程序暫停,從而影響客戶端,加大記錄的通信延遲。
與初期的 Kafka 相比,現(xiàn)在避免垃圾回收已經(jīng)不是什么問(wèn)題了。像 Shenandoah 和 ZGC 這樣的現(xiàn)代垃圾收集器可以擴(kuò)展到巨大的、多 TB 級(jí)的堆,在最壞的情況下,并且可以自動(dòng)調(diào)整垃圾收集的暫停時(shí)間,降到幾毫秒。
現(xiàn)在,可以看見(jiàn)大量的基于 Java 虛擬機(jī)的應(yīng)用程序使用堆緩存,而不是堆外緩存。
流處理的并行性
日志的 I/O 效率是性能的一個(gè)重要方面,主要的性能影響在于寫(xiě)。Kafka 對(duì)主題結(jié)構(gòu)和消費(fèi)生態(tài)系統(tǒng)中的并行性處理是其讀性能的基礎(chǔ)。
這種組合產(chǎn)生了整體非常高的端到端消息吞吐量。將并發(fā)性深入到分區(qū)方案和使用者組的操作中,這實(shí)際上是 Kafka 中的一種負(fù)載均衡機(jī)制——將分區(qū)平均地分配到各個(gè)消費(fèi)者中。
將此與傳統(tǒng)的消息隊(duì)列進(jìn)行比較:在 RabbitMQ 的設(shè)置中,多個(gè)并發(fā)的消費(fèi)者可以以輪詢的方式從隊(duì)列中讀取數(shù)據(jù),但這樣做會(huì)喪失消息的有序性。
分區(qū)機(jī)制有利于 Kafka 服務(wù)端的水平擴(kuò)展。每個(gè)分區(qū)都有一個(gè)專門的領(lǐng)導(dǎo)者。因此,任何重要的多分區(qū)的主題都可以利用整個(gè)服務(wù)端集群進(jìn)行寫(xiě)操作。
這是 Kafka 和傳統(tǒng)消息隊(duì)列的另一個(gè)區(qū)別。當(dāng)后者利用集群來(lái)提高可用性時(shí),Kafka 通過(guò)負(fù)載均衡來(lái)提高可用性、持久性和吞吐量。
發(fā)布具有多個(gè)分區(qū)的主題時(shí),生產(chǎn)者指定發(fā)布記錄時(shí)的分區(qū)。(可能有一個(gè)單分區(qū)主題,那就不是問(wèn)題了)
可以通過(guò)指定分區(qū)索引直接完成,或通過(guò)記錄鍵間接完成,記錄鍵通過(guò)計(jì)算散列值確定分區(qū)索引。具有相同散列值的記錄共享相同的分區(qū)。
假設(shè)一個(gè)主題有多個(gè)分區(qū),那么具有不同鍵的記錄可能會(huì)出現(xiàn)在不同的分區(qū)中。
然而,由于散列沖突,具有不同散列值的記錄也可能最終出現(xiàn)在同一個(gè)分區(qū)中。這就是散列的本質(zhì)。如果你理解了散列表的工作方式,一切都很自然了。
記錄的實(shí)際處理由消費(fèi)者完成,在一個(gè)可選的消費(fèi)者組中完成。Kafka 保證一個(gè)分區(qū)最多只能分配給消費(fèi)者組中的一個(gè)消費(fèi)者。(為什么用”最多“,當(dāng)所有消費(fèi)者都離線時(shí),那就是 0 個(gè)消費(fèi)者了)
當(dāng)組中的第一個(gè)消費(fèi)者訂閱主題時(shí),它將接收該主題上的所有分區(qū)。當(dāng)?shù)诙€(gè)消費(fèi)者訂閱主題時(shí),它將接收到大約一半的分區(qū),從而減輕第一個(gè)消費(fèi)者的負(fù)載。
根據(jù)需要添加消費(fèi)者(理想情況下,使用自動(dòng)伸縮機(jī)制),這使你能夠并行地處理事件流,前提是你已經(jīng)對(duì)事件流進(jìn)行了分區(qū)。
以兩種方式控制記錄的吞吐量:
①主題分區(qū)方案。應(yīng)該對(duì)主題進(jìn)行分區(qū),最大化事件流的數(shù)量。換句話說(shuō),只有在絕對(duì)需要時(shí)才提供記錄的順序。
如果任何兩個(gè)記錄不存在關(guān)聯(lián),它們就不應(yīng)該被綁定到同一個(gè)分區(qū)。這意味著要使用不同的鍵,因?yàn)?Kafka 使用記錄鍵的散列值作為分區(qū)映射的根據(jù)。
②組中消費(fèi)者的數(shù)量。你可以增加消費(fèi)者的數(shù)量來(lái)均衡入站記錄的負(fù)載,消費(fèi)者的數(shù)量最多可以增加到和分區(qū)數(shù)量一樣多。(你可以增加更多的消費(fèi)者,但每個(gè)分區(qū)最多只能有一個(gè)的活動(dòng)消費(fèi)者,剩下的消費(fèi)者將處于閑置狀態(tài))
請(qǐng)注意,你可以提供一個(gè)線程池,根據(jù)消費(fèi)者執(zhí)行工作負(fù)載的不同,消費(fèi)者可以是一個(gè)進(jìn)程或一個(gè)線程。
如果你想知道 Kafka 為什么這么快,它是如何做到的,以及它是否適合你,我想你現(xiàn)在已經(jīng)有了答案了。
為了更清楚地說(shuō)明問(wèn)題,Kafka 不是最快的消息中間件,吞吐量也不是最大的。有其他平臺(tái)能夠提供更高的吞吐量——有些是基于軟件的,有些是基于硬件的。
很難同時(shí)做到吞吐量大且延遲低,Apache Pulsar[1] 是一個(gè)有前途的技術(shù),可擴(kuò)展,更好的吞吐量-延遲配置文件,同時(shí)提供順序性和持久性。
采用 Kafka 的理由是,作為一個(gè)完整的生態(tài)系統(tǒng),它在整體上仍然是無(wú)與倫比的。
它展示了出色的性能,同時(shí)提供了一個(gè)豐富和成熟的環(huán)境,Kafka 仍在以令人羨慕的速度增長(zhǎng)。
Kafka 的設(shè)計(jì)者和維護(hù)者在設(shè)計(jì)一個(gè)以性能為核心的解決方案時(shí)做了大量的工作。它的設(shè)計(jì)元素中很少有讓人覺(jué)得是事后才想到的,或者是補(bǔ)全的。
從將工作負(fù)載轉(zhuǎn)移到客戶端,到服務(wù)端日志的持久性、批處理、壓縮、零拷貝 I/O 和并行流處理——Kafka 向任何其他消息中間件廠商發(fā)起挑戰(zhàn),無(wú)論是商業(yè)的還是開(kāi)源的。
最令人印象深刻的是,它做到了這一點(diǎn),卻沒(méi)有犧牲持久性、記錄有序性和至少一次分發(fā)的語(yǔ)義。
Kafka 不是最簡(jiǎn)單的消息中間件平臺(tái),還有許多需要改進(jìn)的地方。在設(shè)計(jì)和構(gòu)建高性能事件驅(qū)動(dòng)系統(tǒng)之前,必須掌握總體和部分的順序、主題、分區(qū)、消費(fèi)者和消費(fèi)者組的概念。
雖然知識(shí)曲線很陡峭,但值得你花時(shí)間去學(xué)習(xí)。如果你知道這個(gè)諺語(yǔ)“red pill”(red pill,指為了達(dá)到對(duì)某種事物的深度探索或追求,選擇去思考,不放棄,繼續(xù)走下去,哪怕這條路多難走),請(qǐng)閱讀“介紹 Kafka 和 Kafdrop 中的事件流 Introduction to Event Streaming with Kafka and Kafdrop[2]”。
相關(guān)鏈接:
- https://pulsar.apache.org/
- https://medium.com/swlh/introduction-to-event-streaming-with-kafka-and-kafdrop-22afdb4b380a
作者:鐘濤編譯
來(lái)源:分布式實(shí)驗(yàn)室
總結(jié)
以上是生活随笔為你收集整理的两个服务器之间怎么传输大量数据速度快 java socket_一口气说出Kafka为啥这么快?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: oracle 监听程序当前无法识别连接描
- 下一篇: echarts柱状图显示百分比_Echa