Въведение в Apache Beam

1. Общ преглед

В този урок ще представим Apache Beam и ще разгледаме основните му концепции.

Ще започнем с демонстриране на случая на употреба и предимствата от използването на Apache Beam, а след това ще разгледаме основни концепции и терминологии. След това ще разгледаме един прост пример, който илюстрира всички важни аспекти на Apache Beam.

2. Какво представлява Apache Beam?

Apache Beam (Batch + strEAM) е унифициран програмен модел за пакетни и поточни задачи за обработка на данни. Той предоставя комплект за разработка на софтуер за дефиниране и изграждане на тръбопроводи за обработка на данни, както и бегачи за тяхното изпълнение.

Apache Beam е проектиран да осигури преносим слой за програмиране. Всъщност, Beam Pipeline Runners превеждат конвейера за обработка на данни в API, съвместим с бекенда по избор на потребителя. Понастоящем се поддържат тези разпределени бекендове за обработка:

  • Apache Apex
  • Apache Flink
  • Зъбна помпа Apache (инкубационна)
  • Apache Samza
  • Apache Spark
  • Google Cloud Dataflow
  • Hazelcast Jet

3. Защо Apache Beam?

Apache Beam обединява пакетна и поточна обработка на данни, докато други често го правят чрез отделни API. Следователно е много лесно да промените процеса на поточно предаване на партиден процес и обратно, да речем, когато изискванията се променят.

Apache Beam повишава преносимостта и гъвкавостта. Ние се фокусираме върху нашата логика, а не върху основните подробности. Освен това можем да променим бекенда за обработка на данни по всяко време.

За Apache Beam са налични Java, Python, Go и Scala SDK. Всъщност всеки от екипа може да го използва със своя език по избор.

4. Основни понятия

С Apache Beam можем да изграждаме графики на работния поток (конвейери) и да ги изпълняваме. Основните понятия в програмния модел са:

  • PCollection - представлява набор от данни, който може да бъде фиксирана партида или поток от данни
  • PTransform - операция за обработка на данни, която отнема едно или повече PCollection s и извежда нула или повече PCollection s
  • Pipeline - представлява насочена ациклична графика на PCollection и PTransform и следователно капсулира цялата задача за обработка на данни
  • PipelineRunner - изпълнява Pipeline на определен разпределен бекенд за обработка

Просто казано, PipelineRunner изпълнява Pipeline, а Pipeline се състои от PCollection и PTransform .

5. Пример за преброяване на думи

Сега, след като научихме основните концепции на Apache Beam, нека проектираме и тестваме задача за преброяване на думи.

5.1. Изграждане на тръбопровод за лъч

Проектирането на графика на работния поток е първата стъпка във всяка задача на Apache Beam. Нека дефинираме стъпките на задача за преброяване на думи:

  1. Прочетете текста от източник.
  2. Разделете текста на списък с думи.
  3. Всички малки думи с малки букви.
  4. Подрязване на пунктуацията.
  5. Филтрирайте стоп думи.
  6. Пребройте всяка уникална дума.

За да постигнем това, ще трябва да преобразуваме горните стъпки в един тръбопровод с помощта на абстракции PCollection и PTransform .

5.2. Зависимости

Преди да можем да приложим нашата графика на работния поток, трябва да добавим основната зависимост на Apache Beam към нашия проект:

 org.apache.beam beam-sdks-java-core ${beam.version} 

Beam Pipeline Runners разчитат на разпределена обработваща среда за изпълнение на задачи. Нека добавим DirectRunner като зависимост от изпълнението:

 org.apache.beam beam-runners-direct-java ${beam.version} runtime 

За разлика от други Pipeline Runners, DirectRunner не се нуждае от допълнителна настройка, което го прави добър избор за начинаещи.

5.3. Изпълнение

Apache Beam utilizes the Map-Reduce programming paradigm (same as Java Streams). In fact, it's a good idea to have a basic concept of reduce(), filter(), count(), map(), and flatMap() before we continue.

Creating a Pipeline is the first thing we do:

PipelineOptions options = PipelineOptionsFactory.create(); Pipeline p = Pipeline.create(options);

Now we apply our six-step word count task:

PCollection
    
      wordCount = p .apply("(1) Read all lines", TextIO.read().from(inputFilePath)) .apply("(2) Flatmap to a list of words", FlatMapElements.into(TypeDescriptors.strings()) .via(line -> Arrays.asList(line.split("\\s")))) .apply("(3) Lowercase all", MapElements.into(TypeDescriptors.strings()) .via(word -> word.toLowerCase())) .apply("(4) Trim punctuations", MapElements.into(TypeDescriptors.strings()) .via(word -> trim(word))) .apply("(5) Filter stopwords", Filter.by(word -> !isStopWord(word))) .apply("(6) Count words", Count.perElement());
    

The first (optional) argument of apply() is a String that is only for better readability of the code. Here is what each apply() does in the above code:

  1. First, we read an input text file line by line using TextIO.
  2. Splitting each line by whitespaces, we flat-map it to a list of words.
  3. Word count is case-insensitive, so we lowercase all words.
  4. Earlier, we split lines by whitespace, ending up with words like “word!” and “word?”, so we remove punctuations.
  5. Stopwords such as “is” and “by” are frequent in almost every English text, so we remove them.
  6. Finally, we count unique words using the built-in function Count.perElement().

As mentioned earlier, pipelines are processed on a distributed backend. It's not possible to iterate over a PCollection in-memory since it's distributed across multiple backends. Instead, we write the results to an external database or file.

First, we convert our PCollection to String. Then, we use TextIO to write the output:

wordCount.apply(MapElements.into(TypeDescriptors.strings()) .via(count -> count.getKey() + " --> " + count.getValue())) .apply(TextIO.write().to(outputFilePath));

Now that our Pipeline definition is complete, we can run and test it.

5.4. Running and Testing

So far, we've defined a Pipeline for the word count task. At this point, let's run the Pipeline:

p.run().waitUntilFinish();

On this line of code, Apache Beam will send our task to multiple DirectRunner instances. Consequently, several output files will be generated at the end. They'll contain things like:

... apache --> 3 beam --> 5 rocks --> 2 ...

Defining and running a distributed job in Apache Beam is as simple and expressive as this. For comparison, word count implementation is also available on Apache Spark, Apache Flink, and Hazelcast Jet.

6. Where Do We Go From Here?

Успешно преброихме всяка дума от нашия входен файл, но все още нямаме отчет за най-честите думи. Разбира се, сортирането на PCollection е добър проблем за решаване като следващата ни стъпка.

По-късно можем да научим повече за прозорци, задействания, показатели и по-сложни трансформации. Документацията на Apache Beam предоставя задълбочена информация и справочен материал.

7. Заключение

В този урок научихме какво е Apache Beam и защо е предпочитан пред алтернативи. Също така демонстрирахме основни концепции на Apache Beam с пример за преброяване на думи.

Кодът за този урок е достъпен в GitHub.