kafka的c/c++高效能用戶端librdkafka簡介

來源:互聯網
上載者:User

標籤:程式   ogg   最小   多次   auto   其他   nas   分區函數   c語言實現   

Librdkafka是c語言實現的apachekafka的高效能用戶端,為生產和使用kafka提供高效可靠的用戶端,並且提供了c++介面

 

效能:

Librdkafka 是一款專為現代硬體使用而設計的高效能庫,它嘗試將記憶體複製保持在最小,可以讓使用者決定是需要高輸送量還是低延遲的服務,效能調優的兩個最重要的配置是:

*batch.num.messages:在發送訊息之前累積在本地隊列中等待的訊息的最小數量。

*queue.buffering.max.ms:等待batch.num.messages多長時間來填寫到本地隊列中。

 

使用:

源碼中的rdkafka.h、CONFIGURATION.md有Librdkafka的API的說明

初始化:

應用程式需要執行個體化一個頂級對象rd_kafka_t作為基礎容器,提供全域配置和共用狀態,調用rd_kafka_new()建立。

還需要執行個體化一個或多個topics(`rd_kafka_topic_t`)來提供生產或消費,topic對象儲存topic特定的配置,並在內部填充所有可用分區和leader brokers,通過調用`rd_kafka_topic_new()`建立。

`rd_kafka_t``rd_kafka_topic_t`內建一個可選的配置API,如果沒有調用API,Librdkafka將會使用CONFIGURATION.md中的預設配置。

 

注意

1.應用程式可能會建立多個`rd_kafka_t`對象,並且它們不共用任何狀態

2.一個`rd_kafka_topic_t`對象僅可以用於建立它的`rd_kafka_t`對象

 

配置

為了簡化與Apache Kafka官方軟體的整合,降低學習曲線,librdkafka實現了與Apache Kafka官方用戶端相同的配置屬性。

使用`rd_kafka_conf_set()` 和`rd_kafka_topic_conf_set()`在建立對象之前應用配置。

注意:

`rd_kafka.._conf_t`對象在傳遞給rd_kafka.._new()`之後不可重複使用,調用`rd_kafka.._new()`後,應用程式不需要free任何配置資源。

 

例子

 

[cpp] view plain copy 
  1. rd_kafka_conf_t*conf;  
  2. char errstr[512];  
  3.      
  4. conf = rd_kafka_conf_new();  
  5. rd_kafka_conf_set(conf, "compression.codec","snappy", errstr, sizeof(errstr));  
  6. rd_kafka_conf_set(conf, "batch.num.messages", "100",errstr, sizeof(errstr));  
  7.      
  8. rd_kafka_new(RD_KAFKA_PRODUCER,conf);  



 

線程和回呼函數

librdkafka內部使用多個線程來充分利用硬體資源.

API是安全執行緒的,應用程式可以在任意時間調用其線程內的任意api函數.

poll-based的API用於嚮應用程式提供訊號,應用程式定期調用` rd_kafka_poll() `,poll API將會調用如下的API:

*訊息傳遞報告回呼函數:訊息傳遞成功或失敗的訊號,允許應用程式釋放訊息中使用的任何應用程式資源。

*錯誤回呼函數:發出錯誤訊號,這些錯誤通常具有資訊性質,例如串連broker失敗,應用程式通常不需要做任何處理,錯誤的類型通過` rd_kafka_resp_err_t `枚舉值傳遞,包括遠端broke錯誤和本地錯誤。

 

可選回調不是通過poll觸發的,可以通過任意線程調用:

*Logging callback :允許應用程式輸出librdkafka產生的日誌訊息

*partitioner callback:應用提供的訊息分區器,可在任意時刻、任意線程中調用,對於相同的鍵,可以調用多次

 

Brokers

Librdkafka需要至少一個brokers的初始化list,稱作` bootstrap brokers `,通過"metadata.broker.list"配置屬性或`rd_kafka_brokers_add()`來指定,用來串連所有bootstrapbrokers,並查詢每個中繼資料的資訊,其中包含brokers、topic、partitions和它們在kafka cluster中的leaders的完整列表,

Brokers的名字被指定為"host[:port]",連接埠可選(預設9092),host是主機名稱或ip地址,如果主機解析到多個地址,librdkafka將輪詢每個嘗試串連的地址,因此,可以使用包含所有brokers地址的DNS記錄來提供可靠的bootstrap broker。

 

Producer API

使用`RD_KAFKA_PRODUCER`設定了`rd_kafka_t`對象,並設定了一個或多個`rd_kafka_topic_t`對象後,librdkafka已經準備好接收要發送給brokers的訊息。

`rd_kafka_produce()`函數有如下參數:

*`rkt` - 需要produce的topic,之前通過`rd_kafka_topic_new()`函數創

*`partition` - 生產到的partition,如果設定為`RD_KAFKA_PARTITION_UA`(UnAssigned),那麼配置的分區函數將會用來選擇目標資料分割。

*`msgflags` - 0,或者是:

         * `RD_KAFKA_MSG_F_COPY` - librdkafka會立刻產生payload的一份拷貝,當payload在非持久化記憶體中(例如堆)時使用。

         * `RD_KAFKA_MSG_F_FREE` - librdkafka使用完payload後,會使用`free(3)`將其釋放。

這兩個指標是互斥的,如果既不需要copy也不需要free,那麼這兩個指標都不需要設定。

 

如果`RD_KAFKA_MSG_F_COPY`沒有設定,將不會執行資料的複製,librdkafka將會hold住payload的指標直到訊息成功傳輸或傳輸失敗。

當librdkafka完成訊息的傳遞,使應用程式重新獲得payload記憶體的所有權後,傳遞報告回呼函數將會被調用

如果設定了`RD_KAFKA_MSG_F_FREE`,傳遞報告回呼函數不能對payload進行free

*`payload`,`len` - 訊息的payload

*`key`,`keylen` - 可以用來進行訊息分區的訊息鍵

         它將被傳遞到topic分區回呼函數(如果存在的話),並在發送給broker的時候附加在訊息上

*`msg_opaque` - 應用程式提供的一個可選的每條訊息的不透明指標,在訊息回呼函數中提供,讓應用程式引用一個特定的指標。

 

`rd_kafka_produce()`是一個非阻塞API,它會在內部隊列中排列訊息並立即返回。如果已排列的訊息個數超過了"queue.buffering.max.messages"配置項,`rd_kafka_produce()`返回-1並將errno設定為`ENOBUFS`,從而提供了一種背壓機制

 

Simple Consumer API

NOTE: 對於進階KafkaConsumer介面,查看rd_kafka_subscribe(rdkafka.h) 或者 KafkaConsumer (rdkafkacpp.h)。

使用`RD_KAFKA_CONSUMER`和`rd_kafka_topic_t`執行個體建立`rd_kafka_t`後,應用程式還必須通過調用`rd_kafka_consume_start()`來為給定的分區啟動consumer。

 

`rd_kafka_consume_start()` 參數:

  * `rkt` - 需要消費的topic,之前通過`rd_kafka_topic_new()`建立。

  *`partition` - 從哪個分區消費

  *`offset` - 開始消費的訊息offset,這可能是絕對訊息位移或兩個特殊位移之一:

         `RD_KAFKA_OFFSET_BEGINNING` :從partition隊列的起始位置開始消費(最老的message)

         `RD_KAFKA_OFFSET_END`:在下一個要生產到該partition上的訊息處開始消費

         `RD_KAFKA_OFFSET_STORED`:使用儲存的offset

 

一個topic+partition的consumer啟動後,librdkafka將會嘗試通過反覆從broker擷取批次訊息以保持本地隊列中儲存"queued.min.messages"條訊息,然後這個本地訊息佇列將會通過三個不同的consume API傳遞給應用程式:

*`rd_kafka_consume()` - consume單條訊息

*`rd_kafka_consume_batch()` - consume單條或多條訊息

*`rd_kafka_consume_callback()` - consume本地隊列中的所有訊息,並給每條訊息調用一個回呼函數

這三個API按照效能升序排列,`rd_kafka_consume()`最慢,`rd_kafka_consume_callback()`最快。

使用`rd_kafka_message_t`類型標識一條已消費的訊息,其成員為:

*`err` - 發回到應用程式的錯誤訊號,如果不為0,那麼`payload`成員將被認為是一條錯誤訊息,`err`是錯誤碼(`rd_kafka_resp_err_t`),如果為0,`payload`則包含訊息資料。

*`rkt`,`partition` - 該訊息的topic和partition

*`payload`,`len` - payload訊息,或者是錯誤資訊(err!=0)

*`key`,`key_len` - 生產者指定的可選訊息key

*`offset` - Message offset

 

`payload`和`key`以及整個訊息的記憶體,屬於librdkafka,調用`rd_kafka_message_destroy()`後不可再次使用,librdkafka將為該訊息集的所有訊息payloads共用相同的訊息集接收緩衝儲存空間,以避免過度複製,這意味著如果應用程式決定hang on單個rd_kafka_message_t,它將阻止從相同訊息集中釋放所有其他訊息的備份記憶體。

 

當應用程式完成從topic+partition的訊息消費後,需要調用`rd_kafka_consume_stop()`來停止這個consumer,這也將清除本地隊列中的當前的訊息。

 

Offset management

broker version >= 0.9.0結合使用高版本的KafkaConsumer介面,可實現基於Broker的offset管理(查看rdkafka.h或 rdkafkacpp.h)

還可以通過本地檔案儲存體來實現Offset管理,通過如下的topic配置參數,offset被永久寫在本地檔案中:

  * `auto.commit.enable`

  * `auto.commit.interval.ms`

  * `offset.store.path`

  * `offset.store.sync.interval.ms`

 

目前還沒有對ZooKeeper的位移量管理的支援。

Consumer groups

當kafka broker 版本>= 0.9 ,librdkafka支援基於broker的consumer groups

 

Topics

Librdkafka支援自動建立topic,broker需要配置"auto.create.topics.enable=true"

kafka的c/c++高效能用戶端librdkafka簡介

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.