【发布时间】:2019-05-18 18:47:15
【问题描述】:
我正在使用 confluent REST API 代理调用 Kafka。我正在读取一个 CSV 文件,从那里的所有记录(大约 400 万条记录)中创建一个对象并向 REST 代理发送请求。我不断收到OutOfMemory 异常。
确切的异常消息是:
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "kafka-producer-network-thread | producer-81"
我只有一个 REST 代理服务器实例,作为 docker 容器托管。环境变量设置为:
JAVA_OPTIONS=-Xmx1g
其他配置:
CPU - 1
Memory - 1024
它在崩溃之前处理了大约 1,00,000 个。 我尝试将其扩展到 4 个实例,并将 CPU 增加到 3,内存也增加到 2046 mb。然后它会处理大约 5,00,000 条记录。
读取 csv 后,我以 5k 条记录的批次调用 Kafka 端点。那是用Node写的。这是节点代码
fs.createReadStream(inputFile)
.pipe(parser({skip_lines_with_error: true}))
.on('data', (records) => {
country.push({ 'value' : {
country: records[0],
capital: records[1]
}
});
if (country.length > 5000) {
batch++;
callKafkaProxy(country).then((rec) => {
console.log(`'Batch done!'`);
}).catch((reason) => {
console.log(reason);
});
country = [];
}
})
.on('end', () => {
console.log('All done!');
});
function callKafkaProxy(records) {
const urlAndRequestOptions = {
url: 'http://kafka-rest-proxy.com/topics/test-topic',
headers: {
'content-type' : 'application/vnd.kafka.json.v2+json',
'Accept' : 'application/vnd.kafka.v2+json'
}
};
let recordsObject = {records: records};
//request here is a wrapper on the http package.
return request.post(urlAndRequestOptions, recordsObject);
我觉得我错过了一些配置,这些配置应该有助于解决这个问题而不增加实例数 > 1。
任何帮助将不胜感激。
【问题讨论】:
-
你能给出你的代码的sn-p你是如何批量记录到Kafka的吗?您似乎没有使用节点流或以错误的异步方式进行操作。
-
刚刚添加@ŽilvinasJocius,您可以查看。
-
Kafka REST 客户端真的适合你的需求吗?如果客户端没有像 http 那样的额外层但直接使用 tcp/ip 进行通信呢?如果您能找到支持流的客户端,您的任务将执行得更快而不会出现此类问题。
-
其余客户端现在在生产中的很多地方都在使用。但是,目前,它产生的消息要低几个数量级。直接生产到 kafka 是可能的,但不方便并且禁止代码重用(因为它已经用于其他应用程序)。
-
你明白我在下面的回答中试图解释的问题吗?
标签: node.js apache-kafka kafka-producer-api kafka-rest