Skip to content

Redis Key Naming Convention

Scope: the Redis instance shared by CubeMaster and CubeProxy; CubeAPI must follow this convention when it onboards in the future.

1. Overview

Multiple CubeSandbox services (CubeMaster, CubeProxy, and potentially CubeAPI in the future) share the same Redis instance. To prevent key collisions, accidental deletes/overwrites, and to enable SCAN-based governance and auditing, every Redis key must follow a unified namespace convention.

Core principles:

  • Bare entity IDs as top-level keys are forbidden.
  • All keys must be produced by each service's unified key-builder module; scattered literal concatenation is forbidden.
  • Cross-service shared data uses the shared namespace; changes require multi-side coordination.

2. Naming format

cube:{ver}:{scope}:{resource}[:{sub}...]:{id}
SegmentMeaningValues
cubeFixed product prefix, prevents collisions with third-party keysconstant cube
verSchema version; bump on breaking value-structure changescurrently v1
scopeOwnership namespace (by ownership/sharing, not by language)see §3
resource[:sub]Business entity, lowercase, colon-separatede.g. node:metric, instance:info
idEntity ID (sandboxID, nodeID, taskID, etc.)must not be omitted

Example: cube:v1:shared:sandbox:proxy:7c8fbcd45ffe450fb8f7fb223ad45507

3. Scope enumeration

scopeMeaningReaders / writers
masterCubeMaster-private dataCubeMaster only
proxyCubeProxy-private dataCubeProxy only
apiCubeAPI-private data (reserved)CubeAPI only
sharedCross-service contractmultiple services

Keys under shared are cross-service contracts: adding, renaming, or changing the data structure requires all readers and writers to change in lockstep; no single service may change unilaterally.

4. Mandatory rules

  1. Centralized construction: CubeMaster uses CubeMaster/pkg/base/rediskey/rediskey.go; CubeProxy uses CubeProxy/lua/redis_keys.lua. When adding a new key, register a builder there first (or in the CubeAPI equivalent), then call it from business code.
  2. Explicit TTL: cache keys must set a TTL; keys whose lifecycle is managed by an explicit business DEL (e.g. sandbox routes) default to no TTL. A fallback TTL is only allowed when there is a refresh path, or when the TTL exceeds the entity's maximum lifetime.
  3. Reserved semantic segments (use when adding locks, idempotency keys, etc.):
    • Distributed lock: cube:v1:{scope}:lock:{resource}:{id}
    • Idempotency key: cube:v1:{scope}:idemp:{resource}:{id}
  4. Governance friendly: keys of the same kind must be enumerable via SCAN cube:v1:{scope}:{resource}:*; do not embed a variable ID in the middle of the prefix in a way that breaks bulk matching.
  5. Version evolution: bump ver only on breaking value-structure changes; adding Hash fields or extending fields does not require a bump.
  6. ID safety: the id segment must not contain unescaped :; validate entity IDs before construction to prevent key injection and unauthorized reads.

5. Registered key catalog

The following are the standard keys currently registered in the system (v1). New business keys must be added here.

MeaningKey patternTypescopeWriterReaderTTL
Node resource metricscube:v1:master:node:metric:{nodeID}HashmasterCubeMasterCubeMasterrefresh-style (heartbeat, default 600s)
Sandbox proxy routecube:v1:shared:sandbox:proxy:{sandboxID}HashsharedCubeMasterCubeProxynone (lifecycle via DEL)
Instance infocube:v1:master:instance:info:{insID}HashmasterCubeMasterCubeMasternone
Describe task resultcube:v1:master:task:describe:{taskID}HashmasterCubeMasterCubeMaster / external86400s (configurable)
Instance metadata (reserved)cube:v1:master:instance:meta:{...}string / listmasterCubeMasterCubeMasternone
Sandbox lifecycle registrycube:v1:shared:sandbox:lifecycle:metaHashsharedCubeMastercube-proxy-sidecarnone (lifecycle via HDEL)
Sandbox lifecycle eventscube:v1:shared:sandbox:lifecycle:eventsStreamsharedCubeMastercube-proxy-sidecarMAXLEN ~ 100000
Sandbox lifecycle statecube:v1:shared:sandbox:lifecycle:state:{sandboxID}Stringsharedcube-proxy-sidecarcube-proxy-sidecarSET TTL (default 60s)

5.1 Hash field conventions

node:metric (node metrics)

fieldMeaning
ins_idNode ID
update_atMetric update time
quota_cpu_usageCPU quota usage (milli-cpu)
quota_mem_mb_usageMemory quota usage (MB)
mvm_numVM count
nic_queuesNIC queue count
data_disk_usage_per / storage_disk_usage_per / sys_disk_usage_perDisk usage (%)

sandbox:proxy (sandbox route, cross-service contract)

fieldMeaning
HostIPHost IP
SandboxIPSandbox internal IP (optional)
CreatedAtCreation time
{containerPort}Container port → host mapped port (dynamic field)

instance:info (instance info)

See the redis tags on InstanceInfoMap in CubeMaster/pkg/base/types/redis.go.

task:describe (async task)

fieldMeaning
task_idTask ID
statusTask status
error_codeError code
error_messageError message

sandbox:lifecycle:meta (sandbox lifecycle registry, cross-service contract)

fieldMeaning
{sandboxID}JSON-encoded SandboxLifecycleMeta (see CubeMaster/pkg/lifecycle/schema.go)

sandbox:lifecycle:state (pause/resume coordination)

valueMeaning
runningSandbox is active
pausingPause transition in progress
pausedSandbox is paused
resumingResume transition in progress

6. TTL policy

Key typePolicyNotes
node:metricRefresh-style TTLEXPIRE after each heartbeat write (default 600s); live nodes keep refreshing, offline nodes auto-expire
sandbox:proxyNo TTLWritten once at sandbox creation with no refresh path; lifecycle managed by CubeMaster DEL on teardown. Do not set a TTL shorter than the max sandbox lifetime
task:describeFixed TTLEXPIRE on write, default 86400s (describe_task_expire_time)
instance:info / instance:metaNo TTLManaged per instance lifecycle; may be augmented later
sandbox:lifecycle:metaNo TTLWritten on sandbox create, HDEL on destroy
sandbox:lifecycle:eventsMAXLEN ~Stream trimmed on each XADD (default ~100000)
sandbox:lifecycle:stateSET TTLEX on each write (sidecar default 60s); released on rollback or sandbox delete
Cache keys (future)TTL requiredMust be declared on write and registered in this document

7. Per-service implementation

CubeMaster (Go)

CubeProxy (OpenResty / Lua)

CubeAPI (Rust, reserved)

CubeAPI does not use Redis today. If it onboards in the future, it must follow:

  • Private data: cube:v1:api:{resource}:{id}
    • Session: cube:v1:api:session:{token}
    • Rate limit: cube:v1:api:ratelimit:{apikey}
    • Config cache: cube:v1:api:setting:{setting_key}
  • Shared data: reuse cube:v1:shared:*; never create prefix-less keys
  • Implement a key-builder module equivalent to CubeMaster / CubeProxy

8. Adding a new key

  1. Register the key pattern, data type, scope, readers/writers, and TTL in §5 of this document.
  2. Add a builder function in the service's key-builder module (Go rediskey / Lua redis_keys).
  3. If shared scope, update all readers and writers together and add integration tests.
  4. Confirm SCAN cube:v1:{scope}:{resource}:* enumerates correctly.

Appendix: Legacy key crosswalk

The table below maps pre-standardization keys to the keys defined in this convention. Use it when investigating legacy data, logs, or ops scripts. New code must use only the standard keys on the right.

MeaningLegacy key (deprecated)Standard keyTypescope
Node resource metrics{nodeID} (bare ID)cube:v1:master:node:metric:{nodeID}Hashmaster
Sandbox proxy routebypass_host_proxy:{sandboxID}cube:v1:shared:sandbox:proxy:{sandboxID}Hashshared
Instance infocube_instance_info:{insID}cube:v1:master:instance:info:{insID}Hashmaster
Describe task resultdescribetask:{taskID}cube:v1:master:task:describe:{taskID}Hashmaster
Instance metadatainstance:metadata:{...}cube:v1:master:instance:meta:{...}string / listmaster