librdkafka poll等问题

1. librdkafka中producer的poll是干什么用的?

由于producer是异步调用,消息是否发送成功,是通过回调而得知结果。poll就是调用回调函数用的,回调函数就是 dr_cb 函数。
poll函数的参数:
0:非阻塞调用,立马返回;
n: 阻塞n 毫秒,期间成功发送的消息会调到dr_cb函数;
-1:一直阻塞等到消息为止。(例如linger.ms=5秒,batch.num.messages=1000,那么要么producer后达到5秒时间,要么producer生成了1000条数据,否则poll会一直阻塞)

2. 不调用poll会有什么后果?

导致事件队列满,生产者写数据失败,事件队列满后报错如下:

Produce failed: Local: Queue full

3. linger.ms 、batch.num.messages干什么用?

linger.ms = queue.buffering.max.ms
两者都是一个等待时间,等待什么呢?调用producer后,数据不会立马等上前往broker的列车,而是先等待,到达一定时间发车,或者达到一定消息数量发车。就像街上的黑车,他不会一直等着,但人少也不发车。
linger.ms就是他的等待时间;
batch.num.messages就是等待人数。
kafka比黑车控制的更精确,它还能根据体重发车(batch.size等参数)。

4. 打印librdkafka的默认配置参数

打印全局配置和topic配置

RdKafka::Conf *conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL);
int pass;
for (pass = 0 ; pass < 2 ; pass++) 
{
    std::list<std::string> *dump;
    if (pass == 0) {
        dump = conf->dump();
        std::cout << "# Global config" << std::endl;
    } else {
        dump = tconf->dump();
        std::cout << "# Topic config" << std::endl;
    }

    for (std::list<std::string>::iterator it = dump->begin();it != dump->end(); ) 
    {
        std::cout << *it << " = ";
        it++;
        std::cout << *it << std::endl;
        it++;
    }
    std::cout << std::endl;
}

5.一次librakafak写kafka效率问题排查历程

5.1 发现程序循环调用produce 1000次,获取发送条数后,每条调用一次poll,每次调用阻塞1毫秒,导致每发送成功1000数据阻塞1秒。
5.2发现此问题后改为每发送1000条数据后调用一次poll,但又有了新问题。poll调用次数太少,阻塞时间太短,导致报错 Produce failed: Local: Queue full
5.3 查询Queue full的解决办法,github的issues列表中有一条同样的问题: librdkafka issues。根据作者的建议,加统计回调stats_cb(这个回调函数其实就包含在event_cb中,根据事件类型区分,害我找半天),加参数 statistics.interval.ms ,否则默认统计信息是关闭的。
5.4 打印statistic信息后,可以比较清楚看到待发送队列中数据的bytes,条数等信息。根据打印信息,调节poll为10ms, 调大queue.buffering.max.kbytes 为2048000后,错误消失。
5.5 Local Queue full 错误再现 ,poll调整为50ms, linger.ms调整为100ms, queue.buffering.max.messages 调整为100万, 并在消息投递错误时重试两次。目前未见错误。
参数设置如下:

queue.buffering.max.ms = 100
queue.buffering.max.messages = 1000000
queue.buffering.max.kbytes = 2000000

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
使用librdkafka库可以轻松地开发Kafka客户端应用程序。以下是使用librdkafka库的一些基本步骤: 1. 安装librdkafka库:您可以通过下载和编译源代码或使用操作系统的软件包管理器来安装librdkafka库。 2. 创建Kafka生产者/消费者配置:您需要设置Kafka集群的连接配置和其他参数,例如主题名称、分区、消息序列化器等。 3. 创建Kafka生产者/消费者:使用librdkafka库提供的API创建Kafka生产者/消费者对象。 4. 发送/接收消息:使用Kafka生产者/消费者对象发送/接收消息。您可以使用同步或异步API发送/接收消息。 5. 处理错误:处理可能发生的错误,例如连接错误、发送错误、接收错误等。 以下是使用librdkafka库创建Kafka生产者/消费者的示例代码: ```c #include <stdio.h> #include <string.h> #include <librdkafka/rdkafka.h> int main(int argc, char **argv) { rd_kafka_t *rk; /* Producer instance handle */ rd_kafka_conf_t *conf; /* Temporary configuration object */ char errstr[512]; /* librdkafka API error reporting buffer */ /* Kafka broker configuration */ char *brokers = "localhost:9092"; char *topic = "test_topic"; /* Create Kafka configuration object */ conf = rd_kafka_conf_new(); /* Set bootstrap broker(s) */ if (rd_kafka_conf_set(conf, "bootstrap.servers", brokers, errstr, sizeof(errstr)) != RD_KAFKA_CONF_OK) { fprintf(stderr, "Failed to set broker: %s\n", errstr); rd_kafka_conf_destroy(conf); return 1; } /* Create producer instance */ rk = rd_kafka_new(RD_KAFKA_PRODUCER, conf, errstr, sizeof(errstr)); if (!rk) { fprintf(stderr, "Failed to create producer: %s\n", errstr); rd_kafka_conf_destroy(conf); return 1; } /* Create message object */ rd_kafka_topic_t *rkt; rkt = rd_kafka_topic_new(rk, topic, NULL); /* Produce message */ const char *message = "Hello, Kafka!"; size_t len = strlen(message); rd_kafka_resp_err_t err; err = rd_kafka_produce(rkt, RD_PARTITION_UA, RD_MSG_F_COPY, (void *)message, len, NULL, 0, NULL); if (err != RD_KAFKA_RESP_ERR_NO_ERROR) { fprintf(stderr, "Failed to produce message: %s\n", rd_kafka_err2str(err)); } /* Wait for message delivery */ rd_kafka_poll(rk, 0); /* Destroy message object */ rd_kafka_topic_destroy(rkt); /* Destroy producer instance */ rd_kafka_destroy(rk); return 0; } ``` 这是一个简单的Kafka生产者示例代码,它将消息“Hello, Kafka!&rdquo;发送到Kafka集群。您可以使用类似的方式创建Kafka消费者。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值