Skip to main content

Redis Cheatsheet

Key Points

  • in-memory, key-value store
  • supports string, int, hash(map<string, string>), list, set, sorted set, bitmap
  • can be used as a database, cache, messsage broker, pub/sub
  • key-eviction, expiration, hashes, string, set, order-set, pub/sub, channel, RDB, AOL,

Common uses

  • high performrance for read and writes
  • cache, session store, distributed lock, rate limiter, leader board

Differs between traditional database?

  • in memory and key-value store (NoSQL)

Can Redis be used in a multi-threaded application?

  • Redis is single-threaded, but it is event-driven and asynchronous I/O to handle multiple client connections

What is Redis Transactions?

  • like a SQL transaction, grouping a set of commands together so that they either all executes or not execute at all

How to ensure persistence?

  • Snapshots: RDB, and AOF: append-only-file
  • RDB, write a new RDB file, and only replace the old one when new one is completed
  • In production, relying on RDB or AOF in server downtime is not ideal. Use replicas instead: once primary Redis fails, promote one of the replicas to take over.

Diff between RDB and AOF?

  • RDB takes a snapshot of all data into a single file, runs less frequently. it's efficient, but can result in data loss.
  • AOF stores only new data to the file. runs more frequently to prevent dataloss, but can be inefficient and larger files
  • RDB is generally faster and consumes less CPU because AOF tracks repeated or overlapping operations.

How to scale Redis?

  • replication
  • Redis Sentinel for HA
  • Redis Cluster for sharding

why is it so fast?

  • Redis keeps everything in RAM

Data types?

  • string, list, set, and sorted set
  • Keys are binary safe, so any binary sequence is allowed

What is key eviction?

  • when memory is reached, some keys can be evicted to make room. like volatile-lru or allkeys-lru.

How does Redis manage memory?

  • maxmemory, keyeviction, RDB, AOF

When would Redis not be an appropriate choice?

  • When data is large, or requires complex transactions. OR ACID compliance is required for data consistency. Heavy write may impace performance as well. Full text search.

What is Redis Sentinel?

  • Provides High Availability for Redis, it monitors and detects failures, and halding automatic failover to a replica.

How to search for values in Redis?

  • Redis doesn't provide search functionality in redis by default.
  • RediSearch is a module pluggable to Redis to allow searching.

How to optimize Redis for high read volumes?

  • using replicas

What is pipelining in Redis?

  • Send multiple commands to Redis without waiting for results from previous ones. Fast and efficient, reduces round trip costs.

Limitations of Redis?

  • not suitable for complex operations like table joins
  • doesn't support for BLOB

How to monitor and debug performance issues?

  • redis-cli provides tools like:

    • monitor: watch commands being executed in real-time
    • slowlog: log slow operations
    • info: for statistics about operation performance
  • Slowlog:

    • logs operations that are slower than a target limit (set in configuration file)
    • in memory only
    • has max-len set in configuration files, stored in circular buffers
    • SLOWLOG GET, SLOWLOG LEN, SLOWLOG RESET

How does it manage data?

  • data expirations (set expiration times for keys)
  • data partitioning (divide large datasets into smaller, more manageable chunks)
  • offloading to persistent storage (store less frequently accessed data on disk, snapshots or log files)
  • clustering (distribute across multiple redis instances)

Lua scripting?

  • like SQL script to MySQL
  • Redis lets users upload and execute Lua scripts on the serve
  • used for atomic execution of complex operations

How to handle caching in a distributed enironment?

  • redis instances has a caching layer in front of my database. Use consistent hashing to distribute keys across the cache nodes, ensures evey load distribution and reduces cache misses.

