直播回顧| Apache Pulsar 2.10.0 新特性概覽

ApachePulsar發表於2022-04-08

關於 StreamNative

StreamNative 是一家開源基礎軟體公司,由 Apache 軟體基金會頂級專案 Apache Pulsar 創始團隊組建而成,圍繞 Pulsar 打造下一代雲原生批流融合資料平臺。StreamNative 作為 Apache Pulsar 商業化公司,專注於開源生態和社群構建,致力於前沿技術領域的創新,創始團隊成員曾就職於 Yahoo、Twitter、Splunk、EMC 等知名大公司。

導語:本文是 Apache Pulsar PMC 成員,StreamNative 首席架構師李鵬輝在 TGIP-CN 037 直播活動的文字整理版本。Pulsar 2.10.0 版本即將釋出,本場直播為大家帶來 Apache Pulsar 2.10.0 的主要新特性及版本解讀,解答大家對新版本對於技術細節的疑問。

點選 檢視回顧視訊

Pulsar 2.10.0 包含來自於 99 位貢獻者的 1000+ commits,其中諸多貢獻來自於國內的貢獻者,感謝大家對 Pulsar 的支援與貢獻。 本次版本釋出是一次新的里程碑,如此多的 commit 數量也為文件帶來了升級;Apache Pulsar 網站升級中,新網站 Beta 版本對文件進行了重新歸檔與完善,歡迎大家試用並提出寶貴意見

Apache Pulsar 2.10.0 版本新特性內容包括:

  • 去除對 ZooKeeper 的強依賴;
  • 新的消費型別 TableView;
  • 多叢集自動故障轉移;
  • Producer Lazy Loading + Partial RoundRobin;
  • Redeliver Backoff;
  • Init Subscription for DLQ;
  • 引入多叢集全域性 Topic Policy 設定支援以及 Topic 級別的跨地域複製配置;
  • ChunkMessageId;
  • 增加批量操作 Metadata 服務的支援:可以在大量 Topic 的場景下提升 Pulsar 穩定性;
  • ...

去除對 ZooKeeper API 強依賴

ZooKeeper 是 Pulsar 中使用非常廣泛的一個 API,舊版對該 API 的依賴無處不在,但這種依賴不利於使用者選擇其他型別的後設資料服務。為了解決這一問題,Pulsar 經過多個版本的迭代,做了大量準備和測試工作後終於在 2.10.0 版本去除了對 ZooKeeper 的強依賴。

目前新版支援三種後設資料服務:

  • ZooKeeper
  • Etcd
  • RocksDB(standalone)

其中需要注意的是 Etcd 目前沒有很好的 Java 客戶端,綜合考量使用要慎重。此外從 benchmark 測試成績來看 ZooKeeper 與 Etcd 的效能是相近的,使用者可以根據自身情況來選擇。

該特性的提案是 PIP 45 : Pluggable metadata interface(Metadata Store + Coordination Service)。顧名思義,這裡的 Metadata Store 是一個後設資料儲存,而 Coordination Service 則提供了一箇中心化服務來獲得全域性鎖。

2.10 版本還增加了 Metadata 批量操作支援,降低客戶端與服務端互動需求,大幅減輕了 metadata 的操作壓力。

# The metadata store URL
# Examples:
# * zk:my-zk-1:2181,my-zk-2:2181,my-zk-3:2181
# * my-zk-1:2181,my-zk-2:2181,my-zk-3:2181 (will default to ZooKeeper when the schema is not specified)


# * zk:my-zk-1:2181,my-zk-2:2181,my-zk-3:2181/my-chroot-path (to add a ZK chroot path) 

metadataStoreUrl=

# The metadata store URL for the configuration data. If empty, we fall back to use metadataStoreUrl configurationMetadataStoreUrl=

以上就是新特性的 API 實現,可以看到上述配置引數已經不再需要 ZooKeeper。但去除對 ZooKeeper 的依賴並不代表會將其移除。考慮到 ZooKeeper 還有大量使用者,使用較為廣泛,所以短期內官方並不會考慮刪除實現,而只是將其外掛化來方便使用。

更多減輕 ZooKeeper 依賴細節,可以閱讀部落格 Apache Pulsar 輕裝上陣:邁向輕 ZooKeeper 時代

新的消費型別 TableView

Pulsar 的消費模式比較多樣化,如今 2.10 版本再引入了 TableView,這是一個類似於 KV 的表格服務。它是一個不支援寫入的純檢視,可以直接在客戶端記憶體構建表格檢視,適合資料量不大的場景生成檢視。但 TableView 不太合適資料量較大、單臺機器的記憶體都難以承受的場景。

