Шторм в Твиттере, почему bolt не получает то, что отправляет spout

#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. Прошу прощения … Я вас неправильно понял. Да, вероятно, именно это и произошло.