真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Kafka的相關(guān)知識-創(chuàng)新互聯(lián)

一. Kafka基本介紹

Kafka是一個分布式、支持分區(qū)的(partition)、多副本的(replica),基于zookeeper協(xié)調(diào)的分布式消息系統(tǒng)。具有:高吞吐量、低延遲、可擴(kuò)展性、持久性、可靠性、容錯性、高并發(fā)等特性。常見的應(yīng)用場景有:日志收集、消息系統(tǒng)、流式處理等。

創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的靈川網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!二. Kafka的基本架構(gòu)

在這里插入圖片描述

  • Producer:生產(chǎn)者,也就是發(fā)送消息的一方。生產(chǎn)者負(fù)責(zé)創(chuàng)建消息,然后將其發(fā)送到 Kafka。
  • Consumer:消費(fèi)者,也就是接受消息的一方。消費(fèi)者連接到 Kafka 上并接收消息,進(jìn)而進(jìn)行相應(yīng)的業(yè)務(wù)邏輯處理。
  • Consumer Group:一個消費(fèi)者組可以包含一個或多個消費(fèi)者。使用多分區(qū) + 多消費(fèi)者方式可以極大提高數(shù)據(jù)下游的處理速度,同一消費(fèi)組中的消費(fèi)者不會重復(fù)消費(fèi)消息,同樣的,不同消費(fèi)組中的消費(fèi)者消息消息時互不影響。Kafka 就是通過消費(fèi)組的方式來實現(xiàn)消息 P2P 模式和廣播模式。
  • Broker:服務(wù)代理節(jié)點(diǎn)。Broker 是 Kafka 的服務(wù)節(jié)點(diǎn),即 Kafka 的服務(wù)器。
  • Topic:Kafka 中的消息以 Topic 為單位進(jìn)行劃分,生產(chǎn)者將消息發(fā)送到特定的 Topic,而消費(fèi)者負(fù)責(zé)訂閱 Topic 的消息并進(jìn)行消費(fèi)。
  • Partition:Topic 是一個邏輯的概念,它可以細(xì)分為多個分區(qū),每個分區(qū)只屬于單個主題。同一個主題下不同分區(qū)包含的消息是不同的,分區(qū)在存儲層面可以看作一個可追加的日志(Log)文件,消息在被追加到分區(qū)日志文件的時候都會分配一個特定的偏移量(offset)。
  • Offset:offset 是消息在分區(qū)中的唯一標(biāo)識,Kafka 通過它來保證消息在分區(qū)內(nèi)的順序性,不過 offset 并不跨越分區(qū),也就是說,Kafka 保證的是分區(qū)有序性而不是主題有序性。
  • Replication:副本,是 Kafka 保證數(shù)據(jù)高可用的方式,Kafka 同一 Partition 的數(shù)據(jù)可以在多 Broker 上存在多個副本,通常只有主副本對外提供讀寫服務(wù),當(dāng)主副本所在 broker 崩潰或發(fā)生網(wǎng)絡(luò)一場,Kafka 會在 Controller 的管理下會重新選擇新的 Leader 副本對外提供讀寫服務(wù)。
  • Record:實際寫入 Kafka 中并可以被讀取的消息記錄。每個 record 包含了 key、value 和 timestamp。
三. Kafka如何保證消息順序消費(fèi)

Kafka 在Topic級別本身是無序的,只有partition上才有序,所以為了保證處理順序,可以自定義分區(qū)器,將需順序處理的數(shù)據(jù)發(fā)送到同一個partition。自定義分區(qū)器需要實現(xiàn)接口Partitioner接口并實現(xiàn) 3 個方法:partition,close,configure,在partition方法中返回分區(qū)號即可。
Kafka 中發(fā)送 1 條消息的時候,可以指定(topic, partition, key)3 個參數(shù),partitonkey是可選的。
Kafka 分布式的單位是partition,同一個partition用一個write ahead log組織,所以可以保證FIFO的順序。不同partition之間不能保證順序。因此你可以指定partition,將相應(yīng)的消息發(fā)往同 1個partition,并且在消費(fèi)端,Kafka 保證1 個partition只能被1 個consumer消費(fèi),就可以實現(xiàn)這些消息的順序消費(fèi)。
另外,也可以指定 key(比如 order id),具有同 1 個 key 的所有消息,會發(fā)往同 1 個partition,那這樣也實現(xiàn)了消息的順序消息。

