股友問:Kafka為什麼會丟消息,如何解決呢?

2022-01-04 Go招聘

收錄於話題 #每日一股 18個

我是一隻可愛的土撥鼠,專注於分享 Go 職場、招聘和求職,解 Gopher 之憂!歡迎關注我。

歡迎大家加入Go招聘交流群,來這裡找志同道合的小夥伴!跟土撥鼠們一起交流學習。

目錄

本周招聘

本周股

LeetCode每日打卡

1. 「二叉樹的前序遍歷」

2. 「二叉樹的中序遍歷」

3. 「N叉樹的後序遍歷」

4. 「N叉樹的前序遍歷」

5. 「最長回文子串」

6. 「N叉樹的層序遍歷」

7. 「對稱二叉樹」

本周招聘

1、【阿里巴巴】雲原生布道師的機會,這要求。。。

本周股1.簡述 redis 中消息隊列的實現方案list

因為 list 是基於雙端鍊表實現,所以可以實現雙端進出的功能。也就是能夠實現消息隊列(生產者放進尾端,消費者取頭部),但只能一對一單播,不能廣播,不能重複消費。如果消費者獲取到消息在處理時發生宕機,就會丟失數據。

發布訂閱

發布訂閱也能支持消息隊列,但只會發給在線的消費者,並且沒有持久化的功能。每個消費者都有本地的緩衝區,生產者會把發布的消息推到各個消費者的緩衝區(沒有做 RDB 或者 AOF)上面,所以沒在線的消費者無法收到,也沒辦法回溯,當消費者區域緩衝不夠了也會踢消費者下線

stream

redis 5.0 推出的功能,支持持久化,確認應答 ack 機制,多個消費者(不是廣播,只是均勻消費,類似於 kafka 的消費者組)以及可以回溯消費過的內容,並且也支持類似 offset 的消費模式(使用當前消費完成的消費 id 去消費下一條消息)。當然如果消息積壓太大超過了設置的存儲閾值是否丟棄舊的消息,這是 redis 基於內存去實現這個方案的弊端

參考以及延展閱讀

2.簡述 MySQL 中的 MVCC、readview、undolog 的概念及相互的聯繫MVCC

MVCC 是 MySQL 中處理並發讀寫的一種機制,讓一個數據有多個版本,保證讀寫操作沒有衝突。MVCC 具體是由 readview 和 undlog 還有每行的三個隱藏的欄位實現的。

readview

readview 是事務進行時生成的數據快照。事務隔離級別不同生成的時機不一樣(比如 RC 是每次查詢的時候都會生成一個,之後快照讀都會讀最新;RR 是第一次查詢時會生成之後就不再生成,之後快照讀都會讀同一個),readview 本質上其實是根據每行的記錄隱藏的當前事務 ID,去讀取 undolog 的記錄來生成當前事務允許讀到的數據集,所以才有快照讀這個說法。

undolog

undolog 是回滾日誌(實現了 ACID 中的 A 原子性),在執行任何變更操作都會生成一條記錄對應一個 undolog 記錄,每行記錄在一個事務內變更的記錄都會生成一個一個 undolog 讓他們從近到遠的順序連接在一起形成 undolog 版本鏈

總結

MVCC 的實現基於 readview ,而 readview 的實現基於 undolog 以及每行的隱藏欄位(事務 ID 等)。

參考連結以及擴展閱讀:

3.kafka 什麼時候會丟消息,如何解決丟消息的情況生產者發送消息。丟消息的原因主要是生產者一般發送消息到 kafka 都是異步的,所以有可能失敗之後沒有處理。解決方案一般是進行失敗重試,或者設置發消息的方法設置成同步。消費者消費消息。丟消息的原因主要是消費者拉取消息後會設置 autocommit offset,但是消費者拉取消息後因為某些原因宕機後沒有處理這個數據導致丟消息。解決方案可以先關掉 autocommit offset,等待業務處理完後再提交。但是這個方案要注意不要讓消費者消費過長讓 kafka 超時踢出消費者組導致 rebalancekafka 中 topic 及 replicate 的主從同步。

前提知識:kafka 的高可用方案是把一個 topic 在多臺 kafka 實例上做了副本 replicate (當然也分了 leader 和 follower,用的是 zk 管理,新版本的 kafka 也去除了zk 管理的依賴)。這時一般的讀寫都是從 leader 上操作的,當 leader 接收了一個消息,沒有來得及同步到 follwer 前 broker 掛掉了,會導致丟消息。

