如何使用Java在一个周期内从Kafka读取多个记录

时间:2017-08-30 11:47:25

标签: java apache-kafka kafka-consumer-api

我必须创建一个Kafka topics的消费者,他不断倾听并将数据推送到Database

这里的要求是: - 如果您碰巧在一个周期内从Kafka读取多个记录,请尝试将其作为单个调用推送到db而不是多个。

public static void kafkaConsumer(String topicName, String groupId, String autoOffsetReset,
        String enableAutoCommit, String kafkaServers, String acks, String retries, String lingerMS,
        String bufferMemory) throws Exception {

    ObjectMapper mapper = new ObjectMapper();

    KafkaConsumer<String, String> consumer = new KafkaConsumer<>(
            getKafkaParams(groupId, kafkaServers, autoOffsetReset, enableAutoCommit));

    consumer.subscribe(Arrays.asList(topicName));
    logger.info("subscibed to the topic {}", topicName);
    cluster = Cluster.builder().addContactPoints(CASSANDRA_IPS.split(",")).build();
    session = cluster.connect(KEYSPACE);

    try {

        while (true) {
            try {
                ConsumerRecords<String, String> records = consumer.poll(1000);
                for (ConsumerRecord<String, String> record : records) {

                    Model model= mapper.readValue(record.value(), Model.class);

                try {
                        boolean flag = insertIntoDB(session, model);
                        if (flag) {
                            logger.info("************ Data Persisted Successfully ***************");
                        } else {
                            logger.info("******* Data Persition Failed *************");
                        }
                    } catch (Exception ex) {
                        logger.error("Exception while persisting data into DB", ex);
                    }
                }
            } catch (Exception ex) {
                logger.error("Exception while reading data from kafka", ex);
            }
        }
    } finally {
        consumer.close();
    }
}

1 个答案:

答案 0 :(得分:1)

Mysql INSERT支持插入多行一次。像这样:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

因此,您可以先将记录保存到数组中,当数组大小等于BATCH_SIZE时,您可以将其传递给insertIntoDb方法。然后清除数组,继续循环。

您还可以将一个投票中的所有消息都带入数组,并将其传递给insertIntoDb。

但是如果消息计数太大,Mysql会抱怨数据包太大,所以在这种情况下使用指定的BATCH_SIZE会更好。

此外,您可以为消费者指定“max.poll.records”配置,以限制一次轮询中的消息计数。

Cassandra中有类似的事情:

PreparedStatement ps = session.prepare("INSERT INTO messages (user_id,msg_id, title, body) VALUES (?, ?, ?, ?)");
BatchStatement batch = new BatchStatement();
batch.add(ps.bind(uid, mid1, title1, body1));
batch.add(ps.bind(uid, mid2, title2, body2));
batch.add(ps.bind(uid, mid3, title3, body3));
session.execute(batch);