what happens if data in memory grows beyond the configured memory limit?

  • data eviction
    • volatile-lru: evicts the LRU key from among the keys with an expiration set
    • allkeys-lru: evicts the LRU key from all keys
    • volatile-ttl: evicts the key with the nearest expiration time
    • allkeys-random: evicts a random key from all keys
    • volatile-random: evicts a random key from among the keys with an expiration set
    • noeviction: error when memory limit is reached
  • Disk Persistence
    • RDB (Redis Database Backup): snapshot-based persistence method. configure to take period snapshots and save them to disk in binary format
    • AOF (append-only file): this log is written to disk, allow redis to replay the log
      • can be configured to save after every command, every second, or at specific times
    • No Persistence
    • RDB and AOF can be configure to work together

In case of hardware failure or server restarts, what happens?

  • Redis can load data back into memory from disk (from most recent snapshots or append-only-files)

Configuration in redis.conf

  • uncomment requirepass directive to enable ACL
  • use protected-mode no to allow connections from other hosts (a testing container on the same docker network)
  • comment bind 127.0.0.1 -::1 to allow connections from network interfaces other than localhost
  • to specify rdb filename: dbfilename dump1.rdb
  • no-appendfsync-on-rewrite no during an AOF rewrite, fsync (flushing IO buffer to disk) might block IO for too long. If this directive is set to yes, fsync will not happen during AOF rewrites.

Redis RDB and AOF configurations

  • use appendonly yes to turn on AOF mode

  • use appendfsync everysec, appendfsync always, or appendfsync no, to configure append frequency. "appendfsync no" depends on the OS write buffer.

  • use save 3600 1 to turn on snapshotting. 3600 1 means after 3600 seconds if at least 1 change was performed, save to snapshot

  • what if AOF file gets truncated?

    • redis will complain about the truncated data, and disrecard the data
  • what if AOF file gets corrupted?

    • data loss, try to fix it manually. If not, use redis-check-aof --fix, but this tool will discard all data from the corrupted place to the end of file.
  • AOF rewrite is automatically done from time to time. In a AOF rewrite, a new base RDB file and new log file will be created

  • use auto-aof-rewrite-percentage 100 and auto-aof-rewrite-min-size 64mb to set automatic rewrite rules. "precentage" to compared to previous aof file be last rewrite. minSize is to prevent rewrites when the file is still small.

  • use save or bgsave to trigger a snapshot dump

Size limit?

  • strings can't exceed 512MB
    • this applies to keys and string values

Architecture and Topology

Redis-cli

# Start cli: redis-cli -u redis://host:port
$ redis-cli -u redis://redis:6379

# authentication
redis:6379> auth default <password_here>

RDB and AOF

# Force a rdb save:
redis:6379> save
OK

# or bgsave:
redis:6379> bgsave
Background saving started

# Force a background AOF rewrite:
redis:6379> bgrewriteaof
Background append only file rewriting started

Redis ACL

# current user:
redis:6379> acl whoami
(error) NOAUTH Authentication required.

redis:6379> auth cqn%M?-0KR77
OK
redis:6379> acl whoami
"default"
redis:6379> acl users
1) "default"
redis:6379> acl list
1) "user default on sanitize-payload #e2d36090f11f7f36422ab17c5e8d53e344681894a6352d2455d9ef8e0dbbbc91 ~* &* +@all"

# Create a "root" user with get and set permissions on all keys
redis:6379> acl setuser inno_root on +GET +SET allkeys
OK
redis:6379> acl list
1) "user default on sanitize-payload #e2d36090f11f7f36422ab17c5e8d53e344681894a6352d2455d9ef8e0dbbbc91 ~* &* +@all"
2) "user inno_root on sanitize-payload ~* resetchannels -@all +get +set"

# To reset previous set rules and apply new one, use "reset"
redis:6379> acl setuser inno_root reset on allkeys +GET +SET
OK
redis:6379> acl list
1) "user default on sanitize-payload #e2d36090f11f7f36422ab17c5e8d53e344681894a6352d2455d9ef8e0dbbbc91 ~* &* +@all"
2) "user inno_root on sanitize-payload ~* resetchannels -@all +get +set"

# Create a "famapp_dev" user with get and set permissions on all famapp keys
redis:6379> acl setuser famapp_dev reset on (+SET +GET ~famapp*)
OK
redis:6379> acl list
1) "user default on sanitize-payload #e2d36090f11f7f36422ab17c5e8d53e344681894a6352d2455d9ef8e0dbbbc91 ~* &* +@all"
2) "user famapp_dev on sanitize-payload resetchannels -@all (~famapp* resetchannels -@all +set +get)"
3) "user inno_root on sanitize-payload ~* resetchannels -@all +get +set"

# Add a password "inno_root_2028" to inno_root:
# the sha256 hashed value of inno_root_2028 is cad44e192e03abf60ee69c38bd7a83893eea4e25ddaa41efe28ce5dedc8aab4f
redis:6379> acl setuser inno_root >inno_root_2028
OK
redis:6379> acl list
1) "user default on sanitize-payload #e2d36090f11f7f36422ab17c5e8d53e344681894a6352d2455d9ef8e0dbbbc91 ~* &* +@all"
2) "user famapp_dev on sanitize-payload resetchannels -@all (~famapp* resetchannels -@all +set +get)"
3) "user inno_root on sanitize-payload #cad44e192e03abf60ee69c38bd7a83893eea4e25ddaa41efe28ce5dedc8aab4f ~* resetchannels -@all +get +set"

# Delete a user
redis:6379> acl setuser inno_rot
OK
redis:6379> acl list
1) "user default on sanitize-payload #e2d36090f11f7f36422ab17c5e8d53e344681894a6352d2455d9ef8e0dbbbc91 ~* &* +@all"
2) "user famapp_dev on sanitize-payload resetchannels -@all (~famapp* resetchannels -@all +set +get)"
3) "user inno_root on sanitize-payload #cad44e192e03abf60ee69c38bd7a83893eea4e25ddaa41efe28ce5dedc8aab4f ~* resetchannels -@all +get +set"
4) "user inno_rot off sanitize-payload resetchannels -@all"
redis:6379> acl deluser inno_rot
(integer) 1
redis:6379> acl list
1) "user default on sanitize-payload #e2d36090f11f7f36422ab17c5e8d53e344681894a6352d2455d9ef8e0dbbbc91 ~* &* +@all"
2) "user famapp_dev on sanitize-payload resetchannels -@all (~famapp* resetchannels -@all +set +get)"
3) "user inno_root on sanitize-payload #cad44e192e03abf60ee69c38bd7a83893eea4e25ddaa41efe28ce5dedc8aab4f ~* resetchannels -@all +get +set"

Redis Basic Operations

# List all keys
> keys *

# List all keys starting with someting:
> keys famapp*

# List all keys starting with my
> keys my*

# Check if key exists
> exists myKey

# set a key-value
> set sName "333"
> lpush sList "item1" "item2" "item3"

# set a key-value with expire
> set key1 value1 ex 100

# get a value
> get sName

# get multiple values:
> mget key1 key2 key3

# delete a key
> del sName

# set a expiration for key
> set key2 "value1"
> expire key2 100

# get remaining time:
> ttl key2

# removes expiration:
> persist key2

# iterate the set of keys in the currently selected redis database
# returns the cursor of next scan position, 0 for no data left
> scan 0 match my* count 2

# Transactions:
> multi
> set Key1 Value1
> expire key1 3600
> exec

# Server info and Keyspace info
> info server
> info keyspace

Strings and Numbers

# increment a number, if it doesn't exist, redis will set it to 0 first
> incr counterKey

> set key1 value1
> get key1

> append key2 hello
> append key2 " world"
> get key2
"hello world"

List

  • lpush, rpush, llen, lrange, lpop, rpop
> rpush list1 item1 item2 item3 item4
(integer) 4

> lrange list1 0 -1
1) "item1"
2) "item2"
3) "item3"
4) "item4"

> lpush list1 item0
(integer) 5

> rpush list1 item5
(integer) 6

> lrange list1 0 -1
1) "item0"
2) "item1"
3) "item2"
4) "item3"
5) "item4"
6) "item5"

> lpop list1
"item0"

> rpop list1
"item5"

