Skip to content

v0.9.0

Choose a tag to compare

@merlimat merlimat released this 14 Jun 03:38
· 34 commits to main since this release
ce8143e

Oxia Java Client 0.9.0 is a performance-focused release: the hot write and read paths shed allocations and lock contention, batch assembly moves from two dedicated threads per shard to a small shared pool, and the client now applies end-to-end backpressure by bounding the total size of pending operations.

Compatibility

  • The client now caps the total size of accepted-but-incomplete operations at 256 MiB by default (#348). When the cap is reached, further operations block the calling thread until enough pending operations complete. Use OxiaClientBuilder.maxPendingBytes(0) to restore the previous unbounded behavior.
  • Batches are now assembled by a shared oxia-batcher thread pool (1 thread by default, configurable with OxiaClientBuilder.batchingThreads(int)) instead of two dedicated threads per shard (#349). Batching semantics — pipelined sends, per-shard ordering, flush-when-idle — are unchanged.
  • OxiaClientBuilder.batchLinger(...) is deprecated for removal: batching has been adaptive for a while, so the setting has no effect (#346). Configuration files that contain a batchLinger entry keep loading. The perf tool's --batch-linger-ms flag was removed.
  • There are no breaking API changes: code built against 0.8.0 keeps compiling and running.

Requirements

  • Java 17 is required (unchanged).
  • No data migration is required.
  • No configuration change is required.

Public API Changes

  • New OxiaClientBuilder.maxPendingBytes(long): bounds the total size of pending operations; default 256 MiB, 0 disables the limit (#348).
  • New OxiaClientBuilder.batchingThreads(int): number of shared batch-assembly threads; default 1 (#349).
  • OxiaClientBuilder.batchLinger(Duration) is deprecated for removal (#346).

Performance Improvements

  • Batch assembly runs on a small shared pool instead of two platform threads per shard, removing hundreds of idle threads and tens of MB of preallocated arrays at high shard counts (#349).
  • Sync range scans use gRPC manual flow control: the transport thread no longer parks waiting for the application to consume each record, buffering stays bounded to one in-flight response per shard, and close() cancels the underlying streams (#342).
  • Key-to-shard routing is an allocation-free xxh3 hash plus a binary search over the hash ranges, replacing a linear scan with per-call stream and boxing allocations (#343).
  • The key comparator no longer allocates substrings per path segment: sorting 100k multi-segment keys drops from 187 ms / 1.21 GB allocated to 90 ms / 862 KB (#347).
  • Write operations no longer materialize UTF-8 byte arrays just to measure key sizes (#344).
  • Read batch requests are built in place instead of deep-copying a temporary request per get (#351).
  • Session lookups on the ephemeral-put path take a lock-free fast path when the session already exists, instead of serializing all writers of a shard (#350).
  • Each put schedules one timeout task instead of two (#341).
  • Notifications are dispatched with a plain loop instead of a per-event parallelStream (#345).

Metrics Changes

  • None.

Operational Changes

  • Dependency updates: log4j-core pinned to a fixed version across all build configurations, OpenTelemetry upgraded to 1.63.0 for CVE-2026-45292 (#352).

Changes Since v0.8.0

  • feat: limit the total size of the pending operations (#348)
  • perf: assemble batches on shared threads instead of one thread per shard (#349)
  • perf: lock-free fast path for the session lookup (#350)
  • perf: build read batch requests in place (#351)
  • perf: rewrite CompareWithSlash without substring allocations, add JMH benchmarks module (#347)
  • perf: dispatch notifications with a plain loop instead of parallelStream (#345)
  • perf: compute UTF-8 key sizes without materializing the bytes (#344)
  • perf: route keys to shards with a binary search over the hash ranges (#343)
  • perf: switch sync range-scan iterator to gRPC manual flow control (#342)
  • perf: schedule a single timeout task per put operation (#341)
  • api: deprecate batchLinger, which has no effect (#346)
  • build: fix Dependabot alerts for log4j-core and opentelemetry-api (#352)
  • chore: release 0.9.0 (#353)

Full Changelog: v0.8.0...v0.9.0