Redis Compatibility
ParticleDB speaks the Redis protocol (RESP2). You can point redis-cli or a Redis
client library (configured for RESP2) at it and use strings, lists, sets, sorted sets, hashes, streams, HyperLogLog,
geo indexes, Pub/Sub and MULTI/EXEC transactions. Every write is logged to the
same write-ahead log as SQL, so Redis keys survive a restart, and SQL can read and
write the same key space.
For the per-command reference, see Redis Commands.
Enable and connect
Section titled “Enable and connect”The Redis listener is on by default on port 6379. It listens on the same
interface as the PostgreSQL listener (--pg-addr, all interfaces by default).
To choose the interface and port explicitly, use --redis-addr:
particledb start --data-dir ~/.particledb/data --redis-addr 127.0.0.1:6379| Flag | What it does |
|---|---|
--redis-addr host:port |
Listen address for the Redis protocol. Default: the --pg-addr interface, port 6379. |
--tls-cert, --tls-key |
Serve TLS on the Redis port (and the other listeners). Plain-text connections are then refused. |
--connection-timeout seconds |
Close idle Redis connections after this many seconds. Default 300; 0 disables it. |
--resp-commit-mode sync|async |
When a write is acknowledged; see Durability. |
redis-cli -p 6379 PING# PONG
# With TLSredis-cli -p 6379 --tls --cacert ca.pem PINGAuthentication
Section titled “Authentication”Authentication is on by default. Until a client authenticates, every command except
AUTH, HELLO, PING and QUIT fails with NOAUTH Authentication required.
Redis users are ParticleDB users: authenticate with a role created in SQL (or the
initial superuser, postgres by default, whose password you set with
--pg-password). Use the two-argument form of AUTH:
redis-cli -p 6379 --user postgres --pass your_password GET greeting127.0.0.1:6379> AUTH postgres your_passwordOK127.0.0.1:6379> AUTH postgres wrong(error) WRONGPASS invalid username-password pair or user is disabled.- The one-argument form
AUTH passwordauthenticates as a user nameddefault, so it only works if you created such a role. - Commands that read or write keys require a superuser role. A non-superuser can
authenticate and run
PING, but its data commands fail withNOPERM permission denied: this command requires superuser privilege. HELLOanswers with server information but does not authenticate: itsAUTHandSETNAMEoptions are ignored. Configure your client to sendAUTH(most clients do this when you give them a user name and password with RESP2).--no-authdisables authentication on every listener; use it only for local development.
Protocol and databases
Section titled “Protocol and databases”- RESP2 only.
HELLO 3is accepted but the server answers in RESP2 (protois2in the reply). Clients that require RESP3 must be configured for RESP2. - One database.
SELECT 0is accepted; any other index returnsERR DB index is out of range.MOVEandSWAPDBare refused. Use key prefixes to separate applications. - No cluster mode. The server reports
cluster_enabled:0; connect with a standalone (non-cluster) client configuration. - Binary safe. Keys, values, members, hash fields, channels and messages can hold any bytes and are returned exactly as sent.
What ships
Section titled “What ships”| Family | Commands |
|---|---|
| Strings | SET (EX, PX, NX, XX), GET, GETSET, GETDEL, GETEX, SETNX, SETEX, MGET, MSET, MSETNX, INCR, INCRBY, DECR, DECRBY, APPEND, STRLEN, GETRANGE, SUBSTR, SETRANGE |
| Lists | LPUSH, RPUSH, LPUSHX, RPUSHX, LPOP, RPOP, LLEN, LRANGE, LINDEX, LSET, LINSERT, LREM, LTRIM, LPOS, LMOVE, RPOPLPUSH, and the non-waiting forms of BLPOP, BRPOP, BLMOVE, BRPOPLPUSH |
| Sets | SADD, SREM, SMEMBERS, SISMEMBER, SMISMEMBER, SCARD, SPOP, SRANDMEMBER, SMOVE, SUNION, SINTER, SDIFF, SUNIONSTORE, SINTERSTORE, SINTERCARD, SSCAN |
| Sorted sets | ZADD (NX, XX, GT, LT, CH, INCR), ZINCRBY, ZSCORE, ZMSCORE, ZRANK, ZREVRANK, ZRANGE, ZREVRANGE, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZCOUNT, ZLEXCOUNT, ZCARD, ZREM, ZREMRANGEBYSCORE, ZREMRANGEBYRANK, ZPOPMIN, ZPOPMAX, ZRANDMEMBER, ZUNIONSTORE, ZINTERSTORE, ZINTERCARD, ZSCAN |
| Hashes | HSET, HGET, HMSET, HMGET, HSETNX, HGETALL, HDEL, HEXISTS, HKEYS, HVALS, HLEN, HSTRLEN, HINCRBY, HRANDFIELD, HSCAN |
| Streams | XADD, XLEN, XRANGE, XREVRANGE, XREAD, XTRIM, XDEL, XINFO STREAM |
| HyperLogLog | PFADD, PFCOUNT, PFMERGE (Redis-compatible counts) |
| Geo | GEOADD, GEODIST, GEOPOS |
| Keys | DEL, UNLINK, EXISTS, TYPE, KEYS, SCAN, RENAME, COPY, TOUCH, RANDOMKEY, EXPIRE, PEXPIRE, EXPIREAT, PEXPIREAT, TTL, PTTL, EXPIRETIME, PEXPIRETIME, PERSIST |
| Pub/Sub | SUBSCRIBE, UNSUBSCRIBE, PUBLISH |
| Transactions | MULTI, EXEC, DISCARD |
| Scripting | EVAL, EVALSHA, SCRIPT LOAD, SCRIPT EXISTS for a fixed set of built-in scripts (see Differences from Redis) |
| Connection and server | AUTH, HELLO, PING, ECHO, QUIT, RESET, SELECT 0, DBSIZE, FLUSHDB, FLUSHALL, INFO, CONFIG GET, CONFIG SET pdb-resp-commit-mode, TIME, WAIT |
Commands not in this table either return ERR unknown command or are accepted for
client compatibility without doing anything useful (for example CLIENT,
ACL, COMMAND, SAVE, BGSAVE, SLOWLOG). Do not rely on their replies.
Durability
Section titled “Durability”Every Redis write is appended to ParticleDB’s write-ahead log before it is
acknowledged, and keys, values, expirations and streams are
restored on restart. SAVE, BGSAVE and BGREWRITEAOF are not needed and do
nothing.
--resp-commit-mode decides how long a Redis write waits:
| Mode | A reply is sent after | Acknowledged writes can be lost by |
|---|---|---|
sync (default) |
the persistence flush completes (--wal-sync-mode sync or groupsync, the default) |
storage or hardware failures outside the persistence guarantee |
async |
the WAL record is written to the operating system | an operating-system crash or power loss (not a ParticleDB process crash) |
If you know Redis persistence: sync corresponds to appendfsync always, and
async is close to appendfsync everysec, except that the flush starts as soon
as the previous one finishes rather than once a second.
CONFIG GET appendfsync reports always or everysec to match;
CONFIG SET appendfsync is refused. See
Transaction and Durability Modes.
With --wal-sync-mode nosync the server writes no WAL, so Redis writes are not
durable at all.
You can switch the mode at runtime; it returns to the startup value after a restart:
127.0.0.1:6379> CONFIG SET pdb-resp-commit-mode asyncOK127.0.0.1:6379> CONFIG GET pdb-resp-commit-mode1) "pdb-resp-commit-mode"2) "async"async is refused when the server runs with --wal-sync-mode nosync, with
--num-wal-stripes above 1, or with replication.
Memory reporting
Section titled “Memory reporting”The Redis memory commands do not report real memory use in this release:
MEMORY USAGE keyreturns the same fixed value (64) for every existing key, whatever its size, andnilfor a missing key.MEMORY STATSreturns an empty array.INFOhas noMemorysection;INFO memoryreturns the same output asINFO(Server,PersistenceandKeyspacesections).
Use ParticleDB’s server metrics and memory settings (--max-server-memory) to monitor and bound memory instead.
Reaching Redis keys from SQL
Section titled “Reaching Redis keys from SQL”SQL functions read and write the same key space, over any protocol that runs SQL (PostgreSQL wire, native wire, HTTP, gRPC):
redis-cli SET greeting helloredis-cli RPUSH tasks a b credis-cli HSET user:1 name AliceSELECT KV_GET('greeting'); -- helloSELECT LIST_RANGE('tasks', 0, -1); -- [a,b,c]SELECT HASH_GET('user:1', 'name'); -- AliceSELECT KV_SET('from_sql', '42'); -- OK; redis-cli GET from_sql returns "42"SELECT KV_TTL('session:abc'); -- remaining seconds, as TTLOther functions follow the same naming: KV_* for strings and keys, LIST_*,
SET_*, HASH_*, ZSET_*, STREAM_*. SQL functions return text: reading a
value that is not valid UTF-8 fails with SQLSTATE 22021 instead of altering it.
Differences from Redis
Section titled “Differences from Redis”- No Lua.
EVAL,EVALSHA,SCRIPT LOADandSCRIPT EXISTSaccept only a fixed set of built-in scripts, matched by their exact text or SHA1 and run natively and atomically: the Orkes Conductor Redis queue’spop_batch.lua(orkes-redis-queues 1.0.9) and the Redisson 3.13.3RLockscripts (lock, renew, unlock, force-unlock). Any other script returnsERR unknown script;EVALSHAof an unknown SHA returnsNOSCRIPT.EVAL_RO,EVALSHA_RO,SCRIPT FLUSHandFUNCTIONare not supported. - Blocking commands do not wait.
BLPOP,BRPOP,BLMOVE,BRPOPLPUSH, andXREADwithBLOCKreturn at once (nilwhen there is nothing to return). Poll instead. - No
WATCH.MULTI/EXECrun the queued commands atomically, but optimistic locking withWATCH/UNWATCHis not available. - Pub/Sub supports channels only:
PSUBSCRIBE,PUNSUBSCRIBE,SSUBSCRIBEandPUBSUBare not supported. A subscriber that falls more than 32 MB behind is disconnected (like Redis’sclient-output-buffer-limit pubsub). - Streams: Consumer groups (
XGROUP,XREADGROUP,XACK,XPENDING,XCLAIM,XAUTOCLAIM),XINFO GROUPSandXINFO CONSUMERSare not supported.XTRIM ... ~trims exactly to the threshold. - Expiry options:
EXPIREand related commands do not acceptNX,XX,GTorLT. - Not supported in this release:
INCRBYFLOAT,HINCRBYFLOAT,RENAMENX,SDIFFSTORE,ZRANGEBYLEX,ZUNION,ZDIFF,GEOSEARCH,GEORADIUS,GEOHASH,SORT,DUMP/RESTORE,MONITOR;ZRANGEsupports onlystart stop [WITHSCORES](useZREVRANGEandZRANGEBYSCOREfor the other forms);LPOP/RPOPpop one element (no count argument). Bitmap commands (SETBIT,GETBIT,BITCOUNT,BITPOS,BITOP,BITFIELD) are not compatible with Redis: they do not operate on the string value thatGETreturns. - Server information.
CONFIG GETreports fixed values for most parameters andCONFIG SETchanges onlypdb-resp-commit-mode; configure the server withparticledb startflags.