Skip to content

v0.4.0 — two runtime profiles

Choose a tag to compare

@youndie youndie released this 25 Aug 18:19
· 40 commits to main since this release

An S3-compatible object store on the JVM: one process, one node, one disk. Objects live as files
and the whole key index lives in memory, so what the store promises about capacity is a published
number rather than a surprise.

The niche is two-sided and both sides are the same server: a store you run on one machine behind
your own TLS terminator, and an S3 endpoint you start inside a test — where the alternative on
the JVM today is a mock, and a mock answers what it was told to answer.

What is new in v0.4.0

The distribution now carries two runtime profiles, and the chart picks between them by name.

The heap is what the object ceiling is derived from, so a deployment running a different heap is
running a different promise — not a tuning knob. heapProfile: default|small in the chart chooses
one of two whole start scripts:

default small
heap -Xmx512M -Xmx128M
object ceiling 399 215 99 816
memory floor the chart asks for 768Mi 320Mi
a 300 MiB object, served 455 ms 132 ms

The reason the small profile reads faster is not the heap itself: the heap and the page cache come
out of the same cgroup, and this read path is transferTo from a hot file. Measured over a
hundred hours of load, the JVM committed 448 MiB to hold nine of live data and the page cache gave
up exactly that much. Both memory floors are measured under load with the index at that profile's
own ceiling — 576Mi survives and 512Mi is OOM-killed on the default profile, 224Mi and 192Mi on the
small one — and each chart floor is the measured one plus a third.

The lever that looks free — raising limits.memory and keeping the heap — does nothing on a node
without spare memory, because a cgroup limit is a ceiling and not a reservation. That was measured
too, and it is why the profile exists as a choice.

Nothing else moved. Installing with your existing values gives exactly what v0.3.1 gave, and the
bochka-embedded ABI has not changed since v0.2.0.

Where it stands

518 of 744 ceph/s3-tests as it ships, 533 of 744 with BOCHKA_ANONYMOUS=1 — both
measured, at suite revision 5522d1c, and every remaining failure is classified with a reason.

Beside that: four other people's clients over a real socket (aws-cli, boto3, mc, rclone),
all four body framings including the one aws-cli only sends over TLS, a crash test that kills the
JVM with SIGKILL mid-write and demands that everything the log admitted to still reads back, and
a chart harness that installs into a real kubelet rather than rendering YAML.

Install

docker run -d --name bochka -u 1000:1000 \
  -v /srv/bochka:/var/lib/bochka -p 127.0.0.1:9000:9000 \
  -e BOCHKA_KEYS='youraccesskey:yoursecretkey' \
  ghcr.io/youndie/bochka:v0.4.0
helm install bochka oci://ghcr.io/youndie/charts/bochka --version 0.3.0 \
  --set auth.keys[0].id=youraccesskey --set auth.keys[0].secret=yoursecretkey
repositories { maven("https://reposilite.kotlin.website/snapshots") }
dependencies { testImplementation("io.github.youndie.bochka:bochka-embedded:0.4.0") }

Bound to the loopback on purpose: TLS terminates outside the process, and
deploy/ has the configuration and the reason.

What it is not

Not a cluster: no replication, no failover, one volume. Not unbounded in object count — the ceiling
is in the table above and a store that reaches it refuses new keys with 507 InsufficientStorage
rather than degrading. Not a TLS terminator. The full list, with what would change each answer, is
in the README.