Strona główna / Artykuły

Apache Doris 4.1: wyszukiwanie wektorowe, przechowywanie w formacie JSON, OLAP oraz Lakehouse

Przegląd nowości w Apache Doris 4.1: indeksy wektorowe IVF, funkcja wyszukiwania BM25(), dokumenty JSON o wielkości 100 MB, Segment V3, pamięci cache zapytań, zapisy do Iceberg, operacje MERGE INTO oraz TIMESTAMPTZ.

Wydawca: REACTAPP.TOP18 min czytania4072 słów

Źródła: Apache Doris 4.1: Unified Storage and Retrieval for AI & Search

Apache Doris 4.1 kontynuuje rozwój wątku 4.0, której wydanie wprowadziło do projektu wyszukiwanie wektorowe, hybrydowe oraz funkcję search(), umożliwiając obsługę agentów AI, rozwiązań typu RAG, funkcji obserwowalności AI oraz analiz w czasie rzeczywistym. Wersja 4.1 podąża tą samą drogą i ma na celu stworzenie jednego silnika, który będzie zarządzał zarówno przechowywaniem, jak i wyszukiwaniem danych w zastosowaniach AI. Notatki dotyczące tej wersji koncentrują się na problemach, z którymi borykają się zespoły przenoszące aplikacje AI do środowiska produkcyjnego:

  • utrzymanie przystępnych cen dla dużych ilości danych AI,
  • łączenie wyszukiwania wektorowego, pełnotekstowego oraz filtrów strukturalnych w jednym systemie,
  • umieszczenie długich dokumentów oraz rozbudowanych rekordów półstrukturalnych w jednej tabeli,
  • odpowiadanie na zapytania w czasie rzeczywistym oraz na pytania dotyczące obserwowalności dla modeli LLM, agentów i rozwiązań RAG,
  • utrzymanie szybkości obsługi typu OLAP i lakehouse, za którą znany jest ten projekt,
  • łączenie dużych zadań ETL z pipeline’ami w czasie rzeczywistym.
  • Główne punkty to:

    • Szukanie wektorowe: nowe indeksy IVF i IVF_ON_DISK przeznaczone dla zbiorów na poziomie miliardów elementów i większych.
    • Szukanie pełnego tekstu: funkcja search() otrzymała metody oceny BM25 oraz składnię kompatybilną z Elasticsearch.
    • Zapis długich kontekstów: pojedynczy dokument JSON może teraz osiągać rozmiar 100 MB, co jest przeznaczone do przechowywania informacji w pamięci agentów oraz pracy z długimi kontekstami.
    • Szybkość OLAP: projekt odnotował poprawę o 22,6% w teście TPC-H, 19,1% w TPC-DS i 14,3% w SSB, a także pierwsze miejsce w testach zapytań „chłodnych” na ClickBench.
    • Zbiór danych typu data lake: możliwość odczytu i zapisu danych w formacie Apache Iceberg V2/V3, DDL dla Apache Paimon poprzez SQL oraz cache stron w formacie Parquet dający oszczędności na poziomie około 20%.
    • Rozdzielenie obliczeń i przechowywania: tryb, który według projektu jest stosowany w ponad 2000 firmach, oferujący lepszą widoczność pamięci cache, elastyczność oraz lepsze zachowanie przy zapytaniach typu „cold-query”.

    Wszystkie podane poniżej dane dotyczące wydajności pochodzą z oficjalnego ogłoszenia projektu, dlatego należy je traktować jako informacje dostarczone przez producenta i sprawdzać je w porównaniu z własnymi danymi.

    1. Sztuczna inteligencja i wyszukiwanie

    Wyszukiwanie wektorowe

    IVF dołącza do HNSW. Wersja 4.0 oferowała HNSW jako swój indeks wektorowy. Wersja 4.1 dodaje IVF (inverted file) do obsługi większych zbiorów danych. Chodzi o to, aby z góry grupować wektory w koszach, a następnie sprawdzać tylko te kosze, które najprawdopodobniej zawierają sąsiednie wektory, rezygnując z niewielkiej precyzji na rzecz znacznego wzrostu szybkości. W porównaniu z HNSW, IVF radzi sobie z większymi zbiorami przy mniejszej ilości pamięci, ale kosztem nieco gorszego odzyskiwania informacji. Można to włączyć, ustawiając "index_type"="ivf" w właściwościach indeksu:

    CREATE TABLE sift_1M (
      id int NOT NULL,
      embedding array<float>  NOT NULL  COMMENT "",
      INDEX ann_index (embedding) USING ANN PROPERTIES(
          "index_type"="ivf",
          "metric_type"="l2_distance",
          "dim"="128",
          "nlist"="1024"
      )
    ) ENGINE=OLAP
    DUPLICATE KEY(id) COMMENT "OLAP"
    DISTRIBUTED BY HASH(id) BUCKETS 1
    PROPERTIES (
      "replication_num" = "1"
    );
    

    IVF_ON_DISK. Biblioteki takie jak Faiss radzą sobie dobrze z dziesiątkami milionów wektorów, ponieważ przechowują cały indeks w pamięci RAM. Gdy liczba wektorów osiąga dziesiątki miliardów, koszty pamięci gwałtownie rosną. Doris oparła IVF_ON_DISK na technologii IVF, stosując podejście z badań SPANN firmy Microsoft, i łączy pamięć cache w RAM z cache lokalnego systemu plików, aby efektywnie i tanio usuwać niepotrzebne wektory.

    • Dzięki oddzieleniu obliczeń od przechowywania danych umożliwia tani i szybki proces usuwania oraz odzyskiwania informacji w bardzo dużych skali.
    • W porównaniu z DiskANN budowa indeksu jest znacznie tańsza, co stanowi realistyczną drogę do wyszukiwania na poziomie bilionów elementów.
    • Prawdopodobnie znajduje zastosowanie w bazach wiedzy opartych na sztucznej inteligencji, systemach rekomendacji oraz dużych magazynach wektorów.

    Przejście na tę technologię jest niemal identyczne jak używanie IVF, z użyciem parametru "index_type"="ivf_on_disk":

    CREATE TABLE for_ivf_on_disk (
      id BIGINT NOT NULL,
      embedding ARRAY<FLOAT> NOT NULL,
      INDEX idx_emb (embedding) USING ANN PROPERTIES (
        "index_type"="ivf_on_disk",
          "metric_type"="l2_distance",
          "dim"="128",
          "nlist"="1024"
      )
    ) ENGINE=OLAP
    DUPLICATE KEY(id)
    DISTRIBUTED BY HASH(id) BUCKETS 8
    PROPERTIES ("replication_num" = "1");
    

    Kwantyzacja. Oprócz algorytmu indeksowania obsługiwane są trzy metody kwantyzacji: skalarna INT8, skalarna INT4 oraz kwantyzacja iloczynowa (PQ). Dzięki niewielkiej stratie w zakresie dokładności odzyskiwania danych indeks jest zmniejszany do poziomu od jednej czwartej do jednej ósmej jego pierwotnej pamięci, a w połączeniu z IVF_ON_DISK jeszcze bardziej obniża koszty sprzętowe w dużych systemach wyszukiwania. Poniższy DDL pokazuje kompresję PQ wektorów 128-wymiarowych:

    CREATE TABLE product_quant (
      id BIGINT NOT NULL,
      embedding ARRAY<FLOAT> NOT NULL,
      INDEX idx_emb (embedding) USING ANN PROPERTIES (
        "index_type"="ivf_on_disk",
          "metric_type"="l2_distance",
          "dim"="128",
          "nlist"="1024",
          "quantizer"="pq",
          "pq_m"=64,
          "pq_nbits"=8
      )
    ) ENGINE=OLAP
    DUPLICATE KEY(id)
    DISTRIBUTED BY HASH(id) BUCKETS 8
    PROPERTIES ("replication_num" = "1");
    

    Szybsze zapytania. Nowa optymalizacja „Ann Index Only Scan” pozwala zapytaniom wektorowym pominąć operacje I/O na dysku w przypadku surowych kolumn, co znacznie zmniejsza nakład pracy. Projekt twierdzi, że zapytania do indeksu wektorowego działają nawet cztery razy szybciej niż w wersji 4.0. W teście z milionem wektorów na maszynie z 16 rdzeniami i 64 GB pamięci Doris osiąga około 900 zapytań na sekundę przy 97% dokładności, co wystarcza do większości zadań wyszukiwawczych w produkcji.

    W komunikacie przytaczane są również publiczne dane z VectorDBBench (stan na styczeń 2026 roku), według których Doris tworzy indeksy wektorowe szybciej niż Milvus, Qdrant i pgvector, co zawdzięcza swojej architekturze warstwowej przetwarzania danych. W wersji 4.1 wektory są grupowane w pakiety w pamięci podczas tworzenia, a indeks budowany jest partiami, co zwiększa stopień równoległości bez negatywnego wpływu na jakość indeksu.

    Funkcja search()

    Gdzie wyszukiwanie wektorowe zajmuje się odzyskiwaniem informacji semantycznych, to wyszukiwanie pełnego tekstu służy do znajdowania słów kluczowych, rozwiązywania problemów, wyszukiwania w dziennikach oraz analizy tekstu. Nowa funkcja search() wprowadza to do SQL, dzięki czemu jedno zapytanie może jednocześnie filtrować i agregować dane.

    • Przyjmuje składnię query_string Elasticsearch, co powinno ułatwić migrację z tego narzędzia.
    • Do dyspozycji są operatorzy TERM, PHRASE, WILDCARD, REGEXP, PREFIX, NOT i NESTED – wszystkie one mogą być nawzajem łączone.
    • Zintegrowana jest ocena trafności BM25, z optymalizacją TopN na poziomie warstwy przechowywania, dzięki czemu nie przesyłane są całe zbiory wyników.
    • W połączeniu z typem VARIANT, operator NESTED może przeszukiwać zawarte w nich tablice JSON.
  • Wyszukiwanie wielo-pólowe obsługuje best_fields (dokładne dopasowanie w jednym polu) oraz cross_fields (dopasowanie rozproszone między kilkoma polami).
  • Typowy zapytanie wygląda tak:

    -- Multi-condition: TERM + PHRASE + NOT evaluated in a single pass
    SELECT request_id, error_msg, latency_ms
    FROM inference_logs
    WHERE search('
      level:ERROR
      AND error_msg:"CUDA out of memory"
      AND NOT module:healthcheck
      AND model_name:gpt*
    ')
      AND log_time > NOW() - INTERVAL 1 HOUR
    ORDER BY latency_ms DESC LIMIT 100;
    ​
    -- BM25 relevance scoring
    SELECT request_id, error_msg, score() AS relevance
    FROM inference_logs
    WHERE search('error_msg:"memory allocation failed" OR error_msg:"CUDA error"')
    ORDER BY relevance DESC LIMIT 20;
    ​
    -- Nested search: query inside a VARIANT array
    SELECT * FROM agent_logs
    WHERE search('NESTED(steps, status:error AND tool:code_exec)');
    ​
    -- search + aggregation: filter and analyze in one query
    SELECT model_name, COUNT(*) AS error_count,
           PERCENTILE_APPROX(latency_ms, 0.99) AS p99_latency
    FROM inference_logs
    WHERE search('level:ERROR AND error_msg:"CUDA out of memory"')
      AND log_time > NOW() - INTERVAL 1 HOUR
    GROUP BY model_name ORDER BY error_count DESC;
    

    search() zwraca predykat logiczny, dzięki czemu może być wykorzystywany w operacjach łączenia, funkcjach okiennych oraz zapytaniach podrzędnych, co sprawia, że wyszukiwanie pełnego tekstu staje się standardową częścią SQL.

    Dokumenty JSON o wielkości do 100 MB

    Agenty AI, rozwiązania typu RAG oraz aplikacje wieloetapowe z długim kontekstem coraz częściej chcą przechowywać długi kontekst interakcji w jednym miejscu. Doris 4.1 umożliwia przechowywanie pojedynczych wierszy zawierających dokumenty JSON o wielkości do 100 MB, dzięki czemu wszystkie dane sesji mogą znajdować się w bazie danych: rozmowy wieloetapowe, długie teksty, transkrypcje audio i wideo, ślady działania agentów, logi wywołań narzędzi oraz kontekst używany w systemach RAG. Nie ma potrzeby dzielenia, skracania tych danych ani przenoszenia ich do zewnętrznego przechowywania. Po zapisaniu te dokumenty zachowują się jak inne dane – działają filtry, zapytania warunkowe, operacje agregacji i łączenia, dzięki czemu obszerny kontekst AI staje się strukturalnym zasobem poddającym się wyszukiwaniu.

    Zgodnie z projektem przechowywanie dużych plików JSON w ten sposób umożliwia zespołom:

    • pozbycie się zależności od oddzielnego sklepu obiektów,
    • uniknięcie logiki zapewniającej spójność metadanych i surowego treści,
    • pominięcie konieczności przechowywania danych w fragmentach i ich ponownego łączenia, oraz
    • osiągnięcie niższej latencji zapytań, silniejszych gwarancji transakcyjnych i prostszych operacji.

    Segment V3 i szerokie tabele

    Zadania związane z wyszukiwaniem i sztuczną inteligencją zazwyczaj generują szerokie, rzadkie dane półstrukturyzowane z wieloma polami, zmieniającymi się schematami oraz wyraźnymi wzorcami dostępu do danych „gorących” i „zimnych”. Wymagają one szybkich odczytów losowych, wyszukiwań w określonych punktach oraz intensywnych zapisów równoczesnych.

    Przed wersją 4.1 Doris używał formatu Segment V2, który przechowuje metadane na dole pliku. Jest to odpowiednie dla skanowania partiami, ale odczyty losowe i zapytania obejmujące małe zakresy wymagają za każdym razem ładowania całego dolnego fragmentu pliku, co zwiększa koszty operacji dyskowych i parsowania.

    Segment V3, pod wpływem nowszych formatów takich jak Lance i Vortex, oddziela metadane od stopki strony i ładuje je na żądanie. Ma na celu rozwiązanie problemów z nadmiarem metadanych, powolnym otwieraniem plików oraz dużym obciążeniem wynikającym z losowych odczytów. Przykładami zastosowań są szerokie tabele, tabele pełne podkolumn VARIANT, zastosowania, w których opóźnienia przy pierwszym uruchomieniu w systemach przechowywania obiektów stanowią problem, oraz dane półstrukturyzowane z dziedziny sztucznej inteligencji lub telematyki pojazdowej, które są często odczytywane losowo. W tabeli z 7 000 kolumnami i 10 000 segmentami V3 ma otwierać się nawet 16 razy szybciej i zużywać do 60 razy mniej pamięci. Aby to włączyć, ustaw "storage_format" = "V3" w właściwościach tabeli:

    CREATE TABLE table_v3 (
        id BIGINT,
        data VARIANT
    )
    DISTRIBUTED BY HASH(id) BUCKETS 32
    PROPERTIES (
        "storage_format" = "V3"
    );
    

    Kolumny rzadkie

    JSON o szerokim formacie zazwyczaj zawiera długi szereg rzadko używanych ścieżek oraz kilka często aktywnych. Doris 4.1 przebudował mechanizm odczytu danych rzadkich w taki sposób, aby długi szereg ścieżek nie stanowił wąskiego gardła dla pojedynczej kolumny rzadkiej.

    • Rozdzielenie ścieżek często używanych od rzadko używanych: ścieżki często wykorzystywane pozostają jako podkolumny, natomiast ścieżki rzadko używane przenoszone są do przechowywania rzadkiego typu, co zapobiega mnożeniu się podkolumn.
    • Rozdzielanie na fragmenty w formacie rzadkim: variant_sparse_hash_shard_count rozkłada ścieżki rzadko używane na kilka kolumn rzadkich, zmniejszając w ten sposób efekt wzrostu obciążenia przy odczytach z jednej konkretnej kolumny.
    • Pamięć cache dla kolumn rzadkich: cache do odczytu danych z kolumn rzadkich redukuje powtarzające się operacje I/O na dysku, dekodowanie oraz deserializację.

    To rozwiązanie nadaje się do JSON o szerokim formacie pochodzącego z systemów telematyki pojazdów, profili użytkowników oraz rejestrów zdarzeń – wszędzie tam, gdzie rekord zawiera wiele pól, ale tylko kilkadziesiąt lub kilkaset ścieżek jest często wyszukiwanych:

    CREATE TABLE user_feature_wide (
        uid BIGINT,
        features VARIANT<
            'user_id' : BIGINT,
            'region' : STRING,
            properties(
                'variant_max_subcolumns_count' = '2048',
                'variant_sparse_hash_shard_count' = '32'
            )
        >
    )
    DUPLICATE KEY(uid)
    DISTRIBUTED BY HASH(uid) BUCKETS 32
    PROPERTIES (
        "storage_format" = "V3"
    );
    

    Tryb DOC

    Gdy priorytetem jest wydajność zapisu lub pobieranie całych dokumentów JSON, tryb DOC jest lepszym wyborem. Przechowuje surowy format JSON podczas zapisu i odkłada wyodrębnianie poszczególnych elementów na później, podczas procesu kompresji, co zmniejsza koszty zapisu oraz efekt amplifikacji danych.

    • Odkładana materializacja: surowy format JSON jest przechowywany podczas zapisu, co zmniejsza obciążenie w przypadku małych partii danych.
    • Dzielenie na fragmenty w trybie DOC: variant_doc_hash_shard_count dzieli magazyn dokumentów na kilka fragmentów, co ułatwia zarówno odczyt całych dokumentów, jak i wyodrębnianie poszczególnych elementów.
    • Progiem decyzyjnym: variant_doc_materialization_min_rows określa moment, w którym rozpoczyna się proces materializacji; partie danych mniejsze od tego progu czekają aż do momentu kompresji.

    Celuje w wyniki generowane przez LLM, dane śledzenia, zrzuty kontekstu oraz odtwarzanie zdarzeń – zadania, które często zwracają całe dokumenty. Aby to skonfigurować, włącz variant_enable_doc_mode, a następnie dostosuj próg oraz liczbę fragmentów do objętości swoich danych. Tryb DOC i kolumny rzadkie wykluczają się wzajemnie, więc wybierz jeden z nich i połącz go z storage_format = „V3”:

    CREATE TABLE trace_archive (
        ts DATETIME,
        trace_id STRING,
        span VARIANT<
            'service_name' : STRING,
            properties(
                'variant_enable_doc_mode' = 'true',
                'variant_doc_materialization_min_rows' = '100000',
                'variant_doc_hash_shard_count' = '32'
            )
        >
    )
    DUPLICATE KEY(ts, trace_id)
    DISTRIBUTED BY HASH(trace_id) BUCKETS 32
    PROPERTIES (
        "storage_format" = "V3"
    );
    

    2. Szybszy OLAP

    Doris zyskała sławę dzięki szybkiemu, w czasie rzeczywistym OLAP, a wersja 4.1 nadal pracuje nad tym, redukując marnotrawstwo obliczeń, przesyłając mniej danych i działając bardziej efektywnie, dzięki czemu złożone zapytania pozostają szybkie nawet przy realistycznym obciążeniu.

    Testy wielotablicowe i tablic szerokich

    W przypadku standardowych zadań łączenia i agregacji, nowa wersja pokazuje następujące ulepszenia względem 4.0: 22,6% w TPC-H, 19,1% w TPC-DS oraz 14,3% w SSB.

    Dla tablic szerokich ClickBench wykorzystuje 100 GB danych oraz 43 złożone zapytania, aby sprawdzić przechowywanie kolumnowe, wykonywanie wektorowe i kompresję, co czyni go jednym z najbardziej wymagających testów dla pojedynczych tablic. Na instancjach c7a.metal-48xl projekt wskazuje, że Doris 4.1 zajmuje pierwsze miejsce pod względem szybkości obsługi zapytań „chłodnych” oraz zużycia przestrzeni przechowywania, a drugie miejsce ogólnie, ustępując jedynie ClickHouse (web).

    Optymalizacje leżące u podstaw tych wyników zostaną opisane poniżej.

    Agregacja poprzez połączenia

    Ta optymalizacja dzieli skomplikowane operacje agregacyjne i przenosi je na obie strony połączenia. Każda tabela jest agregowana lokalnie, następnie łączą się skrócone wyniki, a ostatecznie przeprowadzana jest agregacja globalna. Kompresja danych przed połączeniem zmniejsza ilość informacji przekazywanych pomiędzy tabelami, co ma wyraźny wpływ na zużycie pamięci i opóźnienia. W testach projektu ogólna wydajność wzrosła o ponad 200%, w ponad połowie przypadków o więcej niż 50%, a w prawie jednej trzeciej nawet o ponad 100 razy.

    Grupowanie zbiórów

    Silnik teraz identyfikuje najdrobniejsze grupy oraz ich wskaźnik agregacji i zmienia strategię z jednoczesnej agregacji wielu grup na plan dwuetapowy: najpierw dokonuje najbardziej szczegółowej agregacji w celu zmniejszenia objętości danych, a następnie wyprowadza pozostałe grupy na podstawie tego wyniku. Odnotowane ogólne ulepszenie przekracza 10%, przy czym w ponad jednej piątej przypadków jest ono większe niż 20%, a w najlepszym przypadku osiąga 160%; najgorszy przypadek charakteryzuje się regresją poniżej 5%.

    Odrzucanie nawarstwionych kolumn

    Silnik dokładniej rozumie strukturę nawarstwionych pól. Gdy zapytanie dotyczy tylko jednego podpola, odczytuje się tylko odpowiednie dane, a pozostałe są pomijane, co oszczędza zasoby dysku. W wersji 4.1 funkcja ta działa zarówno dla tabel wewnętrznych, jak i dla danych z formatów ORC oraz Parquet. Odnotowane ogólne oszczędności przekraczają 60%, a w skrajnych przypadkach sięgają nawet 700%.

    Pamięć cache warunków

    W analizach na dużą skalę często ponownie wykorzystuje się te same filtry w kolejnych zapytaniach:

    SELECT * FROM orders WHERE region = 'ASIA';
    SELECT count(*) FROM orders WHERE region = 'ASIA';
    

    Wielokrotne stosowanie tego samego filtru do tych samych segmentów zużywa zasoby CPU oraz przepustowość dysku. Pamięć cache warunkowa przechowuje wyniki filtrowania dla poszczególnych segmentów, aby umożliwić szybsze zapytania w przyszłości, eliminując zbędne skanowanie i obliczenia. W przypadku złożonych obciążeń zapytaniami, rzekoma poprawa wydajności przekracza 10%.

    Pamięć cache zapytań

    Obciążenia analityczne również powtarzają te same operacje agregacji na niezmienionych danych:

    SELECT region, SUM(revenue) FROM orders WHERE dt = '2024-01-01' GROUP BY region;
    

    Każdy przeprowadzony proces skanuje te same tablice i ponownie oblicza te same agregaty. Cache zapytań przechowuje tymczasowe wyniki agregacji i, gdy kontekst zapytania jest identyczny, zwraca je bezpośrednio, co oszczędza zasoby obliczeniowe oraz operacje wejścia/wyjścia z dysku.

    CASE WHEN

    CASE WHEN to kluczowa struktura służąca do klasyfikacji biznesowej, logiki na poziomie wierszy oraz agregacji warunkowej. Wersja 4.1 wprowadza funkcje łączenia gałęzi, eliminacji gałęzi, wyodrębniania wspólnych podwyrażeń oraz wyodrębniania i przenoszenia wartości typu enum. W zestawie testowym średni wzrost wydajności wynosi ponad 200%, a w najgorszych przypadkach przekracza 50 razy.

    3. Oddzielenie obliczeń od przechowywania

    Zgodnie z informacjami projektu, architektura oddzielająca obliczenia od przechowywania jest już używana przez ponad 2000 użytkowników w środowisku produkcyjnym, dlatego stabilność i wydajność zapytań stały się głównymi obszarami uwagi.

    Cache plików

    Metadane pamięci podręcznej plików są teraz przechowywane trwale, co eliminuje intensywne operacje wejścia/wyjścia z dysku, które wcześniejsze wersje musiały wykonywać podczas uruchamiania w celu odbudowy stanu pamięci podręcznej. Nowa tabela systemowa information_schema.file_cache_info pokazuje szczegóły pamięci podręcznej na poziomie bloków za pomocą SQL i może być wyszukiwana według tablet_id, be_id, cache_path oraz type. Ułatwia to znajdowanie często używanych danych, diagnozowanie nierównowagi pamięci podręcznych oraz wykrywanie nieprawidłowego wzrostu.

    Jednym z zastosowań jest sprawdzanie składu pamięci podręcznej pojedynczej tablicy:

    mysql> select * from information_schema.file_cache_info where TABLET_ID = 1761571031445;
    +----------------------------------+---------------+-------+--------+-------------+-----------------+---------------+
    | HASH                             | TABLET_ID     | SIZE  | TYPE  | REMOTE_PATH | CACHE_PATH       | BE_ID         |
    +----------------------------------+---------------+-------+--------+-------------+-----------------+---------------+
    | 468448215c52334ae5bee147259b1027 | 1761571031445 | 15120 | index | | /mnt/disk1/project/filecache | 1761571031251 |
    | 71bb73d34cd8ffe280b16dd329df5ba1 | 1761571031445 | 13117 | index | | /mnt/disk1/project/filecache | 1761571031251 |
    | 77c6b69d1a7c4fe740a11bab5c1bbaa3 | 1761571031445 | 12249 | index | | /mnt/disk1/project/filecache | 1761571031251 |
    +----------------------------------+---------------+-------+--------+-------------+-----------------------------------------------------------------------------+---------------+
    

    Kolejnym sposobem jest agregacja rozkładu w celu oceny równowagi oraz wykorzystania zasobów pomiędzy węzłami BE:

    SELECT be_id, tablet_id, type, SUM(size) AS cache_bytes
        FROM information_schema.file_cache_info
        WHERE tablet_id = 1761571031445
        GROUP BY be_id, tablet_id, type
        ORDER BY cache_bytes DESC;
    

    Elastyczność, zapytania „chłodne” i inne

    • Elastyczne skalowanie: w tym trybie operacje skalowania na milionach urządzeń kończą się w ciągu kilku minut, ponieważ planowanie nie zależy już od globalnej liczby urządzeń.
    • Zapytania „chłodne”: wcześniejsze pobieranie danych na podstawie semantyki skanowania stron w Doris przyspiesza wykonywanie zapytań „chłodnych” na tabelach wewnętrznych, a dostosowanie parametrów umożliwia Doris wykorzystanie większej przepustowości pamięci przechowywania zdalnego.
    • Wielkoskalowe wdrożenia: obiekty repliki i urządzeń w warstwie FE zostały uproszczone, co zmniejsza zużycie pamięci FE o ponad 30% przy milionach urządzeń.
    • Meta-usługa: warstwa cache zmniejsza liczba powtarzających się żądań do Meta Service i zwiększa przepustowość metadanych, a ścieżki dostępu do niektórych tabel systemowych zostały zoptymalizowane.
  • Koszt przechowywania obiektów: przy częstym importowaniu łączenie zapytań na poziomie węzłów zmniejsza liczbę żądań dotyczących przechowywania obiektów oraz małych plików, a według projektu ogólne koszty mogą spaść nawet o 90%.
  • Kompresja i kodowanie: bardziej efektywne kodowanie binarne w połączeniu z uprzednim dekodowaniem obniża koszty dekodowania w trakcie działania, a domyślny algorytm kompresji stopniowo jest zastępowany przez ZSTD, aby uzyskać lepszy stosunek jakości do szybkości dekompresji. W przypadku szerokich i szczegółowych tabel oznacza to mniejsze zapotrzebowanie na przechowywanie oraz lepszą wydajność przy odczytach z „zimnego” magazynu.
  • 4. Data lakehouse

    Wersja 4.1 rozwija możliwości lakehouse pod względem zakresu formatów, szybkości zapytań oraz kompatybilności z ekosystemem. Dzięki Doris SQL można czytać, pisać i zarządzać głównymi otwartymi formatami tabel, takimi jak Apache Iceberg i Apache Paimon, wykorzystując samą Doris SQL, bez Sparka ani innego zewnętrznego silnika.

    Zarządzanie cyklem życia

    Tworzenie tabel, wstawianie, aktualizowanie i usuwanie danych odbywa się za pośrednictwem Doris SQL, więc jeden silnik obsługuje cały proces pracy z danymi.

    • Czytanie i zapisywanie w formacie Iceberg V2/V3: obsługiwane są operacje INSERT, UPDATE, DELETE i MERGE INTO, a także funkcje V3 takie jak Deletion Vector i Row Lineage. Procesy pobierania danych, aktualizacji i usuwania odbywają się w całości bez udziału zewnętrznych silników.
    • Zarządzanie Paimonem: polecenia CREATE DATABASE, CREATE TABLE oraz inne polecenia DDL są wykonywane bezpośrednio w Doris SQL. Zapisywanie danych do tabel Paimon jest planowane na przyszłe wersje.

    Wydajność zapytań w przypadku danych przechowywanych w formacie lake

    • Zapisywanie danych uporządkowane w formacie Iceberg: dane mogą być zapisywane według wybranej kolejności sortowania, co generuje uporządkowane metadane (granice dolne i górne), których silnik używa do filtrowania plików. W testach TPC-DS stwierdzono, że dzięki temu wydajność zapytań wzrasta o około 15%.
  • Caching manifestu lodowca: przechowywanie w pamięci metadanych na poziomie manifestu zapobiega powtarzającym się odczytom i analizom podczas planowania, co zmniejsza obciążenie dysku oraz zużycie CPU. Przy częstych zapytaniach rozwiązywanie złożonych metadanych zajmuje, jak donoszono, od kilkuset do setek milisekund.
  • Caching stron w formacie Parquet: rozpakowane strony są przechowywane w pamięci, dzięki czemu zmniejsza się liczba operacji rozpakowywania i odczytów z dysku, a opóźnienia przy częstych zapytaniach znacznie spadają. W testach ClickBench ogólna wydajność wzrosła o około 20%.
  • Użyteczność analityki federowanej

    • Kontrola dostępu do pamięci cache: zasady na poziomie użytkownika, katalogu, bazy danych i tabeli decydują, które zapytania mogą zapisywać dane do pamięci cache, zapobiegając wyrzucaniu danych rzadko używanych na rzecz często używanych i zwiększając wskaźnik trafień w kluczowych obszarach. Zasady znajdują się w plikach JSON w określonej katalogu i są aktualizowane dynamicznie po zmianie, bez konieczności restartowania serwera front-endu; komenda EXPLAIN pokazuje decyzje dotyczące dostępu, co umożliwia ich analizę pod kątem optymalizacji.
    • Zapisy w MaxCompute: polecenia CREATE TABLE i INSERT teraz działają w zewnętrznym katalogu MaxCompute, co uzupełnia ścieżkę eksportu z Doris do MaxCompute. Obsługiwany jest dostęp międzykonta poprzez ARN, co ułatwia integrację z ekosystemem Alibaba Cloud.
  • Inspekcja metadanych Parquet: nowa funkcja o wartości tabeli umożliwia uzyskanie statystyk dotyczących podziałów, grup wierszy i kolumn za pomocą SQL, co jest przydatne do debugowania struktury plików, sprawdzania procesu eliminacji niepotrzebnych podziałów oraz optymalizacji zapytań.
  • 5. Przetwarzanie partiami

    Doris dąży do połączenia analityki interaktywnej z dużym przetwarzaniem partiami w jednym silniku, co zmniejsza złożoność architektoniczną związaną z uruchamianiem kilku systemów równocześnie. Wersja 4.1 dodatkowo wzmocniła funkcje natywnego ETL i ELT.

    MERGE INTO

    Jedno standardowe polecenie SQL MERGE INTO obsługuje operacje INSERT, UPDATE i DELETE (upsert), co upraszcza zadania łączenia danych w sposób stopniowy, np. w przypadku CDC, oraz zmniejsza wysiłek potrzebny do rozwoju i konserwacji oprogramowania:

    MERGE INTO target t
    USING source s
    ON t.id = s.id
    WHEN MATCHED THEN
        UPDATE SET t.value = s.value
    WHEN NOT MATCHED THEN
        INSERT (id, value) VALUES (s.id, s.value);
    

    Lepsze przechowywanie danych na dysku

    Wielkie operacje łączenia, agregacje o dużej kardynalności oraz sortowanie globalne wymagają dużej ilości pamięci, a wersja 4.1 rozszerza funkcję przechowywania danych na dysku na te operatory:

    • recyrzytacyjne, wielopoziomowe przechowywanie danych na dysku umożliwia przepływ danych pośrednich przez kilka etapów i zapobiega nagłemu obciążeniu pamięci,
    • funkcja ta działa przy operacjach łączenia, agregacji oraz sortowania, oraz
    • dynamiczne uruchamianie przechowywania na dysku zapewnia równowagę między wykorzystaniem pamięci a operacjami wejścia/wyjścia na dysku, dzięki czemu zapytania pozostają stabilne.

    Zgodnie z tymi zmianami Doris może wykonywać wszystkie zapytania TPC-DS 10 TB na jednym węźle BE z 8 GB pamięci, co stanowi lepszą wydajność przy niższych kosztach zasobów w porównaniu z tradycyjnymi rozwiązaniami typu Hadoop, Greenplum czy Spark. Jak zawsze w przypadku takich danych, jest to twierdzenie, które warto samodzielnie sprawdzić.

    6. Użyteczność

    Wersja 4.1 uzupełnia składnię analityczną, poprawia możliwości wyrażania się w złożonych scenariuszach oraz pracuje nad kompatybilnością z innymi systemami.

    Rozszerzenia silnika wykonywania

    UNNEST. Wbudowany UNNEST upraszcza analizę tablic i zagnieżdżonych struktur w danych JSON oraz logów bez konieczności niezręcznego przepisywania funkcji:

    SELECT user_id, tag
    FROM user_profile,
    UNNEST(tags) AS t(tag);
    

    Recursivezne CTE. Możesz teraz pisać zapytania rekurencyjne do przemierzania drzew organizacyjnych, hierarchii i ścieżek grafowych, lub do analizy innych związków wymagających przeszukiwania:

    WITH RECURSIVE org_tree AS (
        SELECT id, parent_id, name
        FROM org
        WHERE parent_id IS NULL
    ​
        UNION ALL
    ​
        SELECT o.id, o.parent_id, o.name
        FROM org o
        JOIN org_tree t ON o.parent_id = t.id
    )
    SELECT * FROM org_tree;
    

    ŁĄCZENIE ASOF. Łączy dane na podstawie najbliższego zgodnego elementu w kolumnie czasowej (<= lub >=); przydatne w zastosowaniach finansowych, IoT oraz systemach monitoringu, które wymagają synchronizacji serii czasowych i wyszukiwania najbliższych wartości:

    SELECT t1.ts, t1.value, t2.price
    FROM trades t1
    ASOF JOIN prices t2
    ON t1.symbol = t2.symbol
    AND t1.ts >= t2.ts;
    

    Przyjmowanie danych i ścieżka zapisu

    • Ciągły import z S3: można tworzyć zadania ciągłe na podstawie źródeł z S3, a system wykrywa nowe pliki i nadal je importuje, co umożliwia stopniowe przyjmowanie danych z chmury obiektowej.
    • Synchronizacja z MySQL i PostgreSQL: Doris może teraz aktualizować się w czasie rzeczywistym na podstawie danych z MySQL i PostgreSQL, obejmując pełną inicjalizację oraz synchronizację stopniową. To ułatwia tworzenie pipeline’ów w czasie rzeczywistym na bazie bazy danych operacyjnych, służących do przechowywania danych w czasie rzeczywistym, konsolidacji danych oraz przyspieszenia analiz.

    Zapis i aktualizacja modeli

    • Adaptacyjne planowanie zapisu: grupa wątków do oczyszczania MemTable dostosowuje się do obciążenia klastra i dopasowuje jednoczesność zapisów do aktualnych warunków, co poprawia przepustowość, wykorzystanie zasobów oraz stabilność podczas intensywnego zapisu danych.
  • Wielopotokowe aktualizacje w modelu klucza głównego: sequence_mapping umożliwia łączenie aktualizacji z kilku potoków. Różne potoki mogą aktualizować różne kolumny jednej tabeli i łączyć je według własnych pól sekwencyjnych, co nadaje się do jednoczesnych aktualizacji w czasie rzeczywistym oraz uzupełnień offline.
  • Routine Load: elastyczne częściowe aktualizacje kolumn innych niż klucz główny, dynamiczna zmiana parametrów oraz adaptacyjne grupowanie zwiększają stabilność przy wysokim przepustowości.
  • Audyt importu: aktywność Stream Load może być rejestrowana w tabeli systemu audytu, dzięki czemu historia, debugowanie i audyty mają jeden wspólny punkt do wyszukiwania informacji.
  • TIMESTAMPTZ

    Globalne obciążenia pracy, takie jak logi międzyregionowe, analiza zachowań użytkowników i transakcje finansowe, wymagają wyraźnego określenia stref czasowych. Dzięki typowi DATETIME bez strefy konwersja odbywa się w aplikacji, co sprzyja błędom i dodatkowej pracy nad rozwojem. Doris 4.1 wprowadza typ TIMESTAMPTZ (zapis z datą i godziną wraz ze strefą czasową) umożliwiający standardowe zarządzanie strefami czasowymi:

    • wartości są przechowywane w formacie UTC podczas zapisu,
    • wartości odczytywane są konwertowane na strefę czasową używaną przez sesję,
    • dane wejściowe z lub bez informacji o strefie są analizowane i konwertowane automatycznie, oraz
    • TIMESTAMPTZ i DATETIME mogą być wzajemnie konwertowane i współpracować z istniejącymi funkcjami.

    To przenosi zarządzanie strefami czasowymi z kodu aplikacji do jądra bazy danych, poprawiając spójność pomiędzy systemami i zmniejszając złożoność obsługi danych w różnych strefach czasowych.

    Jakie to przynosi korzyści

    Łącznie wersja 4.1 stanowi znaczący krok w kierunku ustanowienia Doris jako kluczowej warstwy danych dla aplikacji AI i analiz w czasie rzeczywistym: indeks IVF rozszerza możliwości wyszukiwania wektorowego o znacznie większe zbiory, dokumenty JSON o pojemności 100 MB umożliwiają prowadzenie rozmów o długim kontekście, a wydajność rozwiązań OLAP i lakehouse wykazuje mierzalne ulepszenia w porównaniu z wersją 4.0. Chodzi o jedną infrastrukturę obejmującą wyszukiwanie wektorowe, wyszukiwanie pełnego tekstu, analizy w czasie rzeczywistym oraz lakehouse, dzięki czemu potrzeba mniej oddzielnych baz danych wektorowych, silników wyszukiwania i mechanizmów zapytań. To, czy taka konsolidacja przyniesie korzyści, zależy od skali działalności, celów dotyczących opóźnień oraz od tego, jak liczby podane przez dostawcę sprawdzą się w rzeczywistych warunkach pracy.

    Literatura pokrewna

  • Hybrydowe wyszukiwanie w RAG: praktyczne zastosowanie BM25, wektorów i fuzji rankingu wzajemnego — Dlaczego RAG oparte wyłącznie na wektorach traci dokładne identyfikatory, jak RRF łączy BM25 z embeddingami, gdzie hybrydowe wyszukiwanie daje gorsze wyniki i dlaczego filtry metadanych powinny być stosowane przed fuzją.
  • Runbooki do wyszukiwania – nie wklejaj ich: krótki przykład ścieżki RAG z odniesieniami w LangChain — Jak stworzyć dwuetapową ścieżkę wyszukiwania w LangChain: załaduj runbooki, podziel je na fragmenty, przeprowadź wyszukiwanie za pomocą precyzyjnego zapytania, zachowaj metadane, wymagaj identyfikatorów źródeł z odniesieniami i przetestuj to bez płatnych embeddingów.
  • GraphRAG vs Vector RAG: Wybieranie strategii wyświetlania danych w zależności od pytania — Wyszukiwanie wektorowe znajduje podobny tekst, ale pytania wieloetapowe wymagają określonych powiązań. Dowiedz się, kiedy nadają się GraphRAG, rozwiązania hybrydowe czy wyszukiwanie według słów kluczowych, oraz ile kosztuje uruchomienie grafu.