Skip to content

perfcached 0.5.5

Choose a tag to compare

@Lt-Flash Lt-Flash released this 06 Oct 23:36
· 1 commit to master since this release

perfcached - found fast, kept safe

A multithreaded, self-clustering cache for Linux, with its own encrypted protocols and a Redis-compatible door. New here? Start with the README.

A rolling restart. 0.5.5 joins a 0.4.5 or later fleet one node at a time: restart the members first and the master last, and read the fleet between nodes. The storage formats, the wire epoch and libperfd (0.4.0) are unchanged. Read-through is off unless a collection names an upstream, so a fleet that does not use it runs exactly as before.

Read-through: take a keyspace over from Redis

A collection can name an UPSTREAM - Redis, Valkey or another perfcached - that a node reads on a local miss and never writes. Move the clients to perfcached and it answers from its own collection; a key it does not hold yet is read from the upstream the first time anyone asks. No big-bang copy, and no way back into Redis. The GUIDE has the whole story; in short:

[secrets]
upstream = <the password perfcached sends to the upstream>

[collection 0]
upstream = redis://reader@10.0.0.12:6379/0
upstream_prefixes = tok:*, cid:*
  • One way only. perfcached sends the upstream the handshake and reads - TYPE, PTTL, GET, HGETALL, JSON.GET, and SCAN for the drain sweep - and nothing else. Point it at a replica, as a user that can only read; the GUIDE has the ACL line.
  • Only the keys you list fall through: upstream_prefixes is required (Redis glob patterns, * for all of them).
  • Strings, hashes and RedisJSON documents are carried, with the upstream's TTL. A list, set, sorted set or stream answers WRONGTYPE and is not stored.
  • A read waits for one fetch and answers from a node-local copy; concurrent misses for one key cause one fetch. A change - INCR, HSET, JSON.* path writes, DEL, EXPIRE and the rest, on either door - first takes the upstream's value over as a real write (logged, replicated), then runs: INCR of an upstream 41 answers 42. A plain overwrite (SET) does not wait.
  • A key the fleet has written or deleted never reads through again. perfcached cannot delete the upstream's copy, so a companion collection, <name>.nofall, created and replicated with the collection, remembers it for as long as the upstream's copy may live.
  • The upstream's own changes reach perfcached through Redis client tracking (RESP3, Redis 6 or later): a key the upstream changes, deletes or expires drops out of the fetched copies at once. Losing a tracking connection drops every fetched copy.
  • When the upstream fails, a read answers an error (or a miss, with upstream_on_error = miss); a change always answers the error - it never runs on a guess.
  • The drain sweep finishes the move: perfcli -E <enable> updrain <collection> scans the upstream and takes over every key the fleet does not already hold, has not written and has not deleted, at most upstream_drain_rate keys a second (5000). Run it on one node; the writes replicate. Then remove upstream and upstream_prefixes on every node and restart them.
  • stats carries an upstream block per collection - fetches and fills by type, promotions, invalidations, errors, timeouts, fetch time, and the drain sweep's progress.

Tested against a scripted upstream that fails the run on any write - on one node and in a three-node eager fleet - and against redis 8.10.2 as a read-only ACL user, where MONITOR shows perfcached sending only the handshake and reads and ACL LOG stays empty (tools/redis-interop.sh, a throwaway container).

Known

  • Read-through: KEYS and SCAN see only what the collection holds; proxy, shard and spread collections refuse an upstream; and in a cluster, a read on another node in the instant before a change reaches it may answer the upstream's older value - the same window in which an eager fleet without an upstream would answer a miss.
  • No sorted sets, lists or streams yet. Keys hold strings, counters, JSON documents or hashes (a hash is one value, under 58,000 bytes).
  • discovery = unicast (clouds, Kubernetes) is tested in lab network namespaces that drop IP fragments and block UDP, not yet in a real cloud deployment. spread mode has not yet carried production traffic.
  • In eager mode a delete made on one side of a network partition can be undone when the partition heals.

Packages

Debian 12 and 13, Ubuntu 20.04 and 24.04, amd64, in both editions:

  • perfcached - the clustered daemon, every cluster mode.
  • perfcached-standalone - the single-node edition, built from the same tree without the cluster code; a [cluster] section in its config is refused rather than ignored. Read-through works in both.

The two install the same files under the same names and replace each other, so moving between editions is one apt install. Each package was built in a clean container and install-checked in a second one: the version and revision, the edition perfcached -V reports, the shipped config passing perfcached -C, the systemd unit, and for the standalone package that a [cluster] section is refused and that installing perfcached over it swaps the edition.