mithril

Configuration

mithril <conf-file> [--<key> <value>]... — the file holds key value lines with # comments; every key can also be given on the command line as --key value, which wins over the file. Unknown keys are startup errors. See mithril.conf.sample.

key type default meaning
bind address 0.0.0.0 listen address (IPv4 or IPv6 literal); one socket, owned by the acceptor thread
port u16 7979 listen port
announce-addr addr:port bind:port address the cluster emulation advertises to clients; must be externally routable when bind is a wildcard
bootstrap list required comma-separated seed nodes of the backing cluster
worker-threads int CPU count worker threads, one runtime each
maxclients int 10000 client connection cap, enforced at accept
backend-conns 1..512 1 shared pipelined connections per node per worker, per database in use (a session on SELECT n opens its own pool to each node; the exclusive-connection cap for blocking and WATCH stays per node across databases)
backend-sharding yes/no/auto auto yes: one process-wide connection per node per database in use, owned by the worker its address hashes to, which deepens backend pipelines for unpipelined workloads; no: every request stays on its worker’s own connections; auto (the default): an unpipelined session uses the shared pipe, a pipelining one its worker’s connections, and the whole proxy moves to the pipes where a measured experiment shows it runs faster (the rule is in architecture.md; a session switches only while nothing is in flight; with the reply cache, only sessions on the shared pipes fill it while every session reads it; a proxy with one worker and one connection per node has nothing to share and runs auto as no)
reply-cache yes/no no worker-local GET/MGET reply cache; the servers track the keys the proxy caches (redirected opt-in RESP3 tracking) and invalidate them on change, so hits skip the backend round trip and a session reads its own writes
reply-cache-max-bytes bytes 64mb per-worker budget for the two cache generations; the live generation holds half of it, so a worker’s hot set must fit in half the budget to keep hitting (see operations.md for sizing and the RSS to expect)
reply-cache-max-age-secs 1..3600 10 staleness backstop for missed invalidations; entries older than this never serve
requirepass string empty password of the default ACL user; empty leaves it passwordless (nopass)
user line none an ACL user, repeatable: user <name> <rules...> in Redis ACL SETUSER syntax (user app on >secret ~app:* &* -@all +@read +@string); applied at startup, editable afterwards with ACL SETUSER
acl-pubsub-default enum allchannels channels a new or reset user starts with: allchannels or resetchannels; changeable at runtime via CONFIG SET
acllog-max-len 0..1000000 128 entries kept by ACL LOG; changeable at runtime via CONFIG SET
slowlog-log-slower-than µs, -1 off -1 off by default; set to a microsecond threshold and a command whose reply took at least this long, from being read to being queued for the client, enters the slow log (0 keeps every command; Redis defaults to 10000); changeable at runtime via CONFIG SET
slowlog-max-len 0..1000000 128 entries the slow log keeps, newest first; changeable at runtime via CONFIG SET
backend-auth-user string empty username sent to backends (AUTH user pass)
backend-auth-pass string empty password sent to backends
slave-mode enum off replica read splitting: off, master_readwrite, master_writeonly
placement enum least-loaded new-connection placement: least-loaded (avoid busy workers; decays to rotation under even load) or round-robin
tcp-keepalive seconds 300 keepalive on backend connections
query-buffer-limit bytes 1gb per-client input cap; accepts kb/mb/gb suffixes; also bounds queued MULTI bytes
topology-refresh-secs 1..3600 15 periodic CLUSTER NODES refresh; redirects trigger one immediately (debounced 100ms)
loglevel enum notice debug, verbose, notice, warning; changeable at runtime via CONFIG SET

Replica read splitting

With slave-mode master_writeonly, read-only commands go to a replica of the owning master (uniformly among replicas); with master_readwrite the master participates in the draw too. Writes, EVAL, transactions and blocking commands always run on the master. Replica reads trade read-your-write consistency for throughput, as with any replica routing.