Методы hashCode() и equals() для пользовательских классов в flink

#apache-flink #flink-streaming #flink-cep #flink-statefun

#apache-flink #flink-потоковая передача #flink-cep #flink-statefun

Вопрос:

я сомневаюсь в том, нужно ли переопределять пользовательские классы в Flink с Java или нет, hashCode() и equals() методы, потому что я прочитал на этой странице, которые hashCode() никогда НЕ ДОЛЖНЫ быть реализованы в распределенных системах, и Apache Flink является одним из них.

Пример: у меня есть этот класс:

 public class EventCounter {
    public String Id;
    public long count;
    public Timestamp firstEvent;
    public Timestamp lastEvent;
    public Date date;

    public EventCounter() {
    }
}
  

Нужно ли мне реализовывать hashCode() и equals() для такого рода классов в Flink или для повышения производительности будет лучше, если я позволю Flink управлять этими методами самостоятельно?

С уважением!

Ответ №1:

Типы, которые вы хотите использовать в качестве ключей в Flink (т. Е. Как значения, которые вы возвращаете из keySelector), должны иметь допустимые реализации hashCode и equals. В частности, hashCode должен быть детерминированным для всех JVM (вот почему массивы и перечисления не работают как ключи в Flink).

Комментарии:

1. Давайте предположим, что этот сценарий для того же класса выше: DataStream<EventCounter> stream = env.addSource(...); KeyedStream<EventCounter, String> keyed = stream.keyby(k->k.id); keyed.flatMap(new customRichFlatMapClass()) or keyed.window(TumblingEventTimeWindows).process(new ProcessFunctionClass()); эти классы customRichFlatMapClass или ProcessFunctionClass работают с состояниями, и у меня есть final TypeInformation<EventCounter> info = Types.POJO(EventCounter.class); возможность сериализовать объект в состояние. Нужны ли мне hashCode() и equals() в EventCounter ? Спасибо

2. Нет, вы этого не делаете. Единственный случай, когда вам нужно подумать об этом, — это если вы хотите сделать stream.keyBy(k -> k) .

3. Большое спасибо @David, я понял это после долгого изучения информации об этом, но я хотел быть уверенным, что именно так это и работает, потому что в противном случае у меня возникает дополнительная загрузка процессора без необходимости создания этих хэшей. Еще раз большое спасибо.

4. Я согласен с ответом Дэвида. Но, тем не менее, в Java всегда предпочтительнее переопределять метод hashcode / equals для любого бизнес-POJO, что является хорошей практикой. Reg I'm having an extra CPU utilization without been needed to create those hashes — Я думаю, что они будут использоваться только тогда, когда вы (или внутренний код) вызываете эти методы. И вы можете ожидать желаемого результата только при переопределении этих методов во время их вызова.

Ответ №2:

Прежде чем писать два метода, просто подумайте, каким должен быть ваш класс, symmetric или transitive или consistent ?

Он специально разработан для алгоритмов, основанных на хэшировании. Поэтому вам нужно убедиться, что они работают должным образом, и примечание: создание хэш-кода — это задача с интенсивным использованием процессора.

Ответ №3:

hasCode() и equals() методы должны быть реализованы только в тех случаях, когда объект / класс будет использоваться в качестве ключей в Flink, например:

 DataStream<EventCounter> stream = env.addSource(...);
KeyedStream<EventCounter, String> keyed = stream.keyby(k->k); /*Where k is the class object type!*/