v0.4.0 — two runtime profiles
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-testsas it ships, 533 of 744 withBOCHKA_ANONYMOUS=1— both
measured, at suite revision5522d1c, 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.0helm install bochka oci://ghcr.io/youndie/charts/bochka --version 0.3.0 \
--set auth.keys[0].id=youraccesskey --set auth.keys[0].secret=yoursecretkeyrepositories { 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.