* chore: add histogram decode Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: add convert func Signed-off-by: shuiyisong <xixing.sys@gmail.com> * feat: implement native histogram persistency Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: add test Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: refactor Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: add README for v2 Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix CR issues Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: cr issue Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: cr issue Signed-off-by: shuiyisong <xixing.sys@gmail.com> * feat: implement metric engine Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: add comments Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix test Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: store nh in one struct Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix CR issues Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix CR issues Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix CR issues Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix CR issues Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix test Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: cr issue Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix CR issues and add feature gate Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix CR issues Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: add config option Signed-off-by: shuiyisong <xixing.sys@gmail.com> --------- Signed-off-by: shuiyisong <xixing.sys@gmail.com>
4.4 KiB
metric-engine — Agent & Contributor Guide
Navigation aid for src/metric-engine. Keep it short and point to code. Paths
are relative to the repo root.
Repo-wide rules that apply here: .agents/architecture-invariants.md.
What this crate does
The Metric Engine is optimized for Prometheus-style workloads with a huge number
of small tables. Many logical regions (one per metric table) share a single
physical pair of Mito2 regions: a data region and a metadata region. Rows
are multiplexed with metric-engine internal identity: dense primary-key mode
injects __table_id and __tsid, while the default sparse mode encodes them
into __primary_key. Reads still add a logical-table filter before forwarding
to the physical data region. It implements RegionEngine and delegates all real
storage to mito2.
The architecture is documented at the top of src/metric-engine/src/lib.rs.
Module map
| Module | Path | Purpose |
|---|---|---|
engine |
src/metric-engine/src/engine.rs, src/metric-engine/src/engine/ |
MetricEngine (RegionEngine impl) and per-op handlers (create.rs, put.rs, read.rs, alter.rs, drop.rs, ...) |
metadata_region |
src/metric-engine/src/metadata_region.rs |
K-V over a Mito2 region storing logical table/column metadata, with an LRU cache |
data_region |
src/metric-engine/src/data_region.rs |
Wraps the Mito2 data region; forwards writes and manages physical columns |
row_modifier |
src/metric-engine/src/row_modifier.rs |
Rewrites incoming rows for dense or sparse primary-key encoding |
batch_modifier |
src/metric-engine/src/batch_modifier.rs |
RecordBatch-level TSID computation and sparse primary-key encoding |
state |
src/metric-engine/src/engine/state.rs |
In-memory cache of physical columns and logical column metadata |
repeated_task |
src/metric-engine/src/repeated_task.rs |
Periodic metadata-region flush task |
utils |
src/metric-engine/src/utils.rs |
RegionId conversions (data vs metadata group), manifest encoding |
config |
src/metric-engine/src/config.rs |
EngineConfig (metadata flush interval, sparse PK) |
test_util |
src/metric-engine/src/test_util.rs |
TestEnv building the Mito2 + Metric stack |
Write path
MetricEngine::handle_request(Put) (engine/put.rs) rejects direct writes to a
physical region, resolves the physical region for the logical id, loads logical
columns from metadata_region, then row_modifier rewrites the rows according
to the data region's primary-key encoding and forwards the request to the Mito2
data region.
Read path
MetricEngine::handle_query (engine/read.rs): a query against a logical region
is rewritten to add a __table_id == <logical_id> filter and forwarded to the
Mito2 data region. Queries against a physical region pass straight through.
Public surface
- Entry:
MetricEngineinsrc/metric-engine/src/engine.rs, built viatry_new(mito, config). - Trait:
impl RegionEngine for MetricEngine(name ="metric"). - Depends on
mito2,store-api, andmito-codec(sparse primary key codec).
When you change X, also touch Y
- Reserved column ids / names (
__tsid,__table_id,__primary_key): seestore-api's metric engine consts; keep them in sync withengine.rs. - Metadata K-V encoding (
metadata_region.rs): changes the on-disk metadata layout. - RegionId group mapping (
utils.rs): data vs metadata region derivation. - Physical column rules (
engine/alter/): ordinary metric fields stay on logical tables; shared physical field adds are only for the native histogram Struct field.
Testing
cargo nextest run -p metric-engine
TestEnv in test_util.rs gives you mito() and metric() handles.
Gotchas
- Physical vs logical region confusion: physical regions reject direct user writes; operate on logical region ids.
- TSID must be stable for the same tag set — it is a hash over sorted tag names
- values and may be stored in
__tsidor encoded into__primary_key.
- values and may be stored in
- Metadata is cached (LRU with a TTL); after an alter, stale reads are possible until invalidation/expiry.
- Always convert ids via
utils::to_data_region_id/to_metadata_region_id.
Maintenance contract
Update this file when you change the logical/physical region model, the injected columns, the metadata encoding, or the public engine entry points.