Redis on a MicroVM
Redis is a very lightweight in-memory data store. It is well suited to MicroVMs because of its low memory consumption and high performance.
Preparing the Image
sudo mount -o loop rootfs.img /mnt/microvm
# Debian/Ubuntu
sudo chroot /mnt/microvm bash -c '
apt update && apt install -y redis-server
'
# Alpine
sudo chroot /mnt/microvm bash -c '
apk add redis
'
sudo umount /mnt/microvm
Optimal Configuration
sudo mount -o loop rootfs.img /mnt/microvm
sudo tee /mnt/microvm/etc/redis/redis.conf << 'REDISCONF'
# Network
bind 0.0.0.0
port 6379
protected-mode no
# Memory
maxmemory 128mb
maxmemory-policy allkeys-lru
# Persistence (optional, disable for a pure cache)
save ""
# save 900 1
# save 300 10
# save 60 10000
appendonly no
# Logging
loglevel notice
logfile ""
# Slow log
slowlog-log-slower-than 10000
slowlog-max-len 128
# Disable dangerous commands
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
REDISCONF
sudo umount /mnt/microvm
Running the MicroVM
qemu-system-x86_64 \
-M microvm -enable-kvm -cpu host -m 512m -smp 2 \
-kernel vmlinuz \
-append "console=ttyS0 root=/dev/vda rw" \
-drive id=rootfs,file=rootfs.img,format=raw,if=none,cache=none \
-device virtio-blk-device,drive=rootfs \
-netdev user,id=net0,hostfwd=tcp::6379-:6379 \
-device virtio-net-device,netdev=net0 \
-nographic -serial stdio
Setting Up the Guest
# Start Redis
redis-server /etc/redis/redis.conf --daemonize yes
# Test the connection
redis-cli ping
# PONG
# Basic operations
redis-cli SET greeting "Hello from MicroVM"
redis-cli GET greeting
# Check the info
redis-cli INFO server
redis-cli INFO memory
Auto Start
sudo tee /mnt/microvm/etc/init.d/redis << 'REDISINIT'
#!/sbin/openrc-run
REDIS_CONF=/etc/redis/redis.conf
PIDFILE=/run/redis/redis.pid
depend() {
need net
keyword timeout 60
}
start() {
ebegin "Starting Redis"
mkdir -p /run/redis
chown redis:redis /run/redis
start-stop-daemon --start --background \
--make-pidfile --pidfile $PIDFILE \
--exec /usr/bin/redis-server -- $REDIS_CONF
eend $?
}
stop() {
ebegin "Stopping Redis"
start-stop-daemon --stop --pidfile $PIDFILE
eend $?
}
REDISINIT
sudo chmod +x /mnt/microvm/etc/init.d/redis
sudo chroot /mnt/microvm rc-update add redis default
Port Forwarding
# QEMU with Redis port forwarding
-netdev user,id=net0,hostfwd=tcp::6379-:6379
# From the host
redis-cli -h 127.0.0.1 -p 6379
Use Cases
Session Store
# Store a session
redis-cli SET "session:user123" '{"name":"John","role":"admin"}' EX 3600
# Retrieve a session
redis-cli GET "session:user123"
Rate Limiting
# Simple rate limiter
redis-cli INCR "ratelimit:ip:192.168.1.1"
redis-cli EXPIRE "ratelimit:ip:192.168.1.1" 60
Pub/Sub
# Terminal 1 (subscriber)
redis-cli SUBSCRIBE notifications
# Terminal 2 (publisher)
redis-cli PUBLISH notifications "New alert from MicroVM"
Caching
# Cache a query result
redis-cli SET "cache:users:list" '{"data":[...]}' EX 300
# Check TTL
redis-cli TTL "cache:users:list"
Monitoring
# Real-time info
redis-cli INFO
# Check memory usage
redis-cli INFO memory | grep used_memory_human
# Check the connections
redis-cli CLIENT LIST
# Check slow queries
redis-cli SLOWLOG GET 10
# Check keys per database
redis-cli INFO keyspace
Persistence
RDB Snapshotting
# Enable save
save 900 1
save 300 10
save 60 10000
# Manual save
redis-cli BGSAVE
AOF (Append Only File)
appendonly yes
appendfsync everysec
Troubleshooting
Redis will not start
# Check the log
redis-server /etc/redis/redis.conf
# Check whether the port is already in use
ss -tlnp | grep 6379
# Check memory
free -h
Out of memory
# Reduce maxmemory
maxmemory 64mb
# Use volatile-lru if there are keys with a TTL
maxmemory-policy volatile-lru
# Check the largest keys
redis-cli --bigkeys