<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                > 為什么需要消息隊列 使用消息隊列最主要的三個原因:異步、削峰、解耦。 - 異步:一個下單流程,你需要扣積分、扣優惠卷、發短信等,有些耗時又不需要立即處理的事,可以丟到隊列里延遲處理。 - 削峰:平常流量不高,突然推出一個優惠活動,請求量極速上升。由于服務器 Redis、MySQL 承受能力不一樣,如果請求全部接收,服務器就會出問題。這時可以將請求放到隊列里,按照服務器的能力去消費。 - 解耦:一個訂單流程,你扣積分、扣優惠券、發短信等需要調用多個接口,出現問題不好排查。像發短信有很多地方需要調用,如果哪天修改了短信接口參數,用到的地方都得修改。這時可以將要發送的內容放到隊列里,起一個服務去消費,統一發送短信。 ![](https://img.kancloud.cn/ce/02/ce0259fec11f4c68de14106cfc15bbfe_709x566.png) > 高吞吐、高可用 MQ 對比分析 看了各大招聘網站,提到較多的消息隊列有:RabbitMQ、RocketMQ、Kafka 以及 Redis 的消息隊列和發布訂閱。 Redis 隊列是用 List 數據結構實現的,一端 push,另一端 pop,一條消息只能被一個程序所消費。如果要一對多消費,可以用 Redis 的發布訂閱。Redis 發布訂閱是實時消費的,服務端不會保存生產的消息,也不會記錄客戶端消費到哪一條。如果客戶端宕機,消息就會丟失。這時就需要用到高級的消息隊列,如 RocketMQ、Kafka 等。 ZeroMQ 只有點對點模式和 Redis 發布訂閱差不多,如果不是對性能要求特別高,我會用其它隊列代替,畢竟關解決開發所需的依賴庫就夠折騰的。 RabbitMQ 多語言支持比較完善,特性的支持也比較齊全,適合在消息量級不是很高的情況下。 RocketMQ 和 Kafka 性能差不多,基于 Topic 的訂閱模式。RocketMQ 支持分布式事務,但在集群下主從不能自動切換,導致了一系列小問題。相比于其它集群是用 Master-Slave 模式,在 Master 沒有宕機時,Slave 作為災備,空閑著機器。 Kafka 采用的是 Leader-Slave 模式,每臺服務器既是 Master 也是 Slave。 | ActiveMQ | RabbitMQ | RocketMQ | Kafka | ZeroMQ | | :--------- | :------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :--------------------------------------------------- | | 吞吐量 | 比 RabbitMQ 低 | 2.6w/s(消息做持久化) | 11.6w/s | 17.3w/s | | 開發語言 | Java | Erlang | Java | Scala/Java | | 主要維護者 | Apache | Mozilla/Spring | Alibaba | Apache | | 訂閱形式 | 點對點(P2P)、廣播(發布—訂閱) | 提供了 4 種:direct、topic、Headers 和 fanout。fanout 就是廣播模式 | 基于 topic/messageTag 以及按照消息類型、屬性進行正則匹配的發布訂閱模式 | 基于 topic 以及按照 topic 進行正則匹配的發布訂閱模式 | | 持久化 | 支持少量堆積 | 支持少量堆積 | 支持大量堆積 | 支持大量堆積 | | 順序消息 | 不支持 | 不支持 | 支持 | 支持 | | 消息回溯 | 不支持 | 不支持 | 支持指定時間點的回溯 | 支持指定分區 offset 位置的回溯 | > Kafka 相關概念 在高可用下,Kafka 會部署多臺,避免 Kafka 宕機后,服務無法訪問,其中每一臺 Kafka 機器就是一個 Broker。Kafka 節點的信息和 Leader 的選舉等等操作需要依賴 ZooKeeper。 同樣地,為了避免 ZooKeeper 宕機導致服務無法訪問,ZooKeeper 也需要部署多臺。生產者的數據是寫入到 Kafka 的 Leader 節點,Follower 節點的 Kafka 從 Leader 中拉取數據同步。在寫數據時,需要指定一個 Topic,也就是消息的類型。一個 Topic 下可以有多個 Partition,將數據分散存儲在 Partition 下。一個 Topic 下一個也可以有多個 Replica,每一個 Replica 都是這個 Topic 的完整數據備份。Producer 生產消息,Consumer 消費消息。在沒給 Consumer 指定 Consumer Group 時會創建一個臨時消費組。Producer 生產的消息只能被同一個 Consumer Group 中的一個 Consumer 消費。 - broker:Kafka 集群中包含的服務器。 - zookeeper:Kafka 通過 ZooKeeper 來存儲集群的 meta 信息。 - leader:replica 中的一個角色,producer 和 consumer 只跟 leader 交互。 - follower:replica 中的一個角色,從 leader 中復制數據。 - controller:Kafka 集群中的其中一個服務器,用來進行 leader election 以及 各種 failover。 - topic:主題:每條發布到 Kafka 集群的消息屬于的類別 - partition:分區,partition 是物理上的概念,每個 topic 包含一個或多個 partition。Kafka 分配的單位是 partition。 - replica:副本,partition 的副本,保障 partition 的高可用。 - producer:消息的生產者。 - consumer:消息的消費者。 - consumer group:消費組,每個 consumer 都屬于一個 consumer group,每條消息只能被 consumer group 中的一個 consumer 消費,但可以被多個 consumer group 消費。 > 分區、副本、消費組 - 分區 主題的分區數有多少個,這個主題的數據就會被分成多少份。這個分區數最好就是消費者數的整數倍。 如果分區數小于消費者數,前面的消費者會分到一個分區的數據消費,后面超過分區數的消費者將無消費消費,除非前面的消費者宕機了。如果分區數大于消費者數,每個消費者至少分配到一個分區的數據,兩個消費者間分區數相差不超過一,如果有新的消費者加入,會把那些分區數多的消費者分區分配給新的消費者。 分區數可以設置成 6、12 等數值。比如 6,當消費者只有一個時,這 6 個分區都歸這個消費者,后面再加入一個消費者時,每個消費者都負責 3 個分區,后面再加入一個消費者時,每個消費者就負責 2 個分區。每個消費者分配到的分區數是一樣的,可以均勻地消費。另外同一個分區寫入是有順序的,如果要保證全局有序,那只能設置一個分區。如果要消費者也有序,消費者也只能有一個。 - 副本 主題的副本數即數據備份的個數,如果副本數為 1 , 即使 Kafka 機器有多個,當該副本所在的機器宕機后,對應的數據將訪問失敗。 集群模式下創建主題時,如果分區數和副本數都大于 1,主題會將分區 Leader 較均勻的分配在有副本的 Kafka 上。這樣客戶端在消費這個主題時,可以從多個臺機器上的 Kafka 消息數據,是實現分布式的關鍵。 副本數不是越多越好,從節點需要從主節點拉取數據同步,一般設置成和 Kafka 機器數一樣即可。如果只需要用到高可用的話,可以采用 N+1 策略,副本數設置為 2,專門弄一臺 Kafka 來備份數據。然后數據分布存儲在 N 臺 Kafka 上,+1 臺 Kafka 保存著完整的主題數據。 Replicas 表示在哪些 Kafka 機器上有主題的副本,Isr 表示當前有副本的 Kafka 機器上還存活著的 Kafka 機器。主題分區中所涉及的 Leader Kafka 宕機時,會將宕機 Kafka 涉及的分區分配到其它可用的 Kafka 節點上。如下: ``` Topic:demo_service PartitionCount:4 ReplicationFactor:2 Configs: Topic: demo_service Partition: 0 Leader: 171 Replicas: 171,170 Isr: 171,170 Topic: demo_service Partition: 1 Leader: 170 Replicas: 170,171 Isr: 170,171 Topic: demo_service Partition: 2 Leader: 171 Replicas: 171,170 Isr: 171,170 Topic: demo_service Partition: 3 Leader: 170 Replicas: 170,171 Isr: 170,171 ``` - 消費組 每一個消費組記錄者各個主題分區的消費偏移量,在消費的時候,如果沒有指定消費組,會默認創建一個臨時消費組。消費指定消費組時,主題的分區只能被某個客戶端消費,即生成者生產的消息只能被相同消費組下某個消費者消費。如果想要一條消息可以被多個消費者消費,可以加入不同的消費組。 ``` TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-ID demo_service 0 2003 2005 2 client1-7b05d48b-b2ae-4b31-89e2-010ce84b1c11 /175.191.15.200 client1 demo_service 1 1916 1918 2 client1-7b05d48b-b2ae-4b31-89e2-010ce84b1c11 /175.191.15.200 client1 demo_service 2 1972 1996 24 client2-116fcb66-b7f4-4162-bb46-6784e501a36a /175.191.11.89 client2 demo_service 3 2002 2022 20 client2-116fcb66-b7f4-4162-bb46-6784e501a36a /175.191.11.89 client2 ``` > 重復消費和數據丟失問題 重復消費和數據丟失問題主要分三種情況: 生產者發送消息成功后不等 Kafka 同步完成的確認繼續發送下一條消息,在發的過程中如果 Leader Kafka 宕機了,但 Producer 并不知情,發出去的信息 Broker 就收不到導致數據丟失。解決方案是將 request.required.acks 設置為 -1,表示 Leader 和 Follower 都收到消息才算成功。 - request.required.acks=0 表示發送消息即完成發送,不等待確認(可靠性低,延遲小,最容易丟失消息) - request.required.acks=1 表示當 Leader 收到消息返回確認后才算成功 消費者有兩種情況,一種是消費的時候自動提交偏移量導致數據丟失:拿到消息的同時將偏移量加一,如果業務處理失敗,下一次消費的時候偏移量已經加一了,上一個偏移量的數據丟失了。 另一種是手動提交偏移量導致重復消費:等業務處理成功后再手動提交偏移量,有可能出現業務成功,偏移量提交失敗,那下一次消費又是同一條消息。怎么解決呢? 這是一個 or 的問題,偏移量要么手動提交要么自動提交,對應的問題是要么數據丟失要么重復消費。如果消息要求實時性高,丟個一兩條沒關系的話可以選擇自動提交偏移量。如果消息一條都不能丟的話可以將業務設計成冪等,不管消費多少次都一樣。 > 如何確保一條消息只被一個服務消費 前面已經講到,同個主題的一個分區只能被消費組里某個消費者消費。在消費主題時,將這些消費者都加入相同的消費組,生成的消息就只能被一個客戶端服務消費。 > 操作命令 - 查看 Kafka 中 Topic: ``` [root@VM_0_17_centos bin]# ./kafka-topics.sh --zookeeper 127.0.0.1:2181 --list __consumer_offsets demo_service ``` - 查看 Topic 詳情: ``` [root@VM_0_17_centos bin]# ./kafka-topics.sh --zookeeper 127.0.0.1:2181 --describe --topic demo_service Topic:demo_service PartitionCount:4 ReplicationFactor:2 Configs: Topic: demo_service Partition: 0 Leader: 171 Replicas: 171,170 Isr: 171,170 Topic: demo_service Partition: 1 Leader: 170 Replicas: 170,171 Isr: 170,171 Topic: demo_service Partition: 2 Leader: 171 Replicas: 171,170 Isr: 171,170 Topic: demo_service Partition: 3 Leader: 170 Replicas: 170,171 Isr: 170,171 ``` - 消費主題: ``` ./kafka-console-consumer.sh --bootstrap-server localhost:9092,localhost:9093 --group test_group --topic demo_service--from-beginning this is a good test - 1 this is a good test - 2 this is a good test - 3 ``` - 查看 Kafka 中 Groups: ``` [root@VM_0_17_centos bin]# ./kafka-consumer-groups.sh --bootstrap-server localhost:9092,localhost:9093 --list test-group ``` - 查看 Group 消費情況: ``` [root@VM_0_17_centos bin]# ./kafka-consumer-groups.sh --bootstrap-server localhost:9092,localhost:9093 --describe --group test_group TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-ID demo_service 0 2003 2005 2 client1-7b05d48b-b2ae-4b31-89e2-010ce84b1c11 /175.191.15.200 client1 demo_service 1 1916 1918 2 client1-7b05d48b-b2ae-4b31-89e2-010ce84b1c11 /175.191.15.200 client1 demo_service 2 1972 1996 24 client2-116fcb66-b7f4-4162-bb46-6784e501a36a /175.191.11.89 client2 demo_service 3 2002 2022 20 client2-116fcb66-b7f4-4162-bb46-6784e501a36a /175.191.11.89 client2 ``` > 總結 - Kafka 高可用 副本是數據的備份,有多個副本分布在不同的機器上時,如果有一臺 Kafka 宕機了,會自動切換到其它可用的 Kafka 上。如果你的 Kafka 有多臺,但是主題的副本數只有一個,那么當 Kafka 機器有宕機時,對應的數據將不可訪問。 - Kafka 高并發 分區是實現高并發的關鍵,當然還需要多個副本。分區數有多個并且分區 Leader 分布在不同的機器上,這樣主題生產的數據可以均勻的保存在多臺機器上,消費這個主題時可以從多臺機器上獲取數據。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看