我正在尝试使用Logstash从TCP套接字接收事件,并将其输出到Kafka主题。我当前的配置能够完美地做到这一点,但是我希望能够以事务性方式向Kafka进行事件。我的意思是,在接收到提交消息之前,系统不应将事件发送到kafka:
START TXN 123 --No message sent to Kafka
123 - Event1 Message --No message sent to Kafka
123 - Event2 Message --No message sent to Kafka
123 - Event3 Message --No message sent to Kafka
COMMIT TXN 123 --Event1, Event2, Event3 messages sent to Kafka
是否有可能仅使用logstash实现此目的,还是应该在源和logstash之间引入任何其他事务协调器?这是我当前的配置:
input {
tcp {
port => 9000
}
}
output {
kafka {
bootstrap_servers => "localhost:9092"
topic_id => "alpayk"
}
}
我试图为此目的使用logstash的聚合过滤器,但最终无法正常工作。
非常感谢您
答案 0 :(得分:0)
我最终决定为此目的使用Apache Flume。我修改了它的netcat源,以使未提交的消息驻留在flume的堆中,并且一旦收到用于事务的提交消息,所有消息都将发送到kafka sink。
我将消息存储位置从水槽堆更改为外部缓存,这样,如果事务异常终止或回滚,我将能够使存储的消息过期。
下面是我关于交易逻辑的代码:
String eventMessage = new String(body);
int indexOfTrxIdSeparator = eventMessage.indexOf("-");
if (indexOfTrxIdSeparator != -1) {
String txnId = eventMessage.substring(0, indexOfTrxIdSeparator).trim();
String message = eventMessage.substring(indexOfTrxIdSeparator + 1).trim();
ArrayList<Event> events = cachedEvents.get(txnId);
if (message.equals("COMMIT")) {
System.out.println("@@@@@ COMMIT RECEIVED");
if (events != null) {
for (Event eventItem : events) {
ChannelException ex = null;
try {
source.getChannelProcessor().processEvent(eventItem);
} catch (ChannelException chEx) {
ex = chEx;
}
if (ex == null) {
counterGroup.incrementAndGet("events.processed");
} else {
counterGroup.incrementAndGet("events.failed");
logger.warn("Error processing event. Exception follows.", ex);
}
}
cachedEvents.remove(txnId);
}
} else {
System.out.println("@@@@@ MESSAGE RECEIVED: " + message);
if (events == null) {
events = new ArrayList<Event>();
}
events.add(EventBuilder.withBody(message.getBytes()));
cachedEvents.put(txnId, events);
}
}
我将此代码添加到Flume的netcat源的processEvents
方法中。我不想使用Ruby代码,这就是为什么我决定改用Flume的原因。然而,同样的事情也可以用logstash完成。
谢谢