四. Kafka發(fā)送消息選擇分區(qū)的邏輯

Kafka在數(shù)據(jù)生產(chǎn)的時候,有一個數(shù)據(jù)分發(fā)策略。默認(rèn)的情況使用org.apache.kafka.clients.producer.internals.DefaultPartitioner類,這個類中就是定義數(shù)據(jù)分發(fā)的策略。默認(rèn)策略為:

  1. 如果在發(fā)消息的時候指定了分區(qū),則消息投遞到指定的分區(qū)
  2. 如果沒有指定分區(qū),但是消息的key不為空,則基于key的哈希值來選擇一個分區(qū)
  3. 如果既沒有指定分區(qū),且消息的key也是空,則用輪詢的方式選擇一個分區(qū)
五. Kafka如何避免消息丟失

Kafka的消息避免丟失可以從三個方面考慮處理:Producer發(fā)送消息避免失敗、Broker能成功保存接收到的消息、Consumer確認(rèn)消費(fèi)消息。

  1. Producer發(fā)送消息避免失敗
    想要Produce發(fā)送消息不失敗,那就得知道發(fā)送結(jié)果,網(wǎng)絡(luò)抖動這些情況是無法避免的,只能是發(fā)送后獲取發(fā)送結(jié)果,那么最直接的方式就是把Kafka默認(rèn)的異步發(fā)送改為同步發(fā)送(Broker收到消息后ack回復(fù)確認(rèn)),這樣就能實時知道消息發(fā)送的結(jié)果,但是這樣會讓Kafka的發(fā)送效率大大降低,因為Kafka在默認(rèn)的異步發(fā)送消息的時候可以批量發(fā)送,以此大幅度提高發(fā)送效率,因此一般很少使用同步發(fā)送的方式,除非消息很重要絕不允許丟失。
    但是我們可以采用添加異步或調(diào)函數(shù),監(jiān)聽消息發(fā)送的結(jié)果,如果失敗可以在回調(diào)中重試,以此來達(dá)到盡可能的發(fā)送成功。同時Producer本身提供了一個retries的機(jī)制,如果因為網(wǎng)絡(luò)問題,或者Broker故障 導(dǎo)致發(fā)送失敗,就是重試。一般這個retries設(shè)置3-5次或者更高,同時重試間隔時間也隨著次數(shù)增長。

  2. Broker能成功保存接收到的消息
    Broker要成功的保存接收到的消息并且不丟失,就需要把接收到的消息保存到磁盤。Kafka為了提高性能采用的是異步批量,存儲到磁盤的機(jī)制,就是有一定的消息量和時間間隔要求的,刷磁盤的這個動作是操作系統(tǒng)來調(diào)度的,如果在刷盤之前系統(tǒng)就崩潰了,就會數(shù)據(jù)丟失。
    針對這個情況,Kafka采用Partition分區(qū)ack機(jī)制,Partition分區(qū)是指一個Topic下的多個分區(qū),有一個Leader分區(qū),其他的都是Follower分區(qū),Leader分區(qū)負(fù)責(zé)接收和被讀取消息,Follower分區(qū)會通過Replication機(jī)制同步Leader的數(shù)據(jù),負(fù)責(zé)高可用(Kafka在2.4之后,Kafka提供了讀寫分離,Follower也可以提供讀取),當(dāng)Leader出現(xiàn)故障時會從Follower中選取一個成為新的Leader。那么當(dāng)一個消息發(fā)送到Leader分區(qū)之后,Kafka提供了一個acks的參數(shù),Producer可以設(shè)置這個參數(shù),去結(jié)合brokerPartition機(jī)制來共同保障數(shù)據(jù)的可靠性,這個參數(shù)的值有三個

    • 0,表示Producer不需要等待broker的響應(yīng),就認(rèn)為消息發(fā)送成功了(可能存在數(shù)據(jù)丟失)
    • 1,表示Leader收到消息之后,不等待其他的Follower的同步就給Producer發(fā)一個確認(rèn),如果LeaderPartition掛了就可能存在數(shù)據(jù)丟失
    • -1,表示Leader收到消息之后還會等待ISR列表(與Leader保持正常連接的Follwer節(jié)點(diǎn)列表)中的Follower同步完成,再給Producer返回一個確認(rèn),也就是所有分區(qū)節(jié)點(diǎn)都確認(rèn)收到消息,保證數(shù)據(jù)不丟失
  3. Consumer確認(rèn)消費(fèi)消息
    當(dāng)Producer確定發(fā)送消息成功并且Broker成功保存消息之后,基本上Consumer就肯定能消費(fèi)到消息。Kafka在消費(fèi)者消費(fèi)時有一個offset機(jī)制,代表了當(dāng)前消費(fèi)者消費(fèi)到了Partition的哪一條消息。kafka的Consumer的配置中,默認(rèn)的enable.auto.commit = true,表示在Consumer通過poll方法 獲取到消息以后,每過5秒(通過配置項可修改)會自動獲取poll中得到的大的offset, 提交給Partition中的offset_consumer(存儲 offset 的特定topic)。如果enable.auto.commit = false時,則關(guān)閉了自動提交,需要手動的通過應(yīng)用程序代碼進(jìn)行提交。
    所以在Consumer消費(fèi)消息時,丟失消息的可能會有兩種,比如開啟了offset自動提交,但是消息消費(fèi)失??;或者沒有開啟自動提交offset,但是在消費(fèi)消息之前提交了offset。針對這兩種情況,可以設(shè)置在消息消費(fèi)完成后手動提交offset??傊?code>Consumer端確認(rèn)消息消費(fèi)成功后再提交offset即可保證消息正常消費(fèi)。

