1.概述
Apache Pulsar 是靈活的發(fā)布-訂閱消息系統(tǒng)(Flexible Pub/Sub messaging),采用計(jì)算與存儲(chǔ)分離的架構(gòu)。雅虎在 2013 年開始開發(fā) Pulsar ,于 2016 年首次開源,目前是 Apache 軟件基金會(huì)的頂級(jí)項(xiàng)目。Pulsar 具有支持多租戶、持久化存儲(chǔ)、多機(jī)房跨區(qū)域數(shù)據(jù)復(fù)制、高吞吐、低延遲等特性。
2.Pulsar 組件
Pulsar 集群主要由以下三部分組成:
- Broker:Pulsar 的 broker 是一個(gè)無狀態(tài)組件,本身不存儲(chǔ)數(shù)據(jù)。主要負(fù)責(zé)處理 producer 和 consumer的請(qǐng)求,消息的復(fù)制與分發(fā),數(shù)據(jù)的計(jì)算。
- Zookeeper:主要用于存儲(chǔ)元數(shù)據(jù)、集群配置,任務(wù)的協(xié)調(diào)(例如哪個(gè) broker 負(fù)責(zé)哪個(gè)
topic),服務(wù)的發(fā)現(xiàn)(例如 broker 發(fā)現(xiàn) bookie 的地址)。 - Bookeeper:主要用于數(shù)據(jù)的持久化存儲(chǔ)。除了消息數(shù)據(jù),cursors 也會(huì)被持久化到 Bookeeper,cursors 是消費(fèi)端訂閱消費(fèi)的位移。Bookeeper 中每一個(gè)存儲(chǔ)節(jié)點(diǎn)叫做 bookie。
3. Pulsar 基本概念
Producer & Consumer
身為?個(gè) Pub/Sub 系統(tǒng),?先的存在要素必然是 producer(?產(chǎn)者)。producer 發(fā)送數(shù)據(jù)給 Pulsar,將消息以 append 的形式追加到 topic 中。發(fā)送的數(shù)據(jù)是 key/value 形式的,并且數(shù)據(jù)會(huì)上 schema 的信息。Pulsar 會(huì)確保?個(gè) producer 往 topic 發(fā)送的消息滿??定的 schema 格式。
既然有 producer 負(fù)責(zé)生產(chǎn)消息,那么相應(yīng)地就有 consumer 負(fù)責(zé)消費(fèi)消息。在 Pulsar 中 consumer 可以使用不同的訂閱模式來接受消息。
Subscription
Pulsar ?將 consumer 接收消息的過程稱之為:subscription(訂閱),類似于 Kafka 的 consumer group(消費(fèi)組)。?個(gè)訂閱?的所有 consumer,會(huì)作為?個(gè)整體去消費(fèi)這個(gè) topic ?的所有消息。Pulsar 有四種訂閱模式:獨(dú)占(exclusive)、故障轉(zhuǎn)移(failover)、共享(shared)、共享鍵(key_shared)。
Exclusive
在 exclusive 模式下,一個(gè) subscription 只允許被一個(gè) consumer 用于訂閱 topic ,如果多個(gè) consumer 使用相同的 subscription 去訂閱同一個(gè) topic,則會(huì)發(fā)生錯(cuò)誤。exclusive 是默認(rèn)的訂閱模式。如下圖所示,Consumer A-0 和 Consumer A-1 都使用了相同的 subscription(相同的消費(fèi)組),只有 Consumer A-0 被允許消費(fèi)消息。
Failover
在 failover 模式下,多個(gè) consumer 允許使用同一個(gè) subscription 去訂閱 topic。但是對(duì)于給定的 topic,broker 將選擇?個(gè) consumer 作為該 topic 的主 consumer ,其他 consumer 將被指定為故障轉(zhuǎn)移 consumer 。當(dāng)主 consumer 失去連接時(shí),topic 將被重新分配給其中?個(gè)故障轉(zhuǎn)移 consumer ,?新分配的 consumer 將成為新的主 consumer 。發(fā)?這種情況時(shí),所有未確認(rèn)的消息都將傳遞給新的主 consumer ,這個(gè)過程類似于 Kafka 中的 consumer 組重平衡(rebalance)。
如下圖所示,Consumer B-0 是 topic 的主 consumer ,當(dāng) Consumer B-0 失去連接時(shí),Consumer B-1 才能成為新的主 consumer 去消費(fèi) topic。
Shared
在 shared 模式下,多個(gè) consumer 可以使用同一個(gè) subscription 去訂閱 topic。消息以輪詢的方式分發(fā)給 consumer ,并且每條消費(fèi)僅發(fā)送給一個(gè) consumer 。當(dāng)有 consumer 失去連接時(shí),所有發(fā)送給該 consumer 但未被確認(rèn)的消息將被重新安排,以便發(fā)送給該 subscription 上剩余的 consumer 。
如下圖所示,Consumer C-1,Consumer C-2,Consumer C-3 以輪詢的方式接受消息。
shared 模式有以下限制:
- 消息不能保證有序。
- 不支持批量 ack。
Key_Shared
key_shared 是 Pulsar 2.4.0 以后?個(gè)新訂閱模式。在 shared 模式下,多個(gè) consumer 可以使用同一個(gè) subscription 去訂閱 topic。消息按照 key 分發(fā)給 consumer ,含有相同 key 的消息只被發(fā)送給同一個(gè) consumer 。
如下圖所示,不同的 consumer 只接受到對(duì)應(yīng) key 的消息。
key_shared 模式有以下限制:
- 需要為每條消息指定一個(gè) key 或者 orderingKey。
- 不支持批量 ack。
- producer 應(yīng)該禁用 batch 或者使用基于
key 的 batch。
Cursor
cursor 是用來存儲(chǔ)一個(gè) subscription 中消費(fèi)的狀態(tài)信息(類似 Kafka 中的 offset,偏移量)。Pulsar 將 subscription 的 cursor 存儲(chǔ)至 BookKeeper 的 ledger 中。
存儲(chǔ)模型
- 第一層抽象是 topic(partition),topic 是一個(gè)邏輯的概念,topic 是消息的集合,所有?產(chǎn)者的消息,都會(huì)歸屬到指定的
topic ?。所有在 topic ?的消息,會(huì)按照?定的規(guī)則,被切分成不同的分區(qū)(partition)。在 Kafka 中
partition 是真正的物理單元,但是在 Pulsar 中 partition 仍然是一個(gè)邏輯的概念。 - Pulsar 把 partition 進(jìn)一步分成多個(gè)分片(segment),segment 是 Pulsar
中真正的物理單元,Pulsar 中的數(shù)據(jù)是持久化在 Bookeeper 中的,segment 其實(shí)對(duì)應(yīng)的就是 Bookeeper 中的
ledger。 - 在分片中存儲(chǔ)了更小粒度的 entry,entry 存儲(chǔ)的是一條或者一個(gè) batch 的消息,batch 是一次性批量提交多條消息。
?最底層的 message 通常包含 Message ID,由以下幾個(gè)部分組成: - partition-index
- ledger-id(segment)
- entry-id
- batch-index
Broker
Pulsar 中的 broker 是無狀態(tài)的,不存儲(chǔ)數(shù)據(jù),真正的數(shù)據(jù)存儲(chǔ)在 Bookeeper 上。每個(gè) topic 的 partition 都會(huì)分配到某一個(gè) borker 上,producer 和 consumer 則會(huì)連接到這個(gè) broker,從而向該 topic 的 partition 發(fā)送和消費(fèi)消息。broker 主要負(fù)責(zé)消息的復(fù)制與分發(fā),數(shù)據(jù)的計(jì)算。
Namespace & Tenant
Pulsar 從一開始就支持多租戶,topic 的名稱是層級(jí)化的,最上層是租戶(tenant),然后是命名空間(namespace),最后才是 topic。
{persistent|non-persistent}://tenant/namespace/topic
- 租戶可以跨集群分布,每個(gè)租戶都可以有單獨(dú)的認(rèn)證和授權(quán)機(jī)制。租戶也是存儲(chǔ)配額、消息 TTL 和隔離策略的管理單元。
- 命名空間是租戶的管理單元,命名空間上配置的策略適用于在該命名空間中創(chuàng)建的所有 topic。租戶可以使用 REST API 和
pulsar-admin CLI 工具來創(chuàng)建多個(gè)命名空間。 - persistent|non-persistent 標(biāo)識(shí)了 topic 的類型,默認(rèn)情況下 topic 是持久化存儲(chǔ)到磁盤上的。
Ack 機(jī)制
在 Pulsar 中支持了兩種 ack 的機(jī)制,分別是單條 ack 和批量 ack。單條 ack(AckIndividual)是指 consumer 可以根據(jù)消息的 messageID 來針對(duì)某一個(gè)特定的消息進(jìn)行 ack 操作;批量 ack(AckCumulative)是指一次 ack 多條消息。
消息生命周期
默認(rèn)情況下,Pulsar Broker 會(huì)對(duì)消息做如下處理:
- 當(dāng)消息被 consumer 確認(rèn)之后,會(huì)立即執(zhí)行刪除操作。
- 對(duì)于未被確認(rèn)的消息會(huì)存儲(chǔ)到 backlog 中。
但是,很多線上的生產(chǎn)環(huán)境下,這種默認(rèn)行為并不能滿足我們的生產(chǎn)需求,所以,Pulsar 提供了
如下配置策略來覆蓋這些行為:
- Retention 策略:用戶可以將 consumer 已經(jīng)確認(rèn)的消息保留下來。
- TTL 策略:對(duì)于未確認(rèn)的消息,用戶可以通過設(shè)置 TTL 來使未確認(rèn)的消息到達(dá)已經(jīng)確認(rèn)的狀態(tài)。
上述兩種策略的設(shè)置都是在NameSpace 的級(jí)別進(jìn)行設(shè)置。
Backlog
backlog 是未被確認(rèn)的消息的集合,它有一個(gè)大前提是,這些消息所在的 topic 是被 broker 所持久化的,在默認(rèn)情況下,用戶創(chuàng)建的 topic 都會(huì)被持久化。換句話說,broker 會(huì)將所有未確認(rèn)或者未處理的消息都存放到 backlog 中。
需要注意的是,對(duì) backlog 進(jìn)行配置時(shí),我們需要明確以下兩點(diǎn):
- 在當(dāng)前的 namespace 下,每一個(gè) topic 允許 backlog 的大小是多少。
- 如果超過設(shè)定的 backlog 的閾值,將會(huì)執(zhí)行哪些操作。
當(dāng)超過設(shè)定的 backlog 的閾值,Pulsar 提供了以下三種策略供用戶選擇:
Retention
Retention 策略的設(shè)置提供了兩種方式:
- 消息的大小,默認(rèn)值:defaultRetentionSizeInMB=0
- 消息被保存的時(shí)間,默認(rèn)值:defaultRetentionTimeInMinutes=0
Time To Live(TTL)
TTL 參數(shù)就像附在每條消息上的秒表,用于定義允許消息停留在未確認(rèn)狀態(tài)的時(shí)間。當(dāng) TTL 過期時(shí),Pulsar 會(huì)自動(dòng)將消息更改為已確認(rèn)狀態(tài)(并使其準(zhǔn)備刪除)。TTL 只去處理一件事情,就是將未被確認(rèn)的消息變?yōu)楸淮_認(rèn)的狀態(tài),TTL 本身不會(huì)去涉及相應(yīng)的刪除操作。
消息寫入流程
producer 向 topic 的 partition 對(duì)應(yīng)的 broker 發(fā)送消息。broker 以并行的方式將消息寫到多個(gè) bookie 中,當(dāng)指定數(shù)量的 bookie 寫入成功時(shí),broker 會(huì)向 producer 響應(yīng)消息寫入成功。
消息讀取流程
consumer 向訂閱 topic 的 partition 對(duì)應(yīng)的 broker 請(qǐng)求消息,如果消息在 broker 的緩存中存在,則 broker 直接將消息返回給 consumer 。如果緩存中不存在,broker 去 bookie 中讀取消息,然后返回給 consumer 。consumer 在完成消費(fèi)后,向 broker 響應(yīng) ack 表示完成消費(fèi)。consumer ack 的元數(shù)據(jù)也是會(huì)持久化在 bookie 中的。
4.Pulsar vs Kafka
數(shù)據(jù)存儲(chǔ)文章來源:http://www.zghlxwxcb.cn/news/detail-457448.html
- Kafka 的服務(wù)層和存儲(chǔ)層位于同一節(jié)點(diǎn)上,broker 負(fù)責(zé)數(shù)據(jù)的計(jì)算與存儲(chǔ)。
- Pulsar 的架構(gòu)將服務(wù)層與存儲(chǔ)層解耦:無狀態(tài) broker 節(jié)點(diǎn)負(fù)責(zé)數(shù)據(jù)服務(wù);bookie 節(jié)點(diǎn)負(fù)責(zé)數(shù)據(jù)存儲(chǔ)。
- 另外 Pulsar 還支持分層存儲(chǔ),如主存儲(chǔ)(基于 SSD)、歷史存儲(chǔ)(S3)等??梢詫⒃L問頻率較低的數(shù)據(jù)卸載到低成本的持久化存儲(chǔ)(如
AWS S3、Azure 云)中。
存儲(chǔ)單元:文章來源地址http://www.zghlxwxcb.cn/news/detail-457448.html
- Kafka 和 Pulsar 都有類似的消息概念,客戶端通過主題與消息系統(tǒng)進(jìn)行交互,每個(gè)主題都可以分為多個(gè)分區(qū)。Pulsar 和Kafka 之間的根本區(qū)別在于 Kafka 是以分區(qū)(partition)作為數(shù)據(jù)的存儲(chǔ)單元,而 Pulsar是以分片(segment)作為為數(shù)據(jù)的存儲(chǔ)單元。
- 在 Kafka中,分區(qū)只能存儲(chǔ)在單個(gè)節(jié)點(diǎn)上并復(fù)制到其他節(jié)點(diǎn),其容量受最小節(jié)點(diǎn)容量的限制。當(dāng)對(duì)集群進(jìn)行擴(kuò)容時(shí)或者發(fā)送副本故障時(shí),會(huì)觸發(fā)數(shù)據(jù)的拷貝,這將耗費(fèi)很長(zhǎng)的時(shí)間。
- 在 Pulsar 中,同樣是以分區(qū)作為為邏輯單元,但是是以 segment為物理存儲(chǔ)單元。分區(qū)隨著時(shí)間的推移會(huì)進(jìn)行分段,并在整個(gè)集群中均衡分布,能夠有效迅速地?cái)U(kuò)展。
名詞對(duì)應(yīng)表
根據(jù)個(gè)人對(duì) Pulsar 和 Kafka 的理解,整理如下 Pulsar 和 Kafka 的名詞對(duì)應(yīng)表:
Pulsar | Kafka |
---|---|
Topic | Topic |
Partition | Partition |
Segment(Ledger) | Segment |
Bookie | Broker |
Broker | Client SDK |
Write Quorum Size (Qw) | Replica Number |
Ack Quorum Size (Qa) | request.required.acks |
- Pulsar 和 Kafka 都是以 topic 描述一個(gè)基本的數(shù)據(jù)集合,topic 數(shù)據(jù)又邏輯分為若干個(gè) partition。
- 但 Kafka 以 partition 作為物理存儲(chǔ)單位,每個(gè) partition 必須作為一個(gè)整體(一個(gè)目錄)存儲(chǔ)在某一個(gè) broker上,雖然 Kafka 也會(huì)將一個(gè) partition 分成多個(gè) segment,但是這些 segment 是存在 Kafka broker的同一個(gè)目錄下。而 Pulsar 的每個(gè) partition 是以 segment(對(duì)應(yīng)到 Bookkeeper 的 ledger)作為物理存儲(chǔ)的單位,所以 Pulsar 中的一個(gè)邏輯上有序的 partition 數(shù)據(jù)集合在物理上會(huì)均勻分散到多個(gè) bookie 節(jié)點(diǎn)中。
- Pulsar 的數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn) Bookkeeper 被稱為 bookie,相當(dāng)于一個(gè) Kafka broker。
- ensemble size 表示 topic 要用到的物理存儲(chǔ)節(jié)點(diǎn) bookie 個(gè)數(shù),其副本數(shù)目 Qw 不能超過 bookie個(gè)數(shù),因?yàn)橐粋€(gè) bookie 上不能存儲(chǔ)超過一個(gè)以上的數(shù)據(jù)副本。
- Qa 是每次寫請(qǐng)求發(fā)送完畢后需要回復(fù)確認(rèn)的 bookie 的個(gè)數(shù)。
到了這里,關(guān)于Apache Pulsar入門指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!