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.
Ź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,
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_stringElasticsearch, 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
NESTEDmoże przeszukiwać zawarte w nich tablice JSON.
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_countrozkł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_countdzieli 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_rowsokreś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.
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 TABLEoraz 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%.
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
EXPLAINpokazuje decyzje dotyczące dostępu, co umożliwia ich analizę pod kątem optymalizacji. - Zapisy w MaxCompute: polecenia
CREATE TABLEiINSERTteraz 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.
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.
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.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
TIMESTAMPTZiDATETIMEmogą 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
- Te ciche błędy w wyszukiwaniu w systemach RAG w produkcji i sposoby ich naprawy — Od rozmiaru i nakładania się fragmentów tekstu po wyszukiwanie hybrydowe, RRF, ponowną klasyfikację, wybór wektorów reprezentujących tekst oraz oceny CI: dziesięć błędów w procesie wyszukiwania powodujących błędne odpowiedzi w systemach RAG i sposoby ich rozwiązania.
- Mierzenie efektywności procesu RAG: wskaźnik trafień, MRR i wyszukiwanie hybrydowe — Jak stworzyć zestaw prawdziwych odpowiedzi, ocenić skuteczność wyszukiwania za pomocą wskaźnika trafień i MRR oraz porównać wyszukiwanie tekstowe, wektorowe i hybrydowe na 360 pytań.