Elastyczne generowanie danych dzięki Datafaker Gen

Wprowadzenie do Datafaker

Datafaker to nowoczesny framework, który umożliwia JVM Programiści mogą efektywnie generować fałszywe dane dla swoich projektów, korzystając z ponad 200 dostawców danych umożliwiających szybką konfigurację i użytkowanie. Niestandardowi dostawcy mogą zostać napisani, gdy potrzebne są dane specyficzne dla domeny. Oprócz dostawców, wygenerowane dane mogą być eksportowane do popularnych formatów, takich jak CSV, JSON, SQL, XML i YAML.

Aby uzyskać dobre wprowadzenie do podstawowych funkcji, proszę zobaczyć “Datafaker: Alternatywa dla korzystania z danych produkcyjnych.

Datafaker oferuje wiele funkcji, takich jak praca z sekwencjami i kolekcjami oraz generowanie niestandardowych obiektów na podstawie schematów (patrz “Datafaker 2.0).

Generowanie danych masowych

Podczas tworzenia i testowania oprogramowania pojawia się potrzeba częstego generowania danych do różnych celów, niezależnie od tego, czy chodzi o przeprowadzanie testów niefunkcjonalnych, czy też symulowanie obciążeń typu burst. Rozważmy prosty scenariusz, w którym mamy za zadanie wygenerować 10 000 wiadomości w ciągu jednego dnia. JSON format do wysłania do RabbitMQ.

Z mojej perspektywy te opcje są warte rozważenia:

  1. Opracowanie własnego narzędzia: Jedną z opcji jest napisanie od podstaw niestandardowej aplikacji do generowania tych rekordów (wiadomości). Jeśli wygenerowane dane mają być bardziej realistyczne, warto skorzystać z aplikacji Datafaker lub JavaFaker.
  2. Korzystanie z określonych narzędzi: Alternatywnie, możemy wybrać określone narzędzia zaprojektowane dla konkretnych baz danych lub brokerów wiadomości. Na przykład narzędzia takie jak voluble dla Kafka zapewniają wyspecjalizowane funkcje generowania i publikowania wiadomości w tematach Kafki; lub bardziej nowoczesne narzędzie, takie jak ShadowTraffic, który jest obecnie w fazie rozwoju i jest ukierunkowany na podejście oparte na kontenerach, co nie zawsze musi być konieczne.
  3. Datafaker Gen: Wreszcie, mamy możliwość skorzystania z Datafaker Gen, który chcę rozważyć w bieżącym artykule.

Przegląd Datafaker Gen

Datafaker Gen oferuje generator wiersza poleceń oparty na bibliotece Datafaker, który umożliwia ciągłe generowanie danych w różnych formatach i integrację z różnymi systemami pamięci masowej, brokerami wiadomości i usługami zaplecza. Ponieważ narzędzie to wykorzystuje Datafaker, może istnieć możliwość, że dane są realistyczne. Konfigurację schematu, typu formatu i zlewu można przeprowadzić bez przebudowywania projektu.

Datafake Gen składa się z następujących głównych komponentów, które można skonfigurować:

1. Definicja schematu

Użytkownicy mogą zdefiniować schemat dla swoich rekordów w sekcji config.yaml . Schemat określa definicje pól rekordu w oparciu o plik Dostawca Datafaker. Umożliwia on również definiowanie pól wbudowanych.

default_locale: en-EN
fields:
  - name: lastname
    generators: [ Name#lastName ]
  - name: firstname
    generators: [ Name#firstName ]

2. Format

Datafake Gen umożliwia użytkownikom określenie formatu, w jakim będą generowane rekordy. Obecnie dostępne są podstawowe implementacje formatów CSV, JSON, SQL, XML i YAML. Dodatkowo formaty można rozszerzyć o niestandardowe implementacje. Konfiguracja formatów jest określona w sekcji output.yaml file.

formats:
  csv:
    quote: "@"
    separator: $$$$$$$
  json:
    formattedAs: "[]"
  yaml:
  xml:
    pretty: true

3. Zlew

Komponent sink określa, gdzie wygenerowane dane będą przechowywane lub publikowane. Podstawowa implementacja obejmuje wyjście wiersza poleceń i zlewozmywaki plików tekstowych. Dodatkowo, zlewy mogą być rozszerzone o niestandardowe implementacje, takie jak RabbitMQ, jak pokazano w bieżącym artykule. Konfiguracja zlewozmywaków jest określona w sekcji output.yaml file.

sinks:
  rabbitmq:
    batchsize: 1 # when 1 message contains 1 document, when >1 message contains a batch of documents
    host: localhost
    port: 5672
    username: guest
    password: guest
    exchange: test.direct.exchange
    routingkey: products.key

Rozszerzalność poprzez Java SPI

Datafake Gen wykorzystuje Java SPI (Service Provider Interface), aby ułatwić dodawanie nowych formatów lub zlewów. Ta rozszerzalność pozwala na dostosowanie Datafake Gen do konkretnych wymagań.

Jak dodać nowy zlew w Datafake Gen

Przed dodaniem nowego zlewu warto sprawdzić, czy istnieje on już w bazie danych Datafake Gen. datafaker-gen-examples repozytorium. Jeśli nie istnieje, proszę zapoznać się z przykładami, jak dodać nowy zlew.

Jeśli chodzi o rozszerzenie Datafake Gen o nowe implementacje sink, programiści mają dwie podstawowe opcje do rozważenia:

  1. Korzystając z tego projektu nadrzędnego, programiści mogą zaimplementować interfejsy sink dla swoich rozszerzeń sink, podobne do tych dostępnych w repozytorium datafaker-gen-examples.
  2. Proszę dołączyć zależności z repozytorium Maven, aby uzyskać dostęp do wymaganych interfejsów. W przypadku tego podejścia Datafake Gen powinien zostać zbudowany i istnieć w lokalnym repozytorium Maven. To podejście zapewnia elastyczność w strukturze projektu i wymaganiach.

1. Wdrażanie RabbitMQ Zlew

Aby dodać nowy zlew RabbitMQ, wystarczy zaimplementować funkcję net.datafaker.datafaker_gen.sink.Sink interfejs.

Interfejs ten zawiera dwie metody:

  1. getName – Ta metoda definiuje nazwę zlewu.
  2. run – Ta metoda uruchamia generowanie rekordów, a następnie wysyła lub zapisuje wszystkie wygenerowane rekordy do określonego miejsca docelowego. Parametry metody zawierają konfigurację specyficzną dla tego zlewu pobraną z pliku output.yaml oraz funkcję generowania danych i żądaną liczbę wierszy do wygenerowania.
import net.datafaker.datafaker_gen.sink.Sink;

public class RabbitMqSink implements Sink {

    @Override
    public String getName() {
        return "rabbitmq";
    }

    @Override
    public void run(Map<String, ?> config, Function<Integer, ?> function, int numberOfLines) {
        // Read output configuration ...
        int numberOfLinesToPrint = numberOfLines;
        String host = (String) config.get("host");
      
        // Generate lines 
        String lines = (String) function.apply(numberOfLinesToPrint);

        // Sending or saving results to the expected resource
        // In this case, this is connecting to RebbitMQ and sending messages.
        ConnectionFactory factory = getConnectionFactory(host, port, username, password);
        try (Connection connection = factory.newConnection()) {
            Channel channel = connection.createChannel();
            JsonArray jsonArray = JsonParser.parseString(lines).getAsJsonArray();
            jsonArray.forEach(jsonElement -> {
                try {
				    channel.basicPublish(exchange, routingKey, null, jsonElement.toString().getBytes());
                } catch (Exception e) {
				    throw new RuntimeException(e);
                }
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

2. Dodawanie konfiguracji dla nowego RabbitMQ Sink

Jak wspomniano wcześniej, konfigurację zlewozmywaków lub formatów można dodać do pliku output.yaml . Konkretne pola mogą się różnić w zależności od niestandardowego zlewozmywaka. Poniżej znajduje się przykładowa konfiguracja dla RabbitMQ sink:

sinks:
  rabbitmq:
    batchsize: 1 # when 1 message contains 1 document, when >1 message contains a batch of documents
    host: localhost
    port: 5672
    username: guest
    password: guest
    exchange: test.direct.exchange
    routingkey: products.key

3. Dodawanie niestandardowego zlewu przez SPI

Dodanie niestandardowego zlewozmywaka za pośrednictwem SPI (Service Provider Interface) obejmuje włączenie konfiguracji dostawcy w pliku ./resources/META-INF/services/net.datafaker.datafaker_gen.sink.Sink file. Ten plik zawiera ścieżki do implementacji zlewu:

net.datafaker.datafaker_gen.sink.RabbitMqSink

To wszystko są 3 proste kroki, jak rozszerzyć Datafake Gen. W tym przykładzie nie zapewniamy pełnej implementacji zlewu, a także sposobu korzystania z dodatkowych bibliotek. Aby zobaczyć kompletne implementacje, proszę zapoznać się z modułem datafaker-gen-rabbitmq w repozytorium przykładów.

Jak uruchomić

Krok 1

Proszę zbudować plik JAR w oparciu o nową implementację:

Krok 2

Proszę zdefiniować schemat dla rekordów w config.yaml i proszę umieścić ten plik w odpowiedniej lokalizacji, w której generator ma działać. Dodatkowo, proszę zdefiniować zlewy i formaty w pliku output.yaml jak pokazano wcześniej.

Krok 3

Datafake Gen można wykonać za pomocą dwóch opcji:

  1. Proszę użyć skryptu bash ze strony bin w projekcie nadrzędnym:

    # Format json, number of lines 10000 and new RabbitMq Sink
    bin/datafaker_gen -f json -n 10000 -sink rabbitmq

2. Proszę uruchomić plik JAR bezpośrednio, w następujący sposób:

java -cp [path_to_jar] net.datafaker.datafaker_gen.DatafakerGen -f json -n 10000 -sink rabbitmq

Jak szybko to działa?

Test został przeprowadzony w oparciu o schemat opisany powyżej, co oznacza, że jeden dokument składa się z dwóch pól. Dokumenty są zapisywane jeden po drugim w kolejce RabbitMQ w formacie JSON. Poniższa tabela przedstawia prędkość dla 10,000, 100,000 i 1M rekordów na mojej lokalnej maszynie:

Rekordy Czas
10000 401 ms
100000 11613ms
1000000 121601ms

Wnioski

Narzędzie Datafake Gen umożliwia tworzenie elastycznych i szybkich generatorów danych dla różnych typów miejsc docelowych. Zbudowany na Datafaker, ułatwia realistyczne generowanie danych. Programiści mogą łatwo skonfigurować zawartość rekordów, formaty i zlewozmywaki zgodnie z własnymi potrzebami. Jako prosty Java aplikację można wdrożyć w dowolnym miejscu, niezależnie od tego, czy jest to w Docker lub na maszynach lokalnych.

  • Pełny kod źródłowy jest dostępny tutaj.
  • Chciałbym podziękować Sergeyowi Nuyanzinowi za zrecenzowanie tego artykułu.

Dziękuję za przeczytanie i cieszę się, że mogłem Państwu pomóc.