六 消息隊列復習
1 為什麽使用消息隊列?
六個字: 解耦、異步、消峰。
2 使用消息隊列有什麽缺點?
消息隊列掛了,系統就不能用了,系統可用性降低。
3 消息隊列的高可用?
kafka使用zookeeper,master/slave,保證高可用;
Kafka通過Zookeeper管理集群配置,選舉leader,以及在Consumer Group發生變化時進行rebalance
4 如何保證消息不被重復消費(冪等性)?
kafka有offset的概念,就是每一個消息都有一個offset,kafka消費過消息後,需要提交offset,讓消息隊列知道自己已經消費過了;
造成重復消費的原因:因為網絡傳輸等等故障,確認信息沒有傳送到消息隊列
- insert操作,主鍵唯一性可以保證。
- update, 不會有問題。
- 其他情況下,可以用第三方工具做消費記錄(比如redis),給消息分配全局ID。將<id,message>以K-V形式寫入redis。消費前,先去redis中查詢有沒有消費記錄。
5 如何保證消費的可靠性傳輸?
我們在使用消息隊列的過程中,應該做到消息不能多消費,也不能少消費。
其實這個可靠性傳輸,每種MQ都要從三個角度來分析:生產者弄丟數據、消息隊列弄丟數據、消費者弄丟數據
(1)生產者弄丟數據:
Producer在發布消息到某個Partition時,先通過ZooKeeper找到該Partition的Leader,然後無論該Topic的Replication Factor為多少(也即該Partition有 多少個Replica),Producer只將該消息發送到該Partition的Leader。Leader會將該消息寫入其本地Log。每個Follower都從Leader中pull數據
在kafka生產中,基本都有一個leader和多個follwer。follwer會去同步leader的信息。
因此,為了避免生產者丟數據,做如下兩點配置:
1. 第一個配置要在producer端設置acks=all。這個配置保證了,follwer同步完成後,才認為消息發送成功。
2. 在producer端設置retries=MAX,一旦寫入失敗,這無限重試;
(2) 消息隊列丟數據:
針對消息隊列丟數據的情況,無外乎就是,數據還沒同步,leader就掛了,這時zookpeer會將其他的follwer切換為leader,那數據就丟失了。針對這種情況,應 該做兩個配置。
1. replication.factor參數,這個值必須大於1,即要求每個partition必須有至少2個副本
2. min.insync.replicas參數,這個值必須大於1,這個是要求一個leader至少感知到有至少一個follower還跟自己保持聯系
這兩個配置加上上面生產者的配置聯合起來用,基本可確保kafka不丟數據。
(3)消費者弄丟數據:消費者丟數據一般是因為采用了自動確認消息模式,至於解決方案,采用手動確認消息即可。
6 如何保證消息的順序性?
針對這個問題,通過某種算法,將需要保持先後順序的消息放到同一個消息隊列中(kafka中就是partition,rabbitMq中就是queue)。然後只用一個消費者去消費該隊列(kafka中,一個partition只能被一個consumer Group中的一個consumer消費)。
六 消息隊列復習