TimeLine模型下確保訊息有序不丟
透過《基於TimeLine模型的訊息同步機制》一文,我們瞭解到Timeline模型有非常多的優點,也是釘釘採用的訊息同步機制。實際工作中,我們也將該模型應用在了C端使用者的訊息場景中。實施過程中也遇到了一些問題,積累了一些經驗。本文將介紹極端情況丟失訊息的問題及解決辦法。
一、Timeline概念
Timeline可以簡單理解為是一個訊息佇列,某個使用者所有的訊息都儲存在這個Timeline中,使用者的各個端可以從這個佇列中同步各自訊息。
圖中的例子中,訊息傳送方是A,訊息接收方是B,同時B存在多個接收端,分別是B1、B2和B3。A向B傳送訊息,訊息需要同步到B的多個端,待同步的訊息透過一個Timeline來進行交換。A向B傳送的所有訊息,都會儲存在這個Timeline中,B的每個接收端都是獨立的從這個Timeline中拉取訊息。每個接收端同步完畢後,都會在本地記錄下最新同步到的訊息的msgid,即最新的一個位點,作為下次訊息同步的起始位點。
二、丟失訊息的原因
理論上講,Timeline模型能夠確保訊息不重不漏。實際實施中,根據系統架構特點以及選用中介軟體的不同,極端情況下,可能出現丟訊息。最主要的原因是某一時刻,Timeline中的資料不連續或不完整。
舉個例子,如果使用者有兩條時間間隔非常近的訊息msg1、msg2,對應的msgId分別為10,11。由於時間很相近,(分散式系統)某些情況下可能出現msg2先寫入TimeLine,如果此時使用者某個端正好執行Sync同步訊息,將同步到最大msgId為11的msg2訊息,造成msg1丟失(msg1此時還沒有寫入TimeLine)。
下圖是IM系統的結構。Dispatcher負責生成msgId,透過Kafka傳遞給具體業務邏輯處理單元Processor(名稱與圖不完全一致),Processor將訊息寫入Redis/MongoDb。
這個過程中有三個環節會造成順序不一致
1、訊息msgid在Dispatcher節點生成(採用類snowflake演算法),由於不同節點時間可能存在誤差,有可能造成msgid和時序不一致
2、Kafka有多個patition,不同patition不能保證訊息順序
3、Processor是多例項部署,多執行緒處理,也不能保證順序
三、解決辦法
1、服務端嚴格有序
應用神奇的hash演算法,把屬於同一使用者的訊息路由到相同的Dispatcher節點,相同的Kafka分割槽,相同的Processor執行緒即可保證訊息循序性。但是對於群訊息,極端情況下還是可能出現時序問題(當然要丟訊息還需要客戶端正好執行Sync同步,這個機率極低)
2、客戶端補償
服務端為Timeline中的每條訊息都進行嚴格遞增編號,叫做sequenceid。從1開始,2、3、4……加一遞增。這樣,客戶端拉取到訊息,能夠透過sequenceid感知是否丟失訊息。如果丟失訊息,可以再次嘗試拉取。
這裡有個問題,這個嚴格編號服務我們利用了redis,萬一redis資料丟失怎麼辦呢?個人收件箱Timeline中最新一條訊息就是已有的最大編號,redis資料萬一丟失了可以從這條訊息中取得之前的最大編號。
透過這兩個方法,能夠確保訊息可靠性。
微信ID:farmerbrag
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31556438/viewspace-2219241/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- RabbitMq如何確保訊息不丟失MQ
- Kafka如何保證訊息不丟之無訊息丟失配置Kafka
- RabbitMQ-如何保證訊息不丟失MQ
- Oracle Goldengate是如何保證資料有序和確保資料不丟失的?OracleGo
- 基於TimeLine模型的訊息同步機制模型
- 訊息推送平臺有沒有保證資料不丟?
- 3DMAX模型匯出到Unity之中如何確保材質不丟失3D模型Unity
- 高併發場景下,如何保證生產者投遞到訊息中介軟體的訊息不丟失?
- Storm確保訊息被消費ORM
- 關於MQ的幾件小事(四)如何保證訊息不丟失MQ
- 阿里二面:要保證訊息不丟失,又不重複,訊息佇列怎麼選型?阿里佇列
- RabbitMQ使用教程(四)如何通過持久化保證訊息99.99%不丟失?MQ持久化
- rocketmq有序訊息的(四)MQ
- 如何確保TCP包的有序傳輸?TCP
- 高併發場景下,如何保證生產者投遞到訊息中介軟體的訊息不丟失?【石杉的架構筆記】架構筆記
- 消費端如何保證訊息佇列MQ的有序消費佇列MQ
- MQ不丟訊息,究竟是怎麼實現的?MQ
- Kafka 訊息丟失與消費精確一次性Kafka
- RabbitMQ防止訊息丟失MQ
- RabbitMQ中釋出者透過確認機制確保訊息釋出MQ
- RabbitMQ-如何保證訊息在99.99%的情況下不丟失MQ
- RocketMQ訊息丟失解決方案:事務訊息MQ
- Elasticsearch如何保證資料不丟失?Elasticsearch
- RabbitMq之訊息確認MQ
- 面試官問:Kafka 會不會丟訊息?怎麼處理的?面試Kafka
- Rabbitmq可靠訊息投遞,訊息確認機制MQ
- 如何處理RabbitMQ 訊息堆積和訊息丟失問題MQ
- Redis能保證資料不丟失嗎?Redis
- RabbitMQ 訊息確認機制MQ
- RocketMq訊息丟失問題解決MQ
- 《RabbitMQ》 | 訊息丟失也就這麼回事MQ
- RabbitMQ訊息佇列(九):Publisher的訊息確認機制MQ佇列
- BigDecimal為什麼能保證精度不丟失?Decimal
- stm32DMA+訊息佇列實現串列埠資料接收不丟包佇列串列埠
- 訊息佇列-如何保證訊息的不被重複消費(如何保證訊息消費的冪等性)佇列
- 訊息佇列之如何保證訊息的可靠傳輸佇列
- RocketMQ的訊息是怎麼丟失的MQ
- 面試官:請談談寫入訊息中介軟體的資料,如何保證不丟失?【石杉的架構筆記】面試架構筆記