我是Storm编程的新手,我有一份工作要对自定义分组方法进行测试,看看它是否更好。
所以我必须在几种不同的条件下测量风暴的吞吐量,例如不同的工人数量,不同的工人记忆......等等
使用conf.setNumWorkers();
设置工作人员编号很容易,但我发现很难设置每个工作人员的最大堆大小。
我尝试编辑storm.yaml
并添加了
worker.childopts: "-Xmn128m-Xms128m-Xmx128m"
带
conf.put(Config.WORKER_CHILDOPTS, "-Xmn128m -Xms128m -Xmx128m");
添加到我的代码中。
但是当我在我的工作节点上使用jmap -heap [pid]
时,我发现最大堆大小仍然是768m,这是默认的最大堆大小。
如何实现此目的以限制JVM的最大内存使用?
顺便说一句,我正在使用kafkaspout向暴风雨发送消息,欢迎对我的测试工作提出任何建议。
答案 0 :(得分:2)
尝试编辑storm / default.yaml文件。查找工作器设置,您将在那里找到设置堆内存的条目。它默认应该是这样的!
worker.heap.memory.mb: 768
在同一个文件中,您还可以找到以下设置,您可以根据需要更改值。
topology.component.resources.onheap.memory.mb: 128.0
topology.component.resources.offheap.memory.mb: 0.0
topology.component.cpu.pcore.percent: 10.0
topology.worker.max.heap.size.mb: 768.0
希望有所帮助!
答案 1 :(得分:2)
如果你的Storm版本是<1.0.0,你必须在storm.yaml中设置worker.childopts,然后重新启动你的主管。此参数不会作为拓扑特定选项from what I've gleaned引入,因此您所做的拓扑配置更改不会影响结果。
对于Storm版本&gt; = 1.0.0,您可以参考ssadaqat's answer,但不是编辑defaults.yaml(这是源代码的一部分),您再次需要将此值插入到storm中。 YAML。
答案 2 :(得分:2)
虽然ssadaquat的答案是正确的,并且您可以在风暴的yaml文件中设置工作程序内存,但我已经能够以编程方式成功地执行此操作:
Config stormConfig = new Config();
int fourGB = 4 * 1024;
stormConfig.put(Config.TOPOLOGY_WORKER_MAX_HEAP_SIZE_MB, fourGB);
如果您不想更改多台服务器中的yaml文件,或者您根本不想更改yaml文件,那么这样做会特别有用。
有很多答案说你必须设置childopts
以增加记忆力,但这对我没有用。事实上,我注意到在设置topology_worker_max_heap_size_mb
后,childopts
值会自动增加。还要尽量确保服务器上有enough of swap memory,尤其是在处理大量数据时。
答案 3 :(得分:1)
您可以通过以下步骤更改工作人员的最大堆大小:
1:添加&#34; worker.heap.memory.mb:2048&#34;进入nimbus节点的conf / storm.yaml文件;
2:重启nimbus和主管
工人&#39;堆大小将更改为2GB
答案 4 :(得分:0)
我无法找出设置JVM最大堆大小的正确方法,但我使用了另一种方法作为解决方法。
注意:我目前没有手头的源代码,所以下面的代码只是为了演示这个想法并完全未经测试。
该方法是利用Storm中重新传输失败元组的机制。
如果您正在使用某种类型的现有鲸鱼喷水,例如KafkaSpout
或其他任何事情,那么您不必担心重新传输失败的元组,默认情况下它都会被处理掉实现。
但是,如果您要实施自己的鲸鱼喷水,则必须自行完成。我相信,如果您尝试实施鲸鱼喷水,那么您必须知道void ack(Object msgId)
和void fail(Object msgId)
等等,并且很容易实现重新传输机制。
我们的WorkerBolt看起来像这样,假设它是一个字数螺栓。
class WorkerBolt implements IRichBolt{
...
private HashMap<String, int> counts = new HashMap<>();
private int wordStoredCount = 0;
private final int COUNT_LIMIT = 500000; // Here's our limit
...
void execute(Tuple tuple){
if(wordStoreCount >= COUNT_LIMIT){
tuple.fail();
}
// do our counting stuff
wordStoredCount++;
// send the tuple downstream to aggregate/process/etc. if needed
}
...
它不是很准确,因为每个单词可能有不同的长度或大小,您可以使用MEMORY_COUNT
memoryStoredCount
并将每个单词的内存使用加到{{1}更准确。
采用这种方法可以使系统更具可控性,因为如果我们设置最大堆大小并且JVM达到约束,它将简单地抛出OutOfMemoryException并关闭系统,这可能不是我们想要的。