# Advanced Features ## Table of Contents - [Lua Scripting](#lua-scripting) - [Pub/Sub Mode](#pubsub-mode) - [Pipe Mode](#pipe-mode) - [CSV and JSON Output](#csv-and-json-output) - [Getting Input from Other Programs](#getting-input-from-other-programs) - [Cluster Management](#cluster-management) ## Lua Scripting Redis supports server-side Lua scripting for atomic multi-command operations. ### Running Scripts ```bash # Run script from file with --eval redis-cli --eval /tmp/script.lua key1 key2 , arg1 arg2 arg3 # The comma separates KEYS[] from ARGV[]: # key1, key2 → KEYS[1], KEYS[2] # arg1, arg2, arg3 → ARGV[1], ARGV[2], ARGV[3] # Inline EVAL redis-cli EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mykey myvalue # EVALSHA (use SHA1 hash of cached script) redis-cli EVALSHA numkeys key [key ...] arg [arg ...] ``` ### Lua Script Examples ```lua -- Conditional SET (only if value matches) local current = redis.call('GET', KEYS[1]) if current == ARGV[1] then return redis.call('SET', KEYS[1], ARGV[2]) end return nil -- Atomic counter reset local old = redis.call('GET', KEYS[1]) redis.call('SET', KEYS[1], ARGV[1]) return old -- Multi-key operation local results = {} for i = 1, #KEYS do results[i] = redis.call('GET', KEYS[i]) end return results ``` ### Lua Debugger ```bash # Enable debugger (--ldb) redis-cli --ldb --eval /tmp/script.lua key1 , arg1 # Synchronous mode (blocks server — for debugging only) redis-cli --ldb-sync-mode --eval /tmp/script.lua key1 , arg1 ``` **Async mode** (default): server continues serving other clients during debugging. Script changes are rolled back from server memory after debugging. **Sync mode**: server is blocked. Script changes persist in server memory. Use only in development. ### Script Management ```bash redis-cli SCRIPT EXISTS sha1 [sha1 ...] # Check if scripts are cached redis-cli SCRIPT FLUSH [ASYNC|SYNC] # Clear script cache redis-cli SCRIPT LOAD script # Cache script, return SHA1 redis-cli SCRIPT KILL # Kill running script (only if no write) ``` ### Function API (Redis 7.0+) Functions are a persistent alternative to scripts: ```bash redis-cli FUNCTION LOAD "redis.register_function('myfunc', function(keys, args) ... end)" redis-cli FCALL myfunc 0 arg1 arg2 redis-cli FUNCTION LIST redis-cli FUNCTION DELETE myfunc redis-cli FUNCTION FLUSH [ASYNC|SYNC] redis-cli FUNCTION DUMP # Serialize all functions redis-cli FUNCTION RESTORE serialized-data # Restore functions ``` ## Pub/Sub Mode redis-cli can publish and subscribe to Redis Pub/Sub channels. ### Subscribing ```bash # Subscribe to specific channels redis-cli SUBSCRIBE channel1 channel2 # Pattern subscription redis-cli PSUBSCRIBE '*' # Read published messages (blocks until Ctrl-C) # Output format: # 1) "pmessage" — message type # 2) "*" — pattern matched # 3) "mychannel" — channel name # 4) "mymessage" — message content ``` ### Publishing ```bash redis-cli PUBLISH mychannel "Hello World" ``` ### Inspecting Pub/Sub ```bash redis-cli PUBSUB CHANNELS [pattern] # List active channels redis-cli PUBSUB NUMSUB [channel ...] # Subscriber count per channel redis-cli PUBSUB NUMPAT # Pattern subscription count redis-cli PUBSUB SHARDCHANNELS [pattern] # List shard channels redis-cli PUBSUB SHARDNUMSUB [channel ...] # Shard channel subscriber count ``` ### Shard Pub/Sub (Redis 7.0+) Shard Pub/Sub routes messages to the cluster node that owns the channel's slot, providing better scalability: ```bash redis-cli SSUBSCRIBE shardchannel redis-cli SUNSUBSCRIBE shardchannel redis-cli SPUBLISH shardchannel "message" ``` ## Pipe Mode Transfer raw Redis protocol from stdin to the server. This is the fastest way to bulk-insert data. ```bash # Basic pipe mode cat data.protocol | redis-cli --pipe # Custom timeout (seconds) cat data.protocol | redis-cli --pipe --pipe-timeout 60 # Zero timeout (wait forever) cat data.protocol | redis-cli --pipe --pipe-timeout 0 ``` ### Protocol Format Each command in the pipe file must use Redis protocol: ``` *\r\n $\r\n \r\n ``` Example — `SET mykey myvalue`: ``` *3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n ``` Pipe mode is dramatically faster than individual commands because it batches network round trips. See the [mass insertion guide](https://redis.io/docs/latest/develop/clients/patterns/bulk-loading/) for generating protocol files. ## CSV and JSON Output ### CSV Output Single-command CSV output for data export: ```bash redis-cli --csv LRANGE mylist 0 -1 # "d","c","b","a" redis-cli --csv HGETALL user:1 # "name","Alice","age","30" ``` **Note:** `--csv` works per command, not for exporting entire databases. ### JSON Output JSON output using RESP3 protocol: ```bash # JSON output (uses RESP3 by default) redis-cli --json HGETALL user:1 # {"name": "Alice", "age": "30"} # Use with RESP2 if needed redis-cli --json -2 HGETALL user:1 # ASCII-safe quoted strings (no Unicode) redis-cli --quoted-json GET mykey ``` ### Pipe Commands to Other Tools ```bash # Format and filter output redis-cli --raw GET mykey | jq . # Export to file redis-cli --csv LRANGE mylist 0 -1 > output.csv # Use with grep redis-cli MONITOR | grep "SET" ``` ## Getting Input from Other Programs ### Read Last Argument from stdin (-x) ```bash # Set key to contents of a file cat /etc/services | redis-cli -x SET net_services # Check the stored value redis-cli GETRANGE net_services 0 50 ``` ### Read Tagged Argument from stdin (-X) ```bash # Dump and restore a key atomically redis-cli -D "" --raw dump mykey > /tmp/mykey.dump redis-cli -X dump_tag restore mykey2 0 dump_tag replace < /tmp/mykey.dump ``` ### Pipe Multiple Commands ```bash # Execute commands from a text file cat /tmp/commands.txt | redis-cli # commands.txt format (one command per line): # SET item:3374 100 # INCR item:3374 # APPEND item:3374 xxx # GET item:3374 ``` ### Feed Continuous Data ```bash # Generate keys continuously while true; do echo "SET timestamp:$(date +%s) $(date -Iseconds)" done | redis-cli --pipe ``` ## Cluster Management redis-cli provides built-in cluster management via `--cluster` subcommands, plus direct cluster commands for lower-level control. ### redis-cli Cluster Operations ```bash # Create a new cluster (interactive prompts for replication) redis-cli --cluster create host1:port1 host2:port2 host3:port3 --cluster-replicas 1 # Check cluster state redis-cli --cluster check host1:port1 # Show cluster info redis-cli --cluster info host1:port1 # Reshard (move slots between nodes) redis-cli --cluster reshard host1:port1 --cluster-from --cluster-to --cluster-slots # Rebalance slots across all nodes redis-cli --cluster rebalance host1:port1 # Add a node to the cluster redis-cli --cluster add-node new-host:new-port existing-host:existing-port # As replica: redis-cli --cluster add-node new-host:new-port existing-host:existing-port --cluster-slave --cluster-master-id # Remove a node redis-cli --cluster del-node host:port # Fix cluster issues (missing slots, etc.) redis-cli --cluster fix host:port # Execute command on all cluster nodes redis-cli --cluster call host:port # List all --cluster subcommands redis-cli --cluster help ``` Use `-c` flag to enable cluster mode in redis-cli (automatically follows `-ASK` and `-MOVED` redirections): ```bash redis-cli -c -h cluster-node -p 6379 ``` ### Cluster Commands (Direct) ```bash # Cluster state and topology redis-cli CLUSTER INFO # Cluster state overview (O(1)) redis-cli CLUSTER NODES # Full node topology (O(N)) redis-cli CLUSTER SHARDS # Shard/node mapping (O(N), Redis 7.0+) # Slot management redis-cli CLUSTER KEYSLOT key # Hash slot for a key (O(1)) redis-cli CLUSTER ADDSLOTS slot [slot ...] # Assign slots to node (O(N)) redis-cli CLUSTER DELSLOTS slot [slot ...] # Unbind slots (O(N)) redis-cli CLUSTER SETSLOT slot IMPORTING|node-id|MIGRATING|STABLE # Slot migration (O(1)) # Node management redis-cli CLUSTER MEET ip port [bus-port] # Join cluster (O(1)) redis-cli CLUSTER FORGET node-id # Remove node (O(1)) redis-cli CLUSTER REPLICATE node-id # Become replica of node (O(1)) redis-cli CLUSTER RESET [HARD|SOFT] # Reset cluster state (O(N)) # Failover redis-cli CLUSTER FAILOVER [FORCE|TAKEOVER] # Manual failover (O(1)) redis-cli CLUSTER SAVECONFIG # Save config to disk (O(1)) # Node identification redis-cli CLUSTER MYID # Current node ID (O(1)) redis-cli CLUSTER MYSHARDID # Current shard ID (O(1)) ``` **Behavioral notes:** - Redis Cluster has 16384 hash slots distributed across master nodes - `CLUSTER SLOTS` is deprecated since Redis 7.0 — use `CLUSTER SHARDS` instead - Use `redis-cli -c` for transparent cluster redirections in interactive mode - `CLUSTER FORGET` auto-propagates via gossip in Redis 7.2+