#java #apache-storm
#java #apache-storm
Вопрос:
Я использую Twitter Storm в проекте, и у меня странная проблема. У меня есть носик со следующим кодом nextTuple:
public void nextTuple()
{
HashMap cluster = this.databaseManager.getCluster();
System.out.println("emitted: " cluster);
this.collector.emit(new Values(cluster));
}
И болт, который подключен к этому носику со следующим выполнением:
public void execute(Tuple tuple)
{
HashMap<String, List<String>> unigrams = (HashMap)tuple.getValueByField("unigrams");
System.out.println("received: " unigrams);
}
То, что передается, должно совпадать с тем, что получено правильно?
Итак, сначала вывод показывает это:
emitted: {218460=[04ef110987074dc6b3e3174b9f57d980], 1702472=[04ef110987074dc6b3e3174b9f57d980]}
received: {218460=[04ef110987074dc6b3e3174b9f57d980], 1702472=[04ef110987074dc6b3e3174b9f57d980]}
(Непочтительно, что означают данные, дело в том, что они передаются и принимаются).
Но затем, когда излучаемое изменяется, полученное остается тем же:
emitted: {13788873=[aa2ec732b5b64b25be81abe79d2176bb], 2293158=[aa2ec732b5b64b25be81abe79d2176bb], 218460=[04ef110987074dc6b3e3174b9f57d980], 1702472=[04ef110987074dc6b3e3174b9f57d980]}
received: {218460=[04ef110987074dc6b3e3174b9f57d980], 1702472=[04ef110987074dc6b3e3174b9f57d980]}
Я пытаюсь понять, почему это не работает во втором случае.
Кроме того, вывод печатает намного больше из nextTuple, чем из execute.
Есть идеи, почему это так?
Ответ №1:
Единственное решение, которое я нашел, состояло в том, чтобы преобразовать HashMap в строку перед отправкой, а затем преобразовать обратно в HashMap в bolt.
Комментарии:
1. Как вы добавили значения в свою карту? Проблема в основном в этом. В одной и той же JVM bolts и spouts сохраняют один и тот же экземпляр Java (я думаю, что для оптимизации нет сериализации kryo), остерегайтесь проблем параллелизма при записи / чтении из кортежей (особенно не параллельной хэш-карты)! Ваше исправление — это, по сути, глубокая копия значения кортежа для подавления любой проблемы параллелизма (здесь нет ссылки на память).
2. Хэш-карта была локальной для bolt. Таким образом, проблем с параллелизмом нет.
3. Нет, вы ошибаетесь: если вы получаете hashmap из кортежа, это означает, что он был передан из другого элемента (bolt / spout), перед которым он его создает / изменяет: он «общий» в той же JVM.
4. Прошу прощения … Я вас неправильно понял. Да, вероятно, именно это и произошло.