標籤:程式 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
- rd_kafka_conf_t*conf;
- char errstr[512];
-
- conf = rd_kafka_conf_new();
- rd_kafka_conf_set(conf, "compression.codec","snappy", errstr, sizeof(errstr));
- rd_kafka_conf_set(conf, "batch.num.messages", "100",errstr, sizeof(errstr));
-
- 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簡介