Skip to content

perfcached 0.6.2

Choose a tag to compare

@Lt-Flash Lt-Flash released this 13 Oct 06: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.

This page covers 0.6.2 and 0.6.1, which has no page of its own. The ChangeLog has the detail.

No packages are attached to this release. Build it from the source archive below (README, Install: a C compiler, make and libsodium), or stay on the 0.6.0 packages.

A rolling restart from 0.4.5. One thing to do first, from 0.6.0 or earlier: a read-through collection's password moved from [secrets] upstream into the collection, as upstream_password. 0.6.1 and later refuse the old key, and perfcached -C says where it goes.

0.6.2

Write-through to Redis

  • upstream_writes = through sends every client write on a read-through collection to the upstream's master first: the listed upstream whose ROLE says master, or, when two say so, the one the serving replicas follow. The written keys are read back in the same round trip, so the fleet then holds what Redis holds: a value with Redis's expiry, a deleted key as gone, and a list, set, sorted set or stream left to Redis. The client gets Redis's own reply.
  • With no master reachable every write is refused (the critical alert write.<collection>) and reads go on. The master is looked for at start and after a failure, backing off to every 10 s; ROLE is asked every 10 s, and RedisJSON every 60 s while it is missing - never once per key.
  • At the RESP door every write command is forwarded as sent; perfcached's EX on JSON.SET becomes an EXPIRE after it. EVAL, EVALSHA and RL.HIT write only this node and are refused. At the native door: set, setnx, setxx, del, expire, jset and jdel.
  • JSON writes need RedisJSON on the master. Without it they are refused here, with no round trip, and a warning alert says so.
  • Pub/sub is not bridged: Redis's channels and the fleet's stay separate.

Commands perfcached does not know

  • Under through, upstream_unknown = pass (the default) lets Redis classify a command perfcached does not implement (COMMAND INFO, COMMAND GETKEYS): a write goes to the master with its keys read back, a read to a serving replica. The reply is relayed byte for byte, up to upstream_pass_max_kb (1024); a larger one is refused, never cut.
  • Refused whatever Redis says: admin, dangerous, blocking, pub/sub, transaction and script commands, another database, writes that name no key, and keys outside upstream_prefixes. refuse keeps "unknown command".

Stats and the status page

  • /stats upstream.write_through has the target, its state, RedisJSON, and the writes by outcome and by command as sent to Redis, with the last eight errors in Redis's own words and the slowest write in five minutes. The page shows them under the collection, grouped with its upstreams.
  • A command that waited for an upstream (a read-through miss, a write-through write) is counted once in the commands table; it was counted twice.
  • The slow log and the alerts fold like the commands table, and the commands table sorts by calls or by its slowest call. Every card holds its content at desktop widths.

The HTTP door

  • A peer refused by http_allow can no longer stall a worker. A silent refused connection held a worker for 200 ms, and one sending a byte every 150 ms held it indefinitely; the 403 is now sent and the socket drained without waiting. Every release from 0.3.0 has this, so update a node whose HTTP port is reachable from outside its allow-list.
  • http_rate (20 requests a second per client address, loopback exempt) answers a faster address 429 Too Many Requests. http_cache_ms (1000) builds /stats and /metrics at most once in that long, however many pages are open.
  • A browser can open a page behind [secrets] http: the 401 asks for its login, and Basic with the token as the password (any user name) is accepted beside Bearer.

0.6.1

Alert mail a person can read

  • The subject is <STATE>: <title> on <host> - CRITICAL, WARNING, INFO or RESOLVED - in at most 78 characters, and From names the host. Each mail has a plain and an HTML part: per alert what happened, its status, when it started, what the node does by itself and what to do. A resolve answers the problem's first mail.
  • Levels say how soon to act: a clean start is info (not mailed at the default level), an unclean start and a WAL loss are warnings, a third loss within an hour and a heal stuck for ten minutes are critical.

Several Redis upstreams for one collection

  • Up to eight. upstream_role = replica reads only from servers whose ROLE says replica (upstream_master_fallback = yes lets the master serve while none does). upstream_mode = balance sends each fetch to the one with the fewest in flight; failover keeps one active, the next taking over when it stops and the primary returning after upstream_preempt_hold_s. Each upstream has its own tracking.
  • The upstream password belongs to the collection, upstream_password, so one perfcached can front several Redis servers.
  • No ring of read-throughs: an upstream that is itself a perfcached is refused unless upstream_allow_perfcached = yes, and then a key crosses one perfcached hop at most.

I/O

  • The page has an io card: the backend running (io_uring or epoll), a fallback in amber with its reason, and the busiest worker's share of the last five minutes.
  • A node on epoll whose busiest worker stays over [alerts] epoll_busy_pct (80) for five minutes is warned, with the change to make.
  • A pub/sub subscriber that keeps up is no longer closed as slow when its worker drains a large backlog of big messages on io_uring: a drain stops at 1 MB as well as at 1,024 messages.