六. Kafka的offset機(jī)制

?Kafka中的每個Partition都由一系列有序的、不可變的消息組成,這些消息被連續(xù)的追加到Partition中。Partition中的每個消息都有一個連續(xù)的序號,用于Partition唯一標(biāo)識一條消息,這個唯一標(biāo)識就是offset。
Offset從語義上來看擁有兩種:Current OffsetCommitted Offset。

Current Offset保存在Consumer客戶端中,它表示Consumer希望收到的下一條消息的序號。它僅僅在poll()方法中使用。例如,Consumer第一次調(diào)用poll()方法后收到了20條消息,那么Current Offset就被設(shè)置為20。這樣Consumer下一次調(diào)用poll()方法時,Kafka就知道應(yīng)該從序號為21的消息開始讀取。這樣就能夠保證每次Consumer poll消息時,都能夠收到不重復(fù)的消息。

Committed Offset保存在Broker上,它表示Consumer已經(jīng)確認(rèn)消費(fèi)過的消息的序號。主要通過commitSynccommitAsyncAPI來操作。舉個例子,Consumer通過poll()方法收到20條消息后,此時Current Offset就是20,經(jīng)過一系列的邏輯處理后,并沒有調(diào)用consumer.commitAsync()consumer.commitSync()來提交Committed Offset,那么此時Committed Offset依舊是0。
Committed Offset主要用于Consumer Rebalance。在Consumer Rebalance的過程中,一個partition被分配給了一個Consumer,那么這個Consumer該從什么位置開始消費(fèi)消息呢?答案就是Committed Offset。另外,如果一個Consumer消費(fèi)了5條消息(poll并且成功commitSync)之后宕機(jī)了,重新啟動之后它仍然能夠從第6條消息開始消費(fèi),因為Committed Offset已經(jīng)被Kafka記錄為5。

在Kafka 0.9前,Committed Offset信息保存在zookeeperconsumers/{group}/offsets/{topic}/{partition}目錄中(zookeeper并不適合進(jìn)行大批量的讀寫操作,尤其是寫操作)。而在0.9之后,所有的offset信息都保存在了Broker上的一個名為_consumer_offsetstopic中。

七. Kafka性能高的原因
  1. 順序讀寫
    Kafka的Partition中寫入數(shù)據(jù),是通過分段、追加日志的方式,這在很大程度上將讀寫限制為順序 I/O(sequential I/O),這在大多數(shù)的存儲介質(zhì)上都很快。實際上不管是內(nèi)存還是磁盤,快或慢關(guān)鍵在于尋址的方式,磁盤分為順序讀寫與隨機(jī)讀寫,內(nèi)存也一樣分為順序讀寫與隨機(jī)讀寫?;诖疟P的隨機(jī)讀寫確實很慢,但磁盤的順序讀寫性能卻很高,一般而言要高出磁盤隨機(jī)讀寫三個數(shù)量級,一些情況下磁盤順序讀寫性能甚至要高于內(nèi)存隨機(jī)讀寫。
    在這里插入圖片描述

  2. Page Cache
    為了優(yōu)化讀寫性能,Kafka利用了操作系統(tǒng)本身的Page Cache,就是利用操作系統(tǒng)自身的內(nèi)存而不是JVM空間內(nèi)存。這樣做可以避免Object消耗,如果是使用 Java 堆,Java對象的內(nèi)存消耗比較大,通常是所存儲數(shù)據(jù)的兩倍甚至更多;還能避免GC問題,隨著JVM中數(shù)據(jù)不斷增多,垃圾回收將會變得復(fù)雜與緩慢,使用系統(tǒng)緩存就不會存在GC問題。

    相比于使用JVMin-memory cache等數(shù)據(jù)結(jié)構(gòu),利用操作系統(tǒng)的Page Cache更加簡單可靠。首先,操作系統(tǒng)層面的緩存利用率會更高,因為存儲的都是緊湊的字節(jié)結(jié)構(gòu)而不是獨(dú)立的對象。其次,操作系統(tǒng)本身也對于Page Cache做了大量優(yōu)化,提供了write-behindread-ahead以及flush等多種機(jī)制。再者,即使服務(wù)進(jìn)程重啟,系統(tǒng)緩存依然不會消失,避免了in-process cache重建緩存的過程。

    通過操作系統(tǒng)的Page Cache,Kafka的讀寫操作基本上是基于內(nèi)存的,讀寫速度得到了極大的提升。

  3. 零拷貝
    Linux操作系統(tǒng) 零拷貝 機(jī)制使用了sendfile方法, 允許操作系統(tǒng)將數(shù)據(jù)從Page Cache直接發(fā)送到網(wǎng)絡(luò),只需要最后一步的copy操作將數(shù)據(jù)復(fù)制到 NIC 緩沖區(qū), 這樣避免重新復(fù)制數(shù)據(jù)。零拷貝的技術(shù)基礎(chǔ)是DMA,又稱之為直接內(nèi)存訪問。DMA 傳輸將數(shù)據(jù)從一個地址空間復(fù)制到另外一個地址空間。當(dāng)CPU 初始化這個傳輸動作,傳輸動作本身是由 DMA 控制器來實行和完成。因此通過DMA,硬件則可以繞過CPU,自己去直接訪問系統(tǒng)主內(nèi)存。很多硬件都支持DMA,其中就包括網(wǎng)卡、聲卡、磁盤驅(qū)動控制器等。通過這種 “零拷貝” 的機(jī)制,Page Cache結(jié)合sendfile方法,Kafka消費(fèi)端的性能也大幅提升。這也是為什么有時候消費(fèi)端在不斷消費(fèi)數(shù)據(jù)時,我們并沒有看到磁盤io比較高,此刻正是操作系統(tǒng)緩存在提供數(shù)據(jù)。

    當(dāng)Kafka客戶端從服務(wù)器讀取數(shù)據(jù)時,如果不使用零拷貝技術(shù),那么大致需要經(jīng)歷這樣的一個過程:

    • 操作系統(tǒng)將數(shù)據(jù)從磁盤上讀入到內(nèi)核空間的讀緩沖區(qū)中。
    • Kafka應(yīng)用程序從內(nèi)核空間的讀緩沖區(qū)將數(shù)據(jù)拷貝到用戶空間的緩沖區(qū)中。
    • Kafka應(yīng)用程序?qū)?shù)據(jù)從用戶空間的緩沖區(qū)再寫回到內(nèi)核空間的socket緩沖區(qū)中。
    • 操作系統(tǒng)將socket緩沖區(qū)中的數(shù)據(jù)拷貝到NIC緩沖區(qū)中,然后通過網(wǎng)絡(luò)發(fā)送給客戶端。

    如果使用零拷貝技術(shù),那么只需要:

    • 操作系統(tǒng)將數(shù)據(jù)從磁盤中加載到內(nèi)核空間的Read Buffer(頁緩存區(qū))中
    • 操作系統(tǒng)之間將數(shù)據(jù)從內(nèi)核空間的Read Buffer(頁緩存區(qū))傳輸?shù)骄W(wǎng)卡中,并通過網(wǎng)卡將數(shù)據(jù)發(fā)送給接收方
  4. 批量讀寫
    Kafka數(shù)據(jù)讀寫也是批量的而不是單條的。除了利用底層的技術(shù)外,Kafka還在應(yīng)用程序?qū)用嫣峁┝艘恍┦侄蝸硖嵘阅?,最明顯的就是使用批次,在向Kafka寫入數(shù)據(jù)時,可以啟用批次寫入,這樣可以避免在網(wǎng)絡(luò)上頻繁傳輸單個消息帶來的延遲和帶寬開銷。假設(shè)網(wǎng)絡(luò)帶寬為10MB/S,一次性傳輸10MB的消息比傳輸1KB的消息10000萬次顯然要快得多。

  5. 批量壓縮
    Kafka可以把所有的消息都變成一個批量的文件,并且進(jìn)行合理的批量壓縮,減少網(wǎng)絡(luò)IO損耗,通過mmap提高I/O速度,寫入數(shù)據(jù)的時候由于單個Partion是末尾添加所以速度最優(yōu),讀取數(shù)據(jù)的時候配合sendfile直接輸出。并且Kafka支持多種壓縮協(xié)議,包括Gzip和Snappy壓縮協(xié)議。

八. Kafka的topic數(shù)量太多性能會急劇下降的原因是什么

Kafka的topic數(shù)量多性能會下降的主要原因是topic在物理層面以partition為分組,一個topic可以分成若干個partition,partition還可以細(xì)分為logSegment,一個partition物理上由多個logSegment組成,logSegment文件由兩部分組成,分別為.index文件和.log文件,分別表示為Segment索引文件和數(shù)據(jù)文件。Kafka在Broker接受并存儲消息的時候,是將消息數(shù)據(jù)使用分段、追加日志的方式寫入log文件,在很大程度上將讀寫限制為順序 I/O(sequential I/O),那么如果topic數(shù)量很多,即使每個topic只有1個partition,也會導(dǎo)致總分區(qū)數(shù)很多,磁盤讀寫退化為隨機(jī),影響性能。同時Kafka中topic的元數(shù)據(jù)是在zookeeper中的,大量topic確實會造成性能瓶頸(zk不適合做高并發(fā)的讀寫操作),不僅在磁盤讀寫上。而且topic太多造成partition過多。partition是kafka的最小并行單元,每個partition都會在對應(yīng)的broker上有日志文件。當(dāng)topic過多,partition增加,日志文件數(shù)也隨之增加,就需要允許打開更多的文件數(shù)。partition過多在controller選舉和controller重新選舉partition leader的耗時會大大增加,造成kafka不可用的時間延長。

九. Kafka的Replication機(jī)制 十. Kafka的Consumer Group 十一. Kafka的零拷貝 十二. Kafka的HW和LEO 十三. Kafka的ISR 十四. Kafka的Rebalance 十五. Kafak為什么依賴zk,zk在其中的作用是什么

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁標(biāo)題:Kafka的相關(guān)知識-創(chuàng)新互聯(lián)
當(dāng)前網(wǎng)址:http://weahome.cn/article/csjgoj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部