解決方案

解決方案和 mysql 有點類似:

全同步。可配置一個參數 acks = all,也就是類似於 Mysql 主從複製中的全同步,等到所有 topic 副本都同步完才返回給生產者發送成功。半同步。可配置一個參數 mini.sync.replicas。也就是 Mysql 的半同步,可以設置同步到多少個副本就返回給生產者發送成功新增副本個數,增大同步到的概率。可配置一個參數 replication.factor,也就是增大副本的個數,因為副本越多,同步到的概率就越大,但會導致數據冗餘。

參考連結以及擴展閱讀:

面試官問我如何保證Kafka不丟失消息?我哭了[3]4.什麼是優雅退出

前提知識:

在 Linux 下很多殺進程的操作都是 kill -9 pid(進程 id)。但是這樣直接殺進程會帶來一些不可預知的問題。比如進程的緩存數據沒有持久化到磁碟,正在進行的一些 IO 操作會被忽然停止,一些數據操作只進行到一半等等。基於這些問題的發生,在退出進程的時候當然是希望能夠處理完現在的數據,釋放正在持有的資源再去關閉。

優雅退出: 優雅退出就是基於這些問題而出現的一個操作,一般的實現都是 kill pid 時,會發出信號去通知進程要關閉。各個程式語言的實現不一,但是都會去捕獲這個信號,之後將進程本身標記為退出狀態,優先處理完現在正在處理的操作,不再接收新的操作請求,操作完成後釋放持有的資源(比如已經建立好的連接進行 4 次揮手等等),之後關閉進程。(當然優雅關閉在實現的代碼上也一般會設計超時控制,超過一定時間會強制關閉)

5.什麼是信號

信號是 Linux 下進程間通信的一種方式。(這裡涉及到進程間通信,就不再贅述)

利用信號進行異步通知這種進程間通信的方式,可以用來通知其他進程,通知之後會讓被通知的進程進入軟中斷去進行邏輯。如果進程對這個信號定義了函數處理的流程,那麼會被執行(比如 go 的 os/signal 可以定義優雅退出)。信號的通知可以被捕捉,忽略,和使用內核默認的處理方式。

參考連結以及擴展閱讀:

LeetCode每日打卡1. 「二叉樹的前序遍歷」

https://leetcode-cn.com/problems/binary-tree-preorder-traversal/

題解參考:https://books.halfrost.com/leetcode/ChapterFour/0100~0199/0114.Flatten-Binary-Tree-to-Linked-List/

2. 「二叉樹的中序遍歷」

https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

題解參考:https://books.halfrost.com/leetcode/ChapterFour/0001~0099/0094.Binary-Tree-Inorder-Traversal/

3. N叉樹的後序遍歷」

https://leetcode-cn.com/problems/n-ary-tree-postorder-traversal/

題解參考:https://leetcode-cn.com/problems/n-ary-tree-postorder-traversal/solution/ncha-shu-de-hou-xu-bian-li-by-leetcode/

4. 「N叉樹的前序遍歷」

https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal/

題解參考:https://books.halfrost.com/leetcode/ChapterFour/0500~0599/0589.N-ary-Tree-Preorder-Traversal/

5. 「最長回文子串」

https://leetcode-cn.com/problems/longest-palindromic-substring/

題解參考:https://books.halfrost.com/leetcode/ChapterFour/0001~0099/0005.Longest-Palindromic-Substring/

6. 「N叉樹的層序遍歷」

https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/

題解參考:https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/solution/ncha-shu-de-ceng-xu-bian-li-by-leetcode/

7. 「對稱二叉樹」

https://leetcode-cn.com/problems/symmetric-tree/

題解參考:https://books.halfrost.com/leetcode/ChapterFour/0100~0199/0101.Symmetric-Tree/

參考資料[1] 

15 | 消息隊列的考驗:Redis有哪些解決方案?: https://time.geekbang.org/column/article/284291

[2] 

MVCC多版本並發控制: https://www.jianshu.com/p/8845ddca3b23

[3] 

面試官問我如何保證Kafka不丟失消息?我哭了: https://juejin.cn/post/6844904094021189639

[4] 

Golang信號處理和優雅退出守護進程: https://studygolang.com/articles/10076

歡迎關注Go招聘公眾號,獲取更多精彩內容。

100:Go簡歷模板 | 101:Go最全面試集錦 | 102:Go超級簡歷 | 103:Go安全指南 | 1024:LeetCode刷題指南 | 6379:redis集錦 

相關焦點

  • 如何理解Kafka的消息可靠性策略?
    遇到各種故障時,我的消息會不會丟?消費者側會收到多條消息嗎?消費者svr重啟後消息會丟失嗎?這些問題都很正常,在開始接觸和使用時總會有這樣或那樣的問題。 一般情況下,不做了解,使用各種默認的推薦值,也是可以work的。 但是我們要優雅的提升自己的姿(知)勢(識)。
  • kafka極簡教程
    Apache kafka是消息中間件的一種,我發現很多人不知道消息中間件是什麼,在開始學習之前,我這邊就先簡單的解釋一下什麼是消息中間件,只是粗略的講解,目前kafka已經可以做更多的事情。雞蛋其實就是「數據流」,系統之間的交互都是通過「數據流」來傳輸的(就是tcp、http什麼的),也稱為報文,也叫「消息」。消息隊列滿了,其實就是籃子滿了,」雞蛋「 放不下了,那趕緊多放幾個籃子,其實就是kafka的擴容。各位現在知道kafka是幹什麼的了吧,它就是那個"籃子"。
  • kafka使用原理介紹
    但是如果某個kafka controller 切換的時候,會導致partition leader的切換(老的 kafka controller上面的partition leader會選舉到其他的kafka broker上),但是這樣就會導致丟數據。
  • 圖解 kafka 架構與工作原理
    應用程式:只需要將消息推送到消息中間件,然後啟用一個線程來不斷從消息中間件中拉取數據,進行消費確認即可!引入消息中間件之後,整個服務開發會變得更加簡單,各負其責。LinkedIn 的開發團隊,為了解決數據管道問題,起初採用了 ActiveMQ 來進行數據交換,大約是在 2010 年前後,那時的 ActiveMQ 還遠遠無法滿足 LinkedIn 對數據傳遞系統的要求,經常由於各種缺陷而導致消息阻塞或者服務無法正常訪問,為了能夠解決這個問題,LinkedIn 決定研發自己的消息傳遞系統,
  • Kafka【入門】就這一篇!
    由於消息在 Partition 的 Segment 數據文件中是順序讀寫的,且消息消費後不會刪除(刪除策略是針對過期的 Segment 文件),這種順序磁碟 IO 存儲設計師 Kafka 高性能很重要的原因。Kafka 是如何準確的知道 message 的偏移的呢?
  • Kafka這些名詞都說不出所以然,您竟然敢說自己精通kafka
    05Kafka如何做到不丟失不重複消費kafka其實有兩次消息傳遞,一次生產者發送消息給kafka,一次消費者去kafka消費消息。在兩端的默認配置,都是at least once,可能重複,通過配置也不能做到exactly once,好像kafka的消息一定會丟失或者重複的,是不是沒有辦法做到exactly once了呢?
  • 深度剖析Kafka/RocketMQ順序消息的一些坑
    我們都知道無論是 Kafka 還是 RocketMQ,每個主題下面都有若干分區(RocketMQ 叫隊列),如果消息被分配到不同的分區中,那麼 Kafka 是不能保證消息的消費順序的,因為每個分區都分配到一個消費者,此時無法保證消費者的消費先後,因此如果需要進行消息具有消費順序性,可以在生產端指定這一類消息的 key,這類消息都用相同的 key 進行消息發送,kafka 就會根據 key
  • 大白話+13張圖解 Kafka
    至於為什麼提高了性能,很簡單,多個分區多個線程,多個線程並行處理肯定會比單線程好得多Topic和partition像是HBASE裡的table和region的概念,table只是一個邏輯上的概念,真正存儲數據的是region,這些region會分布式地存儲在各個伺服器上面,對應於kafka,也是一樣,Topic
  • kafka異步雙活方案 mirror maker2深度解析
    所以kafka2.4版本,推出一個新的mirror maker2(以下mm2即代表mirror maker2)。mirror maker2基於kafka connect工具,解決了上面說的大部分問題。今天主要介紹mirror maker2的設計,主要功能和部署。
  • kafka入門(原理-搭建-簡單使用)
    一、kafka介紹與原理我們將消息的發布(publish)稱作 producer,將消息的訂閱(subscribe)表述為 consumer,將中間的存儲陣列稱作 broker(代理),這樣就可以大致描繪出這樣一個場面:生產者將數據生產出來,交給 broker 進行存儲,消費者需要消費數據了,就從broker中去拿出數據來,然後完成一系列對數據的處理操作。
  • Kafka 基本原理(8000 字小結)
    1)kafka以topic來進行消息管理,每個topic包含多個partition,每個partition對應一個邏輯log,有多個segment組成。2)每個segment中存儲多條消息(見下圖),消息id由其邏輯位置決定,即從消息id可直接定位到消息的存儲位置,避免id到位置的額外映射。
  • 不了解Kafka的acks配置,怎麼能說你會Kafka?
    Kafka生產者有很多可以配置的參數,這些在kafka的說明文檔中已經有詳細的說明,它們大部分都有合理的默認值,一般情況下,我們不需要修改。不過有些參數在內存使用、性能和可靠性方面對生產者的影響比較大,今天就重點來講講acks參數對消息可靠性的影響。
  • 「Spring和Kafka」Kafka整合Spring 深入挖掘 -第1部分
    接下來是《如何在您的Spring啟動應用程式中使用Apache Kafka》「Spring和Kafka」如何在您的Spring啟動應用程式中使用Kafka ,這展示了如何開始使用Spring啟動和Apache Kafka®,這裡我們將更深入地挖掘Apache Kafka項目的Spring提供的一些附加功能。
  • 從未如此簡單:10分鐘帶你逆襲Kafka!
    生產者發送消息給 Kafka,Broker 的 Partition Leader 在收到消息後馬上發送成功 Ack(無需等等 ISR 中的 Follower 同步)。生產者收到後知道消息發送成功,然後會再發送消息。如果一直未收到 Kafka 的 Ack,則生產者會認為消息發送失敗,會重發消息。
  • Kafka分區與消費者的關係
    前言我們知道,生產者發送消息到主題,消費者訂閱主題(以消費者組的名義訂閱),而主題下是分區,消息是存儲在分區中的,所以事實上生產者發送消息到分區,消費者則從分區讀取消息,那麼,這裡問題來了,生產者將消息投遞到哪個分區?消費者組中的消費者實例之間是怎麼分配分區的呢?接下來,就圍繞著這兩個問題一探究竟。2.
  • 圖文詳解:Kafka到底有哪些秘密讓我對它情有獨鍾呢?
    隨著對實時性的要求越來越高,那麼在龐大的數據的傳輸過程中怎麼能保證數據的快速傳遞呢,由此,消息隊列產生了。「消息」是在兩臺計算機間傳送的數據單位。消息可以非常簡單,例如只包含文本字符串;也可以更複雜,可能包含嵌入對象。消息被發送到隊列中。「消息隊列」是在消息的傳輸過程中保存消息的容器。Kafka是一個分布式消息隊列對我們來說掌握它是必不可少的。
  • Apache Kafka 快速入門指南
    Kafka 對消息保存時根據 Topic 進行歸類,發送消息 者稱為 Producer,消息接受者稱為 Consumer,此外 kafka 集群有多個 kafka 實例組成,每個 實例(server)稱為 broker。
  • Kafka常見錯誤整理(不斷更新中)
    :分區數據不在原因分析:producer向不存在的topic發送消息,用戶可以檢查topic是否存在 或者設置auto.create.topics.enable參數2、LEADER_NOT_AVAILABLEWARN Errorwhile fetching metadata with
  • 消息隊列:Rabbitmq如何保證不丟消息
    對於網絡通訊來說,解決丟數據最好的辦法就是,消息確認機制,而rabbitmq裡面是通過兩個方式來保證:一種是事務機制,這個是在amqp協議層面保證的,具體操作如下所示:RabbitMQ中與事務機制有關的方法有三個:txSelect(), txCommit()以及txRollback(), txSelect用於將當前channel設置成transaction模式,txCommit
  • logstash_output_kafka:Mysql同步Kafka深入詳解
    其中:debezium和flume是基於mysql binlog實現的。如果需要同步歷史全量數據+實時更新數據,建議使用logstash。1、logstash同步原理常用的logstash的插件是:logstash_input_jdbc實現關係型資料庫到Elasticsearch等的同步。