我必须创建一个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();
}
}
答案 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);