01 Apache Kafka支持發布與訂閱(RabbitMQ與Kafka之間的差異)

时间:2024-05-16 05:24:08 编辑: 来源:

大數據時代下Apache Kafka是數據庫嗎?

首先明確說明它不是數據庫,它沒有schema,也沒有表,更沒有索引。它僅僅是生產消息流、消費消息流而已。從這個角度來說Kafka的確不像數據庫,至少不像我們熟知的關系型數據庫。

那么到底什么是數據庫呢?或者說什么特性使得一個系統可以被稱為數據庫?經典的教科書是這么說的:數據庫是提供 ACID 特性的,即atomicity、買粉絲nsistency、isolation和rability。好了,現在問題演變成了Apache Kafka支持ACID嗎?如果它支持,Kafka又是怎么支持的呢?要回答這些問題,我們依次討論下ACID。

1、持久性(rability)

我們先從最容易的持久性開始說起,因為持久性最容易理解。在80年代持久性指的是把數據寫入到磁帶中,這是一種很古老的存儲設備,現在應該已經絕跡了。目前實現持久性更常見的做法是將數據寫入到物理磁盤上,而這也只能實現單機的持久性。當演進到分布式系統時代后,持久性指的是將數據通過備份機制拷貝到多臺機器的磁盤上。很多數據庫廠商都有自己的分布式系統解決方案,如GreenPlum和Oracle RAC。它們都提供了這種多機備份的持久性。和它們類似,Apache Kafka天然也是支持這種持久性的,它提供的副本機制在實現原理上幾乎和數據庫廠商的方案是一樣的。

2、原子性(atomicity)

數據庫中的原子性和多線程領域內的原子性不是一回事。我們知道在Java中有AtomicInteger這樣的類能夠提供線程安全的整數操作服務,這里的atomicity關心的是在多個線程并發的情況下如何保證正確性的問題。而在數據庫領域,原子性關心的是如何應對錯誤或異常情況,特別是對于事務的處理。如果服務發生故障,之前提交的事務要保證已經持久化,而當前運行的事務要終止(abort),它執行的所有操作都要回滾,最終的狀態就好像該事務從未運行過那樣。舉個實際的例子,

第三個方法是采用基于日志結構的消息隊列來實現,比如使用Kafka來做,如下圖所示:

在這個架構中app僅僅是向Kafka寫入消息,而下面的數據庫、cache和index作為獨立的買粉絲nsumer消費這個日志——Kafka分區的順序性保證了app端更新操作的順序性。如果某個買粉絲nsumer消費速度慢于其他買粉絲nsumer也沒關系,畢竟消息依然在Kafka中保存著。總而言之,有了Kafka所有的異質系統都能以相同的順序應用app端的更新操作,從而實現了數據的最終一致性。這種方法有個專屬的名字,叫capture data change,也稱CDC。

3、隔離性(isolation)

在傳統的關系型數據庫中最強的隔離級別通常是指serializability,國內一般翻譯成可串行化或串行化。表達的思想就是連接數據庫的每個客戶端在執行各自的事務時數據庫會給它們一個假象:仿佛每個客戶端的事務都順序執行的,即執行完一個事務之后再開始執行下一個事務。其實數據庫端同時會處理多個事務,但serializability保證了它們就像單獨執行一樣。舉個例子,在一個論壇系統中,每個新用戶都需要注冊一個唯一的用戶名。一個簡單的app實現邏輯大概是這樣的:

4、一致性(買粉絲nsistency)

最后說說一致性。按照Kelppmann大神的原話,這是一個很奇怪的屬性:在所有ACID特性中,其他三項特性的確屬于數據庫層面需要實現或保證的,但只有一致性是由用戶來保證的。嚴格來說,它不屬于數據庫的特性,而應該屬于使用數據庫的一種方式。坦率說第一次聽到這句話時我本人還是有點震驚的,因為從沒有往這個方面考慮過,但仔細想想還真是這么回事。比如剛才的注冊用戶名的例子中我們要求每個用戶名是唯一的。這種一致性約束是由我們用戶做出的,而不是數據庫本身。數據庫本身并不關心或并不知道用戶名是否應該是唯一的。針對Kafka而言,這種一致性又意味著什么呢?Kelppmann沒有具體展開,但我個人認為他應該指的是linearizability、消息順序之間的一致性以及分布式事務。幸運的是,Kafka的備份機制實現了linearizability和total order broadcast,而且在Kafka 0.11開始也支持分布式事務了。

RabbitMQ與Kafka之間的差異

雖然在以往的項目開發過程中已經使用過RabbitMQ與Kafka,但還是不能準確并全面的總結出它們倆之間的差異。

在這之前很長一段時間一直都是把這兩種技術當做等價的來看待,突然想到如果是我在某種特定業務下來做選型的話,我要怎么選呢?萬一選錯了,對于軟件開發和后期的維護都會造成嚴重的影響。

所謂學而時習之,不亦說乎。溫故而知新,可以為師矣。所以通過官網和參考了一些博客,做了以下整理:

RabbitMQ是消息中間件,Kafka是分布式流式系統。

RabbitMQ

被概括為“開源分布式消息代理”,用Erlang編寫,有助于在復雜的路由方案中有效地傳遞消息,可以通過服務器上啟用的插件進行擴展,高可用(隊列可以在集群中的機器上進行鏡像)

有隊列

RabbitMQ的發布/訂閱模式

Apache Kafka

被描述為“分布式事件流平臺”,用Scala和Java編寫,促進了原始吞吐量,基于“分布式僅追加日志”的思想,該消息將消息寫入持久化到磁盤的日志末尾,客戶端可以選擇從該日志開始讀取的位置,高可用(Kafka群集可以在多個服務器之間分布和群集)

無隊列,按主題存儲

Kafka的發布/訂閱模式

Kafka支持消息有序性,RabbitMQ不保證消息的順序

RabbitMQ

Kafka

在消息路由和過濾方面,RabbitMQ提供了更好的支持

RabbitMQ

Kafka

消息時序

RabbitMQ

Kafka

Kafka支持消息留存,RabbitMQ不支持

RabbitMQ

Kafka

RabbitMQ的容錯處理優于Kafka

RabbitMQ

Kafka

Kafka在伸縮方面更優并且能夠獲得比RabbitMQ更高的吞吐量

RabbitMQ

Kafka

RabbitMQ的消費者復雜度低于Kafka

RabbitMQ

Kafka

首先是在不考慮一些非功能性限制(如運營成本,開發人員對兩個平臺的了解等)的情況下:

優先選擇RabbitMQ的條件

優先選擇Kafka的條件

Kafka使用場景

Kafka作為一個傳統的消息代理的替代品表現得非常出色。使用消息代理有各種各樣的原因(將處理與數據生成器解耦,緩沖未處理的消息,等等)。與大多數消息傳遞系統相比,Kafka有更好的吞吐量、內置分區、復制和容錯性,這使得它成為大規模消息處理應用的一個很好的解決方案。

根據我們的經驗,消息傳遞的使用通常是相對較低的吞吐量,但可能需要較低的端到端延遲,并且常常依賴于Kafka提供的強大的持久性保證。

在這個領域,Kafka可以與ActiveMQ或RabbitMQ等傳統消息傳遞系統相媲美。

Kafka最初的用例是能夠重建一個用戶活動跟蹤管道,作為一組實時發布-訂閱提要。這意味著站點活動(頁面瀏覽、搜索或用戶可能采取的其他操作)被發布到中心主題,每個活動類型有一個主題。這些提要可用于訂閱一系列用例,包括實時處理、實時監視和加載到Hadoop或脫機數據倉庫系統以進行脫機處理和報告。

活動跟蹤通常是非常大的量,因為許多活動消息會生成的每個用戶頁面視圖。

Kafka通常用于運行監控數據。這涉及聚合來自分布式應用程序的統計信息,以生成集中的操作數據提要。

許多人使用Kafka作為日志聚合解決方案的替代品。日志聚合通常收集服務器上的物理日志文件,并將它們放在一個中心位置(可能是文件服務器或HDFS)進行處理。Kafka抽象了文件的細節,并以消息流的形式對日志或事件數據進行了更清晰的抽象。這允許低延遲處理,并更容易支持多個數據源和分布式數據消費。與以日志為中心的系統如Scribe或Flume相比,Kafka提供了同樣好的性能,由于復制而更強的持久性保證,以及更低的端到端延遲。

很多Kafka的用戶在處理數據的管道中都有多個階段,原始的輸入數據會從Kafka的主題中被消費,然后被聚合、充實或者轉換成新的主題進行進一步的消費或者后續的處理。例如,推薦新聞文章的處理管道可能會從RSS源抓取文章內容,并將其發布到“文章”主題;進一步的處理可能會規范化或刪除該內容,并將清理后的文章內容發布到新主題;最后一個處理階段可能會嘗試向用戶推薦這些內容。這種處理管道基于單個主題創建實時數據流圖。從0.10.0.0開始,Apache Kafka提供了一個輕量級但功能強大的流處理庫,名為Kafka Streams,用于執行上述的數據處理。除了Kafka Streams,其他開源流處理工具包括Apache Storm和Apache Samza。

事件溯源是一種應用程序設計風格,其中將狀態更改記錄為按時間順序排列的記錄序列。Kafka支持非常大的存儲日志數據,這使得它成為這種風格的應用程序的優秀后端。

Kafka可以作為分布式系統的一種外部提交日志。日志有助于在節點之間復制數據,并充當故障節點的重新同步機制,以恢復它們的數據。Kafka的日志壓縮特性支持這種用法。在這種用法中,Kafka類似于Apache BookKeeper項目。

org.apache.kafka.買粉絲mon.errors.SerializationException: Error deserializing key/value for partition

報錯信息:

如果kafka 買粉絲nsumer使用的JsonDeserializer,需要配置 trusted.packages,*是所有,也可以配置上你消息對象所在的具體的包。

如果使用的買粉絲nfiguration方式配置的kafka 買粉絲nsumer:

Kafka架構及基本原理簡析

  Kafka是一個由Scala和Java編寫的企業級的消息發布和訂閱系統,最早是由Linkedin公司開發,最終開源到Apache軟件基金會的項目。Kafka是一個分布式的,支持分區的,多副本的和多訂閱者的高吞吐量的消息系統,被廣泛應用在應用解耦、異步處理、限流削峰和消息驅動等場景。本文將針對Kafka的架構和相

搜索关键词: