Apache Hudi: gdy lakehouse ma nadążać za bazą

Zespół finansów dystrybutora przeładowuje tabelę należności co noc: usunąć partycję miesiąca, zapisać ją na nowo z ERP, cztery godziny pracy klastra. Potem sprzedaż pyta o pozycję kredytową klienta na teraz, bo klient jest na linii. Nocna tabela ma osiemnaście godzin, a jedyna aktualna odpowiedź jest w ERP, którego nikt nie chce oddać działowi sprzedaży do bezpośredniego odpytywania.

Apache Hudi powstał dokładnie dla tej luki. Jego pytanie nie brzmi, jak przechowywać tabelę w jeziorze, lecz jak zmienić jeden wiersz w tabeli z miliarda bez przepisywania partycji i jak powiedzieć zadaniu niżej w łańcuchu, które wiersze zmieniły się od jego ostatniego uruchomienia. W architekturze systemu AI-native dla przedsiębiorstwa czyni to z Hudi format tabeli dla tej części drugiej pamięci, która ma zostać blisko pierwszej.

Co Hudi robi, czego nocne przeładowanie nie potrafi

Projekt niosą trzy mechanizmy. Wszystkie są opisane na stronach projektu; bieżące wydanie to Hudi 1.2.1 z 25 września 2026, z wersją tabeli 9 i konektorem Trino utrzymywanym odtąd w repozytorium projektu (sprawdzono 21 października 2026).

Klucz rekordu i indeks. Każdy wiersz ma klucz, a Hudi trzyma w tabeli metadanych indeks, który mówi, która grupa plików zawiera bieżącą wersję tego klucza. Rodzina indeksów obejmuje indeks Blooma na plik, indeks rekordów (globalny albo per partycja), a od wydania 1.0.0 także indeksy wtórne, indeksy wyrażeń i statystyki partycji. Po stronie pisarza domyślna strategia to SIMPLE, z alternatywami BUCKET, HBASE i FLINK_STATE. Indeks jest tym, co zamienia „zaktualizuj klienta 4471” w zapis do jednej grupy plików zamiast skanu miesiąca.

Oś czasu. Każda akcja na tabeli — commit, delta commit, kompaktowanie, klastrowanie, czyszczenie, wycofanie, punkt zapisu, przywrócenie — jest chwilą na osi czasu w trzech stanach: zażądana, w toku, zakończona. Aktywna oś czasu leży w .hoodie/timeline; historia jest archiwizowana w strukturze LSM z plików Parquet i manifestów, żeby długo żyjąca tabela nie dusiła się własną przeszłością. Chwile są porządkowane po czasie zakończenia. Oś czasu jest dla Hudi tym, czym log transakcji dla Delta Lake: jedynym źródłem prawdy o tym, które pliki składają się na tabelę.

Dwa typy tabel. Copy-on-Write przepisuje bazowy plik Parquet grupy plików przy każdej zmianie; odczyt jest prosty, bo nie ma czego scalać. Merge-on-Read dopisuje zmiany do plików dziennika obok pliku bazowego; odczyt migawkowy scala je w locie, odczyt zoptymalizowany bierze tylko pliki bazowe, a kompaktowanie co jakiś czas składa dzienniki w nowe pliki bazowe. Merge-on-Read daje krótsze opóźnienie zapisu, Copy-on-Write szybszy odczyt. Oba obsługują trzy rodzaje zapytań: migawkowe, przyrostowe — ostatni stan albo przechwycone zmiany z obrazem przed i po — oraz, dla Merge-on-Read, zoptymalizowane pod odczyt.

Infografika

Tabela należności: dwa sposoby utrzymania aktualności

Nocne pełne przeładowanie

  • Usunięcie i ponowny zapis partycji miesiąca z ERP
  • Godziny pracy klastra niezależnie od tego, ile się zmieniło
  • Odpowiedzi tak stare jak ostatnie uruchomienie
  • Zadania niżej przeliczają wszystko
  • Usunięcie oznacza kolejne pełne przepisanie

Przyrostowe upserty z Hudi

  • Zdarzenia CDC z dziennika ERP, stosowane po kluczu
  • Koszt proporcjonalny do liczby zmian
  • Odpowiedzi minuty za bazą
  • Zadania niżej czytają tylko to, co zmieniło się od ich ostatniej chwili
  • Usunięcie to jedna operacja po kluczu, ostateczna po czyszczeniu
Prawa strona przenosi koszt z każdego uruchomienia na serwisy tabeli pracujące w tle.

Droga z ERP

Zwykły łańcuch to dziennik transakcji bazy czytany przez Debezium do Apache Kafka, konsumowany przez Hudi Streamer — własne narzędzie ingestu projektu, które obsługuje Kafkę, systemy plików, JDBC, Pulsar, Kinesis, zdarzenia magazynów obiektowych i rekordy zmian Debezium, pracuje w trybie ciągłym i czyta schematy z rejestru schematów. Streamer stosuje zmiany jako upserty do tabeli Merge-on-Read z kluczem głównym ERP.

Dalej resztę robi zapytanie przyrostowe. Zadanie należności prosi o każdą zmianę od chwili, którą ostatnio przetworzyło, i przelicza tylko klientów, którzy się ruszyli. Agent przygotowujący decyzje kredytowe czyta migawkę i zapisuje chwilę, którą odczytał. Oba są tańsze od nocnego przeładowania i oba potrafią powiedzieć, co widziały.

Taką tabelę może dzielić kilku pisarzy. Hudi 1.x dodaje nieblokującą kontrolę współbieżności dla tabel Merge-on-Read z indeksem kubełkowym: pisarze biorą blokadę tylko na metadane osi czasu, nie na dane, a dokumentacja projektu zaznacza, że nie łączy się to jeszcze z klastrowaniem. Domyślnie nadal jest jeden pisarz, a pomiędzy leży optymistyczna kontrola współbieżności z dostawcą blokad.

Dystrybutor z limitami kredytowymi

Weźmy dystrybutora, którego ERP trzyma zamówienia, faktury i limity kredytowe, a dział sprzedaży potrzebuje pozycji kredytowej w ciągu minut od zaksięgowania płatności. To nasza ilustracja, nie historia klienta.

Przedtem: tabela należności jest odbudowywana nocą. Sprzedaż dzwoni do finansów w każdej pilnej sprawie, a finanse otwierają ERP. Klient po limicie zamawia dalej do następnego ranka.

Z Hudi: Debezium emituje zmiany faktur i płatności; Hudi Streamer wstawia je upsertem do tabeli Merge-on-Read z kluczem faktury; harmonogram kompaktowania składa pliki dziennika co godzinę; zadanie przyrostowe aktualizuje otwartą pozycję na klienta; agent kredytowy czyta tę pozycję i proponuje zwolnienie albo wstrzymanie, co człowiek potwierdza w ERP. Gdy klient korzysta z prawa do usunięcia danych, usunięcie jest zapisem po kluczu i staje się ostateczne, kiedy czyszczenie usunie stare wersje plików — to ustawienie retencji, które ktoś musi mieć na własność.

Co mierzyć: opóźnienie od zmiany w ERP do jej widoczności w tabeli, udział obliczeń niżej w łańcuchu, które są przyrostowe, a nie pełne, czas realizacji żądania usunięcia i miesięczny koszt serwisów tabeli. Ten ostatni to uczciwa cena minut.

Gdzie leżą decyzje inżynierskie

Agenci kodujący dobrze obsługują sporą część tego łańcucha. Generują konfigurację Streamera ze schematu zdarzeń, szkicują harmonogramy kompaktowania i czyszczenia, piszą zadanie przyrostowe i testy, które porównują wynik przyrostowy z pełnym przeliczeniem na próbce. To porównanie jest testem odbiorczym, na który nalegamy, zanim potok przyrostowy zastąpi przeładowanie.

Trzech decyzji nie należy im oddawać. Klucz rekordu, bo zły klucz robi z każdej późniejszej aktualizacji nowy wiersz. Typ tabeli, bo Merge-on-Read bez przypisanego harmonogramu kompaktowania degraduje się po cichu. I retencja, bo czyszczenie jest zarazem kontrolą kosztu i chwilą, w której usunięcie staje się prawdziwe. Te trzy trafiają do specyfikacji danych z nazwiskiem przy każdej.

Należy tam jeszcze jedno: kto czyta tabelę. Dokumentacja Hudi wymienia jako silniki Spark, Flink, Trino i Presto. Inne platformy docierają do tabeli Hudi zwykle przez Apache XTable, który tłumaczy jej metadane na Iceberg albo Delta Lake — a XTable nie obsługuje jeszcze tabel Merge-on-Read. Jeśli w grze jest czytelnik ze Snowflake albo Fabric, to ograniczenie rozstrzyga o typie tabeli, zanim zrobi to jakikolwiek test wydajności.

Jak wygląda dobry wynik

Jedna tabela, którą czytają dział sprzedaży, zadanie finansowe i agent kredytowy, minuty za ERP, z opublikowaną liczbą opóźnienia. Zadania niżej, które przetwarzają zmiany, a nie miesiące. Procedura usunięcia z datą. I pozycja w budżecie na kompaktowanie i czyszczenie, która nikogo nie zaskakuje.

Nasza część

W inżynierii danych AI budujemy ścieżkę przyrostową z systemu zapisu: kontrakty CDC, tabele Hudi z ich kluczami, typami i serwisami, zadania przyrostowe z testami odbiorczymi oraz reguły retencji z nazwanymi właścicielami. Nie odsprzedajemy platform. Więcej o predictes na stronie głównej.