最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

分布式技術(shù)原理與實(shí)戰(zhàn)45講--第31講:消息隊(duì)列選型:Kafka 如何實(shí)現(xiàn)高性能

2023-02-22 20:51 作者:gzqhero  | 我要投稿

在分布式消息模塊的最后 2 個課時(shí)中,我將對消息隊(duì)列中應(yīng)用最廣泛的 Kafka 和 RocketMQ 進(jìn)行梳理,以便于你在應(yīng)用中可以更好地進(jìn)行消息隊(duì)列選型。另外,這兩款消息隊(duì)列也是面試的高頻考點(diǎn)。

所以,這一課時(shí)我們就一起來看一下,Kafka 是如何實(shí)現(xiàn)高性能的。

Kafka 的高性能

不知道你有沒有了解過自己電腦的配置?

我們一般會認(rèn)為高性能是和高配置聯(lián)系在一起的,比如大內(nèi)存比小內(nèi)存快,8 核的機(jī)器比 4 核的機(jī)器快。我身邊也有一些朋友是攢機(jī)愛好者,對各種硬件配置如數(shù)家珍。

對于服務(wù)器來說,家用電腦的性能與配置的關(guān)系也同樣適用——價(jià)格更昂貴的服務(wù)器會有更好的性能——這并不是一件需要大張旗鼓去講述的事情。但 Kafka 所實(shí)現(xiàn)的高性能不需要太高配置的機(jī)器,它使用普通服務(wù)器就能實(shí)現(xiàn) TB 級別的傳輸性能。這一點(diǎn)也是 Kafka 對外宣傳的一個特性,也正是因?yàn)檫@一點(diǎn),Kafka 被廣泛運(yùn)用于大數(shù)據(jù)處理、流式計(jì)算、各類日志監(jiān)控等需要處理海量數(shù)據(jù)的場景。

Kafka 實(shí)現(xiàn)高性能的手段,是面試中經(jīng)常被問到的問題。下面我從 Kafka 的磁盤讀寫、批量優(yōu)化、零拷貝等方面,對 Kafka 的高性能特性進(jìn)行分析。

分析 Kafka 的高性能會涉及操作系統(tǒng)的一些知識,比如文件系統(tǒng)、PageCache等,作為大學(xué)計(jì)算機(jī)專業(yè)的必修課,這些概念就不展開了。如果你覺得這方面比較生疏,可以回顧下操作系統(tǒng)課程的相關(guān)知識,找一些經(jīng)典教材來學(xué)習(xí)。

磁盤順序讀寫

Kafka 消息是存儲在磁盤上的,大家都知道,普通的機(jī)械磁盤讀取是比較慢的,那 Kafka 文件在磁盤上,如何實(shí)現(xiàn)高性能的讀寫呢?

Kafka 對磁盤的應(yīng)用,得益于消息隊(duì)列的存儲特性。與普通的關(guān)系型數(shù)據(jù)庫、各類 NoSQL 數(shù)據(jù)庫等不同,消息隊(duì)列對外提供的主要方法是 生產(chǎn)和消費(fèi),不涉及數(shù)據(jù)的 CRUD。所以在寫入磁盤時(shí),可以使用順序追加的方式來避免低效的磁盤尋址。

我們知道,數(shù)據(jù)存儲在硬盤上,而硬盤有機(jī)械硬盤和固態(tài)硬盤之分。機(jī)械硬盤成本低、容量大,但每次讀寫都會尋址,再寫入數(shù)據(jù)(在機(jī)械硬盤上,尋址是一個物理動作,耗時(shí)最大);SSD 固態(tài)硬盤性能很高,有著非常低的尋道時(shí)間和存取時(shí)間,但成本也特別高。

為了提高在機(jī)械硬盤上讀寫的速度,Kafka 使用了順序讀寫。在一個分區(qū)內(nèi),Kafka 采用 append 的方式進(jìn)行順序?qū)懭?,這樣即使是普通的機(jī)械磁盤,也可以有很高的性能。

除了順序讀寫,在提到磁盤寫入的時(shí)候,還有一個問題避免不了,那就是何時(shí)進(jìn)行刷盤。

在 Linux 系統(tǒng)中,當(dāng)我們把數(shù)據(jù)寫入文件系統(tǒng)之后,其實(shí)數(shù)據(jù)是存放在操作系統(tǒng)的 page cache 里面,并沒有刷到磁盤上,如果服務(wù)器宕機(jī),數(shù)據(jù)就丟失了。

寫到磁盤的過程叫作 Flush。刷盤一般有兩種方式,一種是依靠操作系統(tǒng)進(jìn)行管理,定時(shí)刷盤,另一種則是同步刷盤,比如調(diào)用 fsync 等系統(tǒng)函數(shù)。

同步刷盤保證了數(shù)據(jù)的可靠性,但是會降低整體性能。Kafka 可以配置異步刷盤,不開啟同步刷盤,異步刷盤不需要等寫入磁盤后返回消息投遞的 ACK,所以它提高了消息發(fā)送的吞吐量,降低了請求的延時(shí),這也是 Kafka 磁盤高性能的一個原因。

批量操作優(yōu)化

批量是一個常見的優(yōu)化思路,比如大家熟悉的 Redis,就實(shí)現(xiàn)了 pipeline 管道批量操作。Kafka 在很多地方也應(yīng)用了批量操作進(jìn)行性能優(yōu)化。

Kafka 的批量包括批量寫入、批量發(fā)布等。它在消息投遞時(shí)會將消息緩存起來,然后批量發(fā)送;同樣,消費(fèi)端在消費(fèi)消息時(shí),也不是一條一條處理的,而是批量進(jìn)行拉取,提高了消息的處理速度。

除了批量以外,Kafka 的數(shù)據(jù)傳輸還可以配置壓縮協(xié)議,比如 Gzip 和 Snappy 壓縮協(xié)議。雖然在進(jìn)行數(shù)據(jù)壓縮時(shí)會消耗少量的 CPU 資源,但可以減少網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)大小、優(yōu)化網(wǎng)絡(luò) IO、提升傳輸速率。

Sendfile 零拷貝

零拷貝是什么?它是操作系統(tǒng)文件讀寫的一種技術(shù)。

零拷貝不是不需要拷貝,而是減少不必要的拷貝次數(shù),這里會涉及 Linux 用戶態(tài)和內(nèi)核態(tài)的區(qū)別。

用戶進(jìn)程是運(yùn)行在用戶空間的,不能直接操作內(nèi)核緩沖區(qū)的數(shù)據(jù)。所以在用戶進(jìn)程進(jìn)行系統(tǒng)調(diào)用的時(shí)候,會由用戶態(tài)切換到內(nèi)核態(tài),待內(nèi)核處理完之后再返回用戶態(tài)。

傳統(tǒng)的 IO 流程,需要先把數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū),再從內(nèi)核緩沖拷貝到用戶空間,應(yīng)用程序處理完成以后,再拷貝回內(nèi)核緩沖區(qū)。這個過程中發(fā)生了多次數(shù)據(jù)拷貝。

為了減少不必要的拷貝,Kafka 依賴 Linux 內(nèi)核提供的 Sendfile 系統(tǒng)調(diào)用。 在 Sendfile 方法中,數(shù)據(jù)在內(nèi)核緩沖區(qū)完成輸入和輸出,不需要拷貝到用戶空間處理,這也就避免了重復(fù)的數(shù)據(jù)拷貝。在具體的操作中,Kafka 把所有的消息都存放在單獨(dú)的文件里,在消息投遞時(shí)直接通過 Sendfile 方法發(fā)送文件,減少了上下文切換,因此大大提高了性能。

MMAP 技術(shù)

Kafka 是使用 Scala 語言開發(fā)的。Scala 運(yùn)行在 Java 虛擬機(jī)上,也就是說 Kafka 節(jié)點(diǎn)運(yùn)行需要 JVM 的支持,但是 Kafka 并不直接依賴 JVM 堆內(nèi)存。如果 Kafka 所有的數(shù)據(jù)操作都在堆內(nèi)存中進(jìn)行,則會對堆內(nèi)存造成非常大的壓力,影響垃圾回收處理,增加 JVM 的停頓時(shí)間和整體延遲。

因此,除了 Sendfile 之外,還有一種零拷貝的實(shí)現(xiàn)技術(shù),即 Memory Mapped Files。

Kafka 使用 Memory Mapped Files 完成內(nèi)存映射,Memory Mapped Files 對文件的操作不是 write/read,而是直接對內(nèi)存地址的操作。如果是調(diào)用文件的 read 操作,則把數(shù)據(jù)先讀取到內(nèi)核空間中,然后再復(fù)制到用戶空間。 但 MMAP 可以將文件直接映射到用戶態(tài)的內(nèi)存空間,省去了用戶空間到內(nèi)核空間復(fù)制的開銷,所以說 MMAP 也是一種零拷貝技術(shù)。

那 MMAP 和上面的 Sendfile 有什么區(qū)別呢?

MMAP 和 Sendfile 并沒有本質(zhì)上的區(qū)別,它們都是零拷貝的實(shí)現(xiàn)。零拷貝是一種技術(shù)思想,除了我們說到的這兩種,還有DMA,以及緩沖區(qū)共享等方式,感興趣的同學(xué)可以去擴(kuò)展了解一下。

總結(jié)

這一課時(shí)講解了 Kafka 如何實(shí)現(xiàn)高性能,介紹了順序讀寫、批量優(yōu)化、零拷貝等技術(shù),對于大部分業(yè)務(wù)開發(fā)的同學(xué),這部分知識了解即可。

Kafka 的高性能實(shí)現(xiàn)原理,在很多地方都有應(yīng)用,比如 Netty 中也有零拷貝技術(shù)。Linux 中,一切皆文件,Netty 關(guān)注的是網(wǎng)絡(luò) IO 的傳輸,Kafka 等存儲關(guān)注的是文件 IO 的傳輸,但在操作系統(tǒng)中都是 IO 操作,在優(yōu)化手段上非常類似。

另外,上面提到的 Sendfile 可以大幅提升文件傳輸性能,在 Apache、Nginx 等 Web 服務(wù)器當(dāng)中,都有相關(guān)的應(yīng)用。感興趣的同學(xué)可以了解下 Netty 等網(wǎng)絡(luò)組件的性能優(yōu)化方式,歡迎留言進(jìn)行分享。


分布式技術(shù)原理與實(shí)戰(zhàn)45講--第31講:消息隊(duì)列選型:Kafka 如何實(shí)現(xiàn)高性能的評論 (共 條)

分享到微博請遵守國家法律
昌邑市| 汝州市| 长乐市| 三河市| 潼关县| 盘山县| 祁阳县| 孟津县| 湖州市| 平定县| 密云县| 丰都县| 越西县| 扎囊县| 崇义县| 奉化市| 肥东县| 岢岚县| 青龙| 广宁县| 长泰县| 通辽市| 金山区| 香格里拉县| 霍城县| 民县| 防城港市| 华宁县| 绩溪县| 五莲县| 绥德县| 钦州市| 德庆县| 三河市| 中卫市| 济宁市| 永济市| 磴口县| 稻城县| 渝中区| 苏尼特右旗|