Architecture

July 31, 2026 · View on GitHub

Class hierarchy

hivemind_plugin_manager.database.AbstractDB   (abstract)

        └─ hivemind_redis_database.RedisDB

                ├─ redis.Redis (single-node mode)
                └─ redis.cluster.RedisCluster (cluster mode)

RedisDB auto-detects single-node vs. cluster mode. It tries a CLUSTER INFO command after connecting. If the node reports cluster_enabled:1, RedisDB switches to RedisCluster.

Key schema

Each client record is stored as a set of keys under a configurable prefix (index_prefix, default "client"). In single-node mode:

Key patternTypeContent
<prefix>:client:<id>HashFull client record (all fields).
<prefix>:name:<name>Stringclient_id of the matching record.
<prefix>:api_key:<api_key>Stringclient_id of the matching record.
<prefix>:idx:<id>String"1" (membership sentinel).
<prefix>:countStringInteger count of non-revoked clients.
<prefix>:id_seqStringMonotone ID sequence counter.

Cluster mode with cluster_hash_tag

When cluster_hash_tag is set (recommended for new cluster deployments), all keys embed the tag in braces:

client:{clients}:client:1
client:{clients}:name:alpha
client:{clients}:api_key:alpha-key
client:{clients}:idx:1
client:{clients}:count
client:{clients}:id_seq

The hash tag forces all keys into the same hash slot. This enables RedisCluster.pipeline(transaction=True) for atomic multi-key writes.

RediSearch acceleration

When the RediSearch module is loaded (MODULE LIST returns a module named search), RedisDB creates a secondary FT index over the hash records. It uses FT.SEARCH for search_by_value("name", ...) and search_by_value("api_key", ...).

Without RediSearch, the backend falls back to Redis set-index lookups. Either way, search stays exact-match. RediSearch works as an accelerator, not for full-text or fuzzy queries.

sync()

sync() rebuilds the derived keys (counters, set indexes, RediSearch hash documents) from the authoritative <prefix>:client:<id> hash records. It is a recovery tool, not a transaction boundary. Use it after interrupted writes or manual Redis changes.

Schema migration

hivemind-plugin-manager's AbstractDB.migrate() contract is implemented, but the Redis backend does not track a persistent schema version on disk (there is no SQLite PRAGMA user_version equivalent). Migrations happen at the application level.

For Redis Cluster migrations (moving from the legacy untagged key layout to the cluster_hash_tag layout), use the provided CLI tool:

hivemind-redis-migrate-cluster \
  --config ~/.config/hivemind-core/server.json \
  --target-cluster-hash-tag clients

See cluster_consistency.md for the full migration plan and rollback procedure.

Authoring a database backend plugin

See hivemind-sqlite-database: authoring a plugin for the AbstractDB contract and pyproject.toml entry-point registration pattern. The contract stays the same regardless of the storage technology underneath.


Home · Configuration →