在使用KafkaSpout和几个Bolts开发和执行我的Storm(1.0.1)拓扑之后,我注意到即使拓扑处于空闲状态时网络流量也很大(Kafka上没有消息,没有在螺栓中进行处理)。所以我开始逐个评论我的拓扑结构以找到原因,现在我的主要部分只有KafkaSpout:
....
final SpoutConfig spoutConfig = new SpoutConfig(
new ZkHosts(zkHosts, "/brokers"),
"files-topic", // topic
"/kafka", // ZK chroot
"consumer-group-name");
spoutConfig.scheme = new SchemeAsMultiScheme(new StringScheme());
spoutConfig.startOffsetTime = OffsetRequest.LatestTime();
topologyBuilder.setSpout(
"kafka-spout-id,
new KafkaSpout(config),
1);
....
当这个(无用的)拓扑执行时,即使在本地模式下,即使是第一次,网络流量总是会增长很多:我看到(在我的活动监视器中)
(重要:Kafka没有在集群中运行,一个单个实例在同一台机器上运行,只有一个主题和一个分区。我刚刚在我的机器上下载了Kafka,启动它并创建了一个简单的主题。当我把它放入主题中的消息,拓扑中的所有内容都没有任何问题。
显然,原因在于KafkaSpout.nextTuple()
方法(下方),但我不明白为什么,在Kafka没有任何消息的情况下,我应该有这样的流量。有没有我没有考虑过的事情?这是预期的行为吗?我看看Kafka日志,ZK日志,什么都没有,我已经清理了Kafka和ZK数据,没有,仍然是相同的行为。
@Override
public void nextTuple() {
List<PartitionManager> managers = _coordinator.getMyManagedPartitions();
for (int i = 0; i < managers.size(); i++) {
try {
// in case the number of managers decreased
_currPartitionIndex = _currPartitionIndex % managers.size();
EmitState state = managers.get(_currPartitionIndex).next(_collector);
if (state != EmitState.EMITTED_MORE_LEFT) {
_currPartitionIndex = (_currPartitionIndex + 1) % managers.size();
}
if (state != EmitState.NO_EMITTED) {
break;
}
} catch (FailedFetchException e) {
LOG.warn("Fetch failed", e);
_coordinator.refresh();
}
}
long diffWithNow = System.currentTimeMillis() - _lastUpdateMs;
/*
As far as the System.currentTimeMillis() is dependent on System clock,
additional check on negative value of diffWithNow in case of external changes.
*/
if (diffWithNow > _spoutConfig.stateUpdateIntervalMs || diffWithNow < 0) {
commit();
}
}
答案 0 :(得分:1)
在nextTuple()方法中休眠一秒钟(1000毫秒)并立即观察流量,例如,
@Override
public void nextTuple() {
try {
Thread.sleep(1000);
} catch(Exception ex){
log.error("Ëxception while sleeping...",e);
}
List<PartitionManager> managers = _coordinator.getMyManagedPartitions();
for (int i = 0; i < managers.size(); i++) {
...
...
...
...
}
原因是,kafka消费者在pull methodology的基础上工作,这意味着消费者将从kafka经纪人处获取数据。因此,从消费者的角度来看(Kafka Spout)将持续向kafka经纪人发送一个TCP network request的获取请求。因此,您将面对发送/接收的数据包的大量统计信息。 Though the consumer doesn't consumes any message, pull request and empty response also will get account into network data packet sent/received statistics.
如果您的睡眠时间很长,您的网络流量将会减少。经纪人和消费者也有一些network related configurations。进行配置研究可能对您有所帮助。希望它会对你有所帮助。
答案 1 :(得分:0)
您的螺栓是否正在接收消息?你的螺栓是否继承了BaseRichBolt?
在Kafaspout中注释掉行m.fail(id.offset)并检查出来。如果您的螺栓没有确认,那么您的喷口会假定该消息失败并尝试重播相同的消息。
QStandardItemModel *model = new QStandardItemModel(0, 5, this); //reimplemented class
QItemDelegate *mydelegate = new QItemDelegate(this); //reimplemented class
QSortFilterProxyModel * m_proxyModel = new QSortFilterProxyModel();
m_proxyModel -> setSourceModel(model);
ui -> tableView -> setModel( m_proxyModel);
ui -> tableView -> setItemDelegate (mydelegate);
ui -> tableView -> sortByColumn(0, Qt::AscendingOrder);
ui -> tableView -> setSortingEnabled(true);
for(size_t i=0; i<m_BoardingsVector.size(); i++) //a structure from a function that adds rows dynamically
{
model -> insertRows(model -> rowCount(),1);
for(int j=0; j<5; ++j)
ui -> tableView -> openPersistentEditor(model -> index(model -> rowCount() - 1, j));
}
同时尝试暂停nextTuple()几毫秒并检查它。
如果有帮助请告诉我