Databases 23 min read

Apache Doris 2.0 New Features: High‑Concurrency Data Serving Optimizations

Apache Doris 2.0 introduces a suite of high‑concurrency data‑serving enhancements—including row‑store format, partition‑bucket pruning, advanced indexing, materialized views, runtime filters, TOPN optimization, short‑circuit point‑query paths, prepared statements, and row cache—enabling single‑node tens of thousands QPS and dramatically reducing query latency.

Big Data Technology & Architecture
Big Data Technology & Architecture
Big Data Technology & Architecture
Apache Doris 2.0 New Features: High‑Concurrency Data Serving Optimizations

As user scale expands rapidly, more users employ Apache Doris to build unified internal analytics platforms. This creates two demands: the system must handle larger data volumes and higher concurrency, and it must support diverse analytical workloads such as recommendation, risk control, profiling, and IoT, with Data Serving being a representative scenario.

Data Serving refers to providing data‑access services where the typical query pattern is a key‑based lookup of one or a few rows (e.g., order detail, product detail, logistics status, transaction detail, user info, user profile attributes, etc.). Unlike large‑scale ad‑hoc scans, Data Serving requires ultra‑low latency (milliseconds) and must sustain extremely high concurrency.

Historically, point‑query workloads were handled by separate components (e.g., OLAP columnar stores for scans, HBase or Redis for key lookups), leading to redundant storage and high maintenance cost. Apache Doris now integrates point‑query capabilities into the same engine.

How to Handle High‑Concurrency Queries?

Doris has always excelled at high concurrency. To further improve point‑query performance, the following optimizations are introduced in version 2.0:

Partition‑Bucket Pruning

Doris uses two‑level partitioning: first‑level Partition (often by time) and second‑level Bucket (hash‑distributed). Proper partition‑bucket design can dramatically reduce scanned data. Example query:

select * from user_table where id = 5122 and create_date = '2022-01-01'

By using create_time as the partition key and id as the bucket key with 10 buckets, only one partition and one bucket need to be read, minimizing scan volume and latency.

Indexing

Doris provides several index types:

Sorted (prefix sparse) index : a sparse index created every 1024 rows on sorted columns, allowing fast location of the start row.

ZoneMap index : stores min/max values per page/segment, enabling quick elimination of irrelevant rows.

Secondary indexes (manual): Bloom Filter, Bitmap, Inverted, NGram Bloom Filter (available from 2.0).

Materialized Views

Materialized views pre‑compute and persist results of defined SQL statements. When a query can be satisfied by a materialized view, execution is much faster and reduces on‑the‑fly computation.

Runtime Filters

During a join, Doris builds a hash table on the build side and simultaneously generates a runtime filter (e.g., min/max, IN) for the probe side. This filter is pushed down to early scan nodes, cutting down the amount of data transferred and processed.

TOPN Optimization

For queries that need only the top‑N rows (e.g., recent 100 records, highest price), Doris reads only the sorting columns, keeps a heap of size N, and pushes the current bound down to the scanner, drastically reducing I/O, CPU, and memory usage.

Apache Doris 2.0 New Features

Row‑Store Format

To better serve point‑lookup workloads, Doris adds a row‑store format where an entire row is encoded (using JSONB) into a hidden column DORIS_ROW_STORE_COL. Users enable it via the table property: "store_row_column" = "true" Benefits include flexible schema evolution, faster row‑level reads, and reduced storage footprint.

Short‑Circuit Point‑Query Path

For simple primary‑key lookups, Doris bypasses the full SQL parser‑optimizer‑plan pipeline and directly executes a lightweight RPC to the storage engine. The RPC messages are:

message PTabletKeyLookupRequest {
    required int64 tablet_id = 1;
    repeated KeyTuple key_tuples = 2;
    optional Descriptor desc_tbl = 4;
    optional ExprList  output_expr = 5;
}

message PTabletKeyLookupResponse {
    required PStatus status = 1;
    optional bytes row_batch = 5;
    optional bool empty_batch = 6;
}

rpc tablet_fetch_data(PTabletKeyLookupRequest) returns (PTabletKeyLookupResponse);

The request carries the tablet ID and primary‑key values (e.g., ['123','456']). The backend locates the row via the primary‑key index, checks the delete bitmap, and reads the hidden row‑store column to return the full row.

PreparedStatement Optimization

To reduce CPU cost of repeated parsing, Doris supports MySQL‑compatible prepared statements. The server caches the parsed SQL and expression tree in a session hashmap, and subsequent executions reuse the cached plan, achieving >4× performance gains for point queries.

Example JDBC usage:

url = jdbc:mysql://127.0.0.1:9030/ycsb?useServerPrepStmts=true
PreparedStatement readStatement = conn.prepareStatement("select * from tbl_point_query where key = ?");
readStatement.setInt(1, 1234);
ResultSet rs = readStatement.executeQuery();
// reuse with a different key
readStatement.setInt(1, 1235);
rs = readStatement.executeQuery();

Row Cache

Doris adds a row‑level LRU cache. When enabled, the hidden row‑store column is cached, allowing point queries to be served from memory instead of disk, yielding tens‑fold speedups. Configuration:

disable_storage_row_cache = false   // enable row cache (default off)
row_cache_mem_limit = 20%           // percentage of memory allocated to row cache

Benchmark

Using the Yahoo! Cloud Serving Benchmark (YCSB) on a single 16‑core, 64 GB machine (1 FE + 3 BE) with 100 M rows (~1 KB each), the following results were observed:

Average query latency reduced by 96% (99‑percentile latency becomes 1/28 of the original).

QPS increased from ~1.4 k to ~30 k (over 20× improvement).

Best Practices

Point‑query optimizations work on tables with a UNIQUE KEY primary key, with enable_unique_key_merge_on_write and light_schema_change enabled. Example table definition:

CREATE TABLE `usertable` (
  `USER_KEY` BIGINT NULL,
  `FIELD0` text NULL,
  `FIELD1` text NULL,
  `FIELD2` text NULL,
  `FIELD3` text NULL
) ENGINE=OLAP
UNIQUE KEY(`USER_KEY`)
DISTRIBUTED BY HASH(`USER_KEY`) BUCKETS 16
PROPERTIES (
  "enable_unique_key_merge_on_write" = "true",
  "light_schema_change" = "true",
  "store_row_column" = "true"
);

After creation, a simple primary‑key query such as select * from usertable where USER_KEY = 12345; will benefit from row‑store, short‑circuit execution, and row cache.

Conclusion

By introducing row‑store format, short‑circuit point‑query paths, prepared statements, and row cache, Apache Doris achieves single‑node tens of thousands QPS for Data Serving, delivering dozens of times performance improvement while still supporting massive OLAP workloads. Combined with its MPP architecture, Doris provides a unified platform that handles both high‑throughput analytical queries and ultra‑low‑latency point lookups under a single stack.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

indexinghigh concurrencyBenchmarkApache DorisRow StoreData Serving
Big Data Technology & Architecture
Written by

Big Data Technology & Architecture

Wang Zhiwu, a big data expert, dedicated to sharing big data technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.