spark streaming 接收kafka消息之五 -- spark streaming 和 kafka 的對接總結

Spark streaming 和kafka 處理確保消息不丟失的總結redis

接入kafka

咱們前面的1到4 都在說 spark streaming 接入 kafka 消息的事情。講了兩種接入方式,以及spark streaming 如何和kafka協做接收數據,處理數據生成rdd的數據庫

主要有以下兩種方式緩存

基於分佈式receiver

 

基於receiver的方法採用Kafka的高級消費者API,每一個executor進程都不斷拉取消息,並同時保存在executor內存與HDFS上的預寫日誌(write-ahead log/WAL)。當消息寫入WAL後,自動更新ZooKeeper中的offset。
它能夠保證at least once語義,但沒法保證exactly once語義。緣由是雖然引入了WAL來確保消息不會丟失,但有可能會出現消息已寫入WAL,但更新comsuer 的offset到zk時失敗的狀況,此時consumer就會按上一次的offset從新發送消息到kafka從新獲取一次已保存到WAL的數據。這種方式還會形成數據冗餘(WAL中一份,blockmanager中一份,其中blockmanager可能會作StorageLevel.MEMORY_AND_DISK_SER_2,即內存中一份,磁盤上兩份),大大下降了吞吐量和內存磁盤的利用率。如今基本都使用下面基於direct stream的方法了。分佈式

基於direct stream的方法

 

基於direct stream的方法採用Kafka的簡單消費者API,大大簡化了獲取message 的流程。executor再也不從Kafka中連續讀取消息,也消除了receiver和WAL。還有一個改進就是Kafka分區與RDD分區是一一對應的,容許用戶控制topic-partition 的offset,程序變得更加可控。
driver進程只須要每次從Kafka得到批次消息的offset range,而後executor進程根據offset range去讀取該批次對應的消息便可。因爲offset在Kafka中能惟一肯定一條消息,且在外部只能被Streaming程序自己感知到,所以消除了不一致性,保證了exactly once語義。不過,因爲它採用了簡單消費者API,咱們就須要本身來管理offset。不然一旦程序崩潰,整個流只能從earliest或者latest點恢復,這確定是不穩妥的。源碼分析

 

如何保證處理結果不丟失呢?

主要有兩種方案:spa

2.1. 主要是 經過設計冪等性操做,在 at least once 的語義之上,確保數據不丟失設計

2.2. 在一些shuffle或者是集合計算的結果集中, 在 exactly-once 的基礎上,同時更新 處理結果和 offset,這種狀況下,通常都是使用事務來作。日誌

現有的支持事務的,也就是傳統的數據庫了,對於一些緩存系統爲了更簡單更高效的訪問,即便有事務機制,也設計的很是簡單,或是隻實現了部分功能,例如 redis 的事務是不能支持回滾的。須要咱們在代碼中作相應的設計,來確保事務的正確執行。blog

分佈式 RDD 計算過程如何確保準確性和一致性?

即分佈式RDD計算是如何和確保計算剛好計算一次的呢?後續會出一系列源碼分析,分析 spark 是如何作分佈式計算的。進程

相關文章
相關標籤/搜索