> lrange list1 0 -1
1) "item1"
2) "item2"
3) "item3"
4) "item4"

Set

  • sadd, srem, sismember, smembers
> sadd set1 item1 item2 item3
(integer) 3

> smembers set1
1) "item1"
2) "item2"
3) "item3"

> sismember set1 item1
(integer) 1

> sismember set1 item0
(integer) 0

> srem set1 item1
> smembers set1
1) "item2"
2) "item3"

# get number of elements:
> sadd set2 item1 item2 item3 item4
> scard set2
(integer) 4
> smembers set2
1) "item1"
2) "item2"
3) "item3"
4) "item4"

# Unions
> sunion key1 key2 ...

# remove and return a random member:
> spop set2 [count]

SortedSets

  • zadd, zrem, zrange, zrevrange, zincrby
  • sets with scored elements, scores are used to determine order
  • use cases: Leaderboards, Time-Based Events, priority queues, geolocation, real-time analytics
> zadd set2 3.3 item1 3.2 item2 9 item3
(integer) 3
> zrange set2 0 -1
1) "item2"
2) "item1"
3) "item3"

> zrange set2 0 -1 withscores
1) "item2"
2) "3.2"
3) "item1"
4) "3.3"
5) "item3"
6) "9"

> zadd set2 3.3 item5
(integer) 1

> zrange set2 0 -1 withscores
1) "item2"
2) "3.2"
3) "item1"
4) "3.3"
5) "item5"
6) "3.3"
7) "item3"
8) "9"
# adding items with the same socre, items ares store lexicographcally

> zadd set2 3.3 item0
(integer) 1

> zrange set2 0 -1 withscores
 1) "item2"
 2) "3.2"
 3) "item0"
 4) "3.3"
 5) "item1"
 6) "3.3"
 7) "item5"
 8) "3.3"
 9) "item3"
10) "9"
# change score of an item

> zadd set2 3.9 item5
(integer) 0

> zrange set2 0 -1 withscores
 1) "item2"
 2) "3.2"
 3) "item0"
 4) "3.3"
 5) "item1"
 6) "3.3"
 7) "item5"
 8) "3.9"
 9) "item3"
10) "9"
# remove an element from zSet

> zrem set2 item5
(integer) 1

> zrange set2 0 -1 withscores
1) "item2"
2) "3.2"
3) "item0"
4) "3.3"
5) "item1"
6) "3.3"
7) "item3"
8) "9"

Hashes

  • hset, hget, hgetall
  • used to store objects (string:string key-values)
  • integers are stored as strings, floats are not supported. (floats are treated as strings, and can't use hincrby function)
  • similar like objects, different key-values can be organized in a single object, efficient, atomic, flexible
> hset user anme Alice
(integer) 1

> hset user age 30
(integer) 1

> hset user email alice@example.com mobile 12345
(integer) 2

> hget user email
"alice@example.com"

> hgetall user
1) "anme"
2) "Alice"
3) "age"
4) "30"
5) "email"
6) "alice@example.com"
7) "mobile"
8) "12345"

> hincrby user age 1
(integer) 31

> hincrby user age -5
(integer) 26


Bitmaps

  • setbit, getbit, bitop, bitcount, bitpos
  • used to keep an estimated count of unique keys
redis> SETBIT mykey 7 1
(integer) 0
redis> GETBIT mykey 0
(integer) 0
redis> GETBIT mykey 7
(integer) 1
redis> GETBIT mykey 100
(integer) 0

HyperLogLog

  • pfadd, pfcount, pfdebug, pfmerge, pfselftest

Streams

  • similar to an append-only log
  • use cases:
    • event sourcing (tracking user actions)
    • sensor monitoring (readings from devices in the field)
    • notifications (storing a record of each user's notifications in a separate stream)
  • xadd, xread, xrange, xlen


Channels

  • pub/sub
# publisher publishes message to a channel
> PUBLISH weather:54481 temp:85f

# subscriber subscribes to channel
> PSUBSCRIBE weather:<sup>*</sup>

Message Queues

  • lists with push and pop