TableView 可用於配合 Topic Compaction,後者可以在服務端做 Key 的壓縮。這一特性的原理是隻在一個 snapshot 中儲存 key 的最新狀態,consumer 需要時只需檢視這個 snapshot,而無需去消耗更多成本讀取原始 backlog。TableView 可以與該特性無縫銜接,恢復 TableView 時就可以直接利用 broker 生成的 snapshot,從而減小恢復開銷。原視訊 22 分處具體介紹了這種壓縮的機制和使用場景

try (TableView<byte[]> tv = client. newTableViewBuilder (Schema.BYTES)
        .topic ("public/default/tableview-test")
        .autoUpdatePartitionsInterval(60, TimeUnit.SECONDS)
        .create()) {
    System.out.println("start tv size: " + tv.size());
    tv. forEachAndListen((k, v) -> System.out.println(k + "->"+ Arrays. toString(v)));

    while (true) f
        Thread. sleep (20000) ;
        System.out.println(tv.size)):
        tv. forEach((k, v) -> System, out.println("checkpoint: "+ k+ "->" + Arrays.toString(v)));
    }

} catch (Exception ex) {
    System.out.println("Table view failed: " + ex. getCause());
}

Cluster 自動故障轉移

ServiceUrlProvider provider = AutoClusterFailover.builder()
        .primary(primary)
        .secondary(Collections.singletonList(secondary))
        .failoverDelay(failoverDelay, TimeUnit.SECONDS)
        .switchBackDelay(switchBackDelay, TimeUnit.SECONDS)
        .checkInterval(checkInterval, TimeUnit.MILLISECONDS)
        .build();

Pulsar 支援多叢集,叢集間可同步資料,因此使用者經常會有叢集間的故障轉移需求,所以引入自動故障轉移特性。過去做故障轉移時需要通過域名切換,或者使用自制的輔助節點,但這些方法往往都需要人工介入,SLA 難以保障。新特性的優勢在於自動化與可配置,可設定 primary 與 secondary 叢集,配置延遲等引數,通過探活實現叢集自動按預期切換。但目前該特性在探活時只探測 Pulsar 埠是否接通,未來版本將繼續改進探活方式。

Producer Lazy loading + Partial RoundRobin

當前在一個規模較大的叢集中,如果 partition 比較多,則傳送訊息時 producer 需要輪詢所有 partition,且 partition 可能分佈在不同 broker 上可能產生巨大的連線壓力,如上圖上半部分。為此,該新特性實現了 producer 懶載入,這樣一來如果不用某個 partition 就不會建立它,減輕了系統負擔。而部分輪詢會先 List 所有 partition 再將它們 shuffle,實現不同客戶端寫入不同的 partition,減少 producer 例項與 broker 的連線數量,同樣可以降低系統壓力。需要注意的是 Shared consumer 暫時不支援這種機制,未來需要社群共同探索這一方面能否實現類似的機制。


PartitionedProducerImpl<byte[]> producerImpl = (PartitionedProducerImpl<byte[]>) pulsarClient.newProducer()
        .topic(topic)
        .enableLazyStartPartitionedProducers(true)
        .enableBatching(false)
        .messageRoutingMode(MessageRoutingMode.CustomPartition)
        .messageRouter(new PartialRoundRobinMessageRouterImpl(3))
        .create();  

Redeliver Backoff

client.newConsumer().negativeAckRedeliveryBackoff(MultiplierRedeliveryBackoff.builder()
        .minDelayMs(1000)
        .maxDelayMs(60 * 1000)
        .build()).subscribe();

client.newConsumer().ackTimeout(10, TimeUnit.SECOND)
        .ackTimeoutRedeliveryBackoff(MultiplierRedeliveryBackoff.builder()
        .minDelayMs(1000)
        .maxDelayMs(60 * 1000)
        .build()).subscribe();

Pulsar現有 ackTimeout 機制,如果使用 shared 訂閱,消費資料時可能在一段時間內無法簽收,則 ackTimeout 可以保證超過一定時間仍未簽收時客戶端自動重新投遞訊息,將訊息重新分發到其他 consumer 上。

訊息重新投遞的時間很難確定,長短不一,且隨著訊息處理失敗次數越來越多,延遲需要越來越長。為此引入了該 API,可以逐漸延長延遲。相比現有方法,這個特性的優勢在於開銷更小,不需要經過另一個 topic,且更加靈活。不足之處是一旦客戶端當機會導致訊息立即重試。另外該特性使用成本很低API 簡潔,很容易掌握。需要注意的是目前只有 Java 客戶端支援該特性,另外它可以配合死信佇列使用。

初始化死信佇列訂閱

Consumer<byte[]> consumer = pulsarClient.newConsumer(Schema.BYTES)
    .topic(topic)
    .subscriptionName(subscriptionName)
    .subscriptionType(SubscriptionType.Shared)
    .ackTimeout(1, TimeUnit.SECONDS)
    .deadLetterPolicy(DeadLetterPolicy.builder()
        .maxRedeliverCount(maxRedeliveryCount)
        .initialSubscriptionName(my-sub)
        .build())
    .receiverQueueSize(100)
    .subscriptionInitialPosition(SubscriptionInitialPosition.Earliest )
    .subscribe();

死信佇列的建立是懶建立策略,這就出現了一個問題:死信訊息尚未發生、topic 尚未建立時,就無法給 topic 指定資料保留策略。為此只能給 namespace 建立策略,粒度會很大。新版引入 InitialSubscriptionName,在設定死信佇列時可以在 create 時同時建立一個訂閱,這樣資料就可以保留下來。且對於死信佇列,大部分場景僅需一個訂閱處理即可,於是 訂閱就會和 InitialSubscriptionName 對應,這樣無需設定 retention,就可以保留髮到死信佇列的訊息。

跨叢集 topic 策略

bin/pulsar-admin topics set-retention -s 1G -t 1d --global my-topic

Message message = MessageBuilder.create()
    ...
    .setReplicationClusters(restrictDatacenters)
    .build();
producer.send(message);

該特性可以跨叢集應用 topic policy,通過 -global 引數對所有叢集生效。表面上來看一個全域性引數很容易實現,其實背後做了很多工作。主要是底層需要將 schema 同步到所有叢集,才能做到跨叢集應用。需要注意的是 broker 沒有重試策略,以下兩種方式任選其一:

  • 主動告知 broker 重試;
  • 斷開客戶端。

新的訊息 ID 型別 ChunkMessageId

public class ChunkMessageIdImpl extends MessageIdImpl implements Messaged {
    private final MessageIdImpl firstChunkMsgId;

    public ChunkMessageIdImpl(MessageIdImplfirstChunkMsgId,MessageIdImpllastChunkMsgId){
        super(lastChunkMsgId.getLedgerId(), lastChunkMsgId.getEntryId(), lastChunkMsgId.getPartitionIndex());
        this. firstChunkMsgId = firstChunkMsgId;
    }
    public MessageIdImplgetFirstChunkMessageId(){
        return firstChunkMsgId;
    }
    public MessageIdImplgetLastChunkMessageId(){
        return this;
    }

}

之前版本引入的 ChunkMessage 可以有效減輕系統壓力,但存在的問題是 Chunk 中只有最後的 MessageId 返回給客戶端,這樣客戶端就無法知曉前面的 Id。這個特性解決了 ChunkMessage 開始到結束對應的 Id 缺失問題,方便使用者 seek MessageId 並消費。目前該特性只有 Java 客戶端支援。

其他特性

  • Topic properties:給 Topic 附加 name 之外的更多資訊,與 metadata 一併儲存;
  • Metadata batch operation:提升效能;
  • CPP client:提供 chunk message 支援;
  • Broker graceful shutdown:支援 REST API 優雅地關閉 Broker,先將 Broker 從叢集拿掉後再關閉 Topic,避免繼續發起對 Broker 的連線;
  • Support creat a consumer in the paused state:在 create consumer 時可以指定暫停狀態,不向服務端獲取訊息;
  • ...

精選 Q&A

新特性介紹完畢後,李老師還對觀眾彈幕問題一一作了解答,以下為 QA 精選內容概要,詳情見視訊 54 分鐘後。

Q:Pulsar 是否支援 failover?

  • Pulsar 支援 failover 模式,且一個 partition 可以有多個 consumer,開銷主要存在於訊息簽收上。Pulsar 支援維護單條訊息簽收狀態,因此會有一定開銷;

Q:Pulsar 對 ack 的操作是 exactly once 嗎?

  • Pulsar 對不開啟 transaction 的情況預設是 at least once 實現,而不是 exactly once;

Q:ChunkMessage 支援事務嗎?

  • 目前暫不支援事務;

Q:Pulsar 的訊息傳送是否會有中間失敗後面成功的情況?

  • Pulsar 中所有訊息的傳送不會出現中間失敗後面成功的情況,其中一個失敗後面都會失敗;

Q:後設資料導致的叢集規模限制問題如何解決?

  • 2.10 版本暫未解決後設資料導致的叢集規模限制問題,未來考慮解決;

Q:KoP 支援 Kafka format 嗎?

  • 現在 KoP 可以支援 Pulsar format 與 Kafka format,避免服務端的序列化/反序列化,把工作交給客戶端。客戶端載入一個 formatter 就可以解析 Kafka format 資料,減輕對 broker 的壓力。

關於PPT

請複製連結到瀏覽器下載PPT:https://pan.baidu.com/s/1sqt9...
密碼: 6wtk

相關閱讀

關注公眾號「Apache Pulsar」,獲取更多技術乾貨

加入 Apache Pulsar 中文交流群??
image.png

點選立即觀看 TGIP-CN 37:Apache Pulsar 2.10.0 新特徵解析 回顧視訊!

相關文章