Redis Interview Questions

35 questions with detailed answers

Question:
What is Redis and why is it popular in modern applications?
Answer:
Redis is an in-memory data structure store that serves as: • **Database**: NoSQL key-value store • **Cache**: High-performance caching layer • **Message broker**: Pub/Sub messaging system **Why Popular:** • Extremely fast (100,000+ ops/sec) • Rich data types (strings, lists, sets, hashes) • Atomic operations • Built-in replication • Lua scripting support **Common Use Cases:** # Session storage SET session:user123 '{"name":"John", "role":"admin"}' EXPIRE session:user123 3600 # Caching SET cache:product:456 '{"name":"Laptop", "price":999}' # Counters INCR page:views:homepage

Question:
Explain Redis data types with practical examples.
Answer:
Redis provides 5 core data types: • Strings (most basic):** SET user:1000:name "Alice" GET user:1000:name INCR user:1000:login_count SETEX temp:token 300 "abc123" # expires in 5 min • Lists (ordered collections):** LPUSH notifications "New message" RPUSH notifications "System update" LRANGE notifications 0 -1 # get all LTRIM notifications 0 99 # keep only 100 items • Sets (unique values):** SADD user:tags "redis" "database" "cache" SISMEMBER user:tags "redis" # check membership SINTER user1:tags user2:tags # common tags • Hashes (field-value pairs):** HSET user:1000 name "Alice" email "alice@example.com" age 30 HGET user:1000 name HINCRBY user:1000 age 1 # increment age • Sorted Sets (scored members):** ZADD leaderboard 1500 "player1" 1200 "player2" ZREVRANGE leaderboard 0 9 WITHSCORES # top 10

Question:
How do you connect to Redis and perform basic operations?
Answer:
**Connection Methods:** **Redis CLI:** redis-cli -h localhost -p 6379 -a password 127.0.0.1:6379> PING PONG 127.0.0.1:6379> SELECT 1 # switch to database 1 **Python (redis-py):** import redis # Basic connection r = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True) # Connection pool (recommended) pool = redis.ConnectionPool(host='localhost', port=6379, max_connections=20) r = redis.Redis(connection_pool=pool) # Operations r.set('key', 'value', ex=3600) # expires in 1 hour value = r.get('key') r.delete('key') **Node.js (ioredis):** const Redis = require('ioredis'); const redis = new Redis({ host: 'localhost', port: 6379, retryDelayOnFailover: 100 }); await redis.set('key', 'value'); const value = await redis.get('key'); **Best Practices:** • Use connection pooling • Handle connection errors • Set appropriate timeouts • Use pipelines for bulk operations

Question:
Compare Redis persistence options: RDB vs AOF.
Answer:
Redis offers two persistence mechanisms: **RDB (Redis Database Backup):** # Configuration save 900 1 # save if 1 key changed in 900 seconds save 300 10 # save if 10 keys changed in 300 seconds save 60 10000 # save if 10000 keys changed in 60 seconds # Manual snapshot BGSAVE # background save SAVE # blocking save **Pros:** Compact, fast recovery, good for backups **Cons:** Data loss possible, CPU intensive during saves **AOF (Append Only File):** # Configuration appendonly yes appendfsync everysec # fsync every second # appendfsync always # fsync every command (slow) # appendfsync no # let OS decide # AOF rewrite BGREWRITEAOF **Pros:** Better durability, readable format **Cons:** Larger files, slower recovery **Hybrid Approach:** # Use both for maximum safety save 900 1 appendonly yes appendfsync everysec **When to Use:** • RDB only: Backup scenarios, can tolerate data loss • AOF only: Need durability, can't lose data • Both: Production systems requiring high availability

Question:
How does Redis Clustering work for horizontal scaling?
Answer:
Redis Cluster provides horizontal scaling across multiple nodes: **Architecture:** • 16384 hash slots distributed across nodes • Each key mapped to a slot using CRC16 • Minimum 3 master nodes required • Each master can have replica nodes **Setup Example:** # Create cluster redis-cli --cluster create \ 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \ 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \ --cluster-replicas 1 # Check cluster status redis-cli -c -p 7000 cluster nodes redis-cli -c -p 7000 cluster info **Configuration (redis.conf):** cluster-enabled yes cluster-config-file nodes-6379.conf cluster-node-timeout 15000 cluster-announce-ip 192.168.1.100 **Client Usage:** from rediscluster import RedisCluster startup_nodes = [ {"host": "127.0.0.1", "port": "7000"}, {"host": "127.0.0.1", "port": "7001"}, {"host": "127.0.0.1", "port": "7002"} ] rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True) rc.set("key", "value") **Hash Tags (for multi-key operations):** SET {user:1000}:profile "data" SET {user:1000}:settings "config" # Both keys go to same slot

Question:
Explain Redis Pub/Sub messaging system with examples.
Answer:
Redis Pub/Sub enables message passing between publishers and subscribers: **Basic Pub/Sub:** # Subscribe to channels SUBSCRIBE news sports weather PSUBSCRIBE news:* # pattern subscription # Publish messages PUBLISH news "Breaking: Redis 7.0 released" PUBLISH sports "Game result: Team A wins" **Python Publisher:** import redis r = redis.Redis() # Publish messages r.publish('notifications', 'User logged in') r.publish('alerts', 'High CPU usage detected') **Python Subscriber:** import redis r = redis.Redis() pubsub = r.pubsub() # Subscribe to channels pubsub.subscribe('notifications', 'alerts') pubsub.psubscribe('user:*') # pattern subscription # Listen for messages for message in pubsub.listen(): if message['type'] == 'message': print(f"Channel: {message['channel']}") print(f"Data: {message['data']}") **Use Cases:** • Real-time notifications • Chat applications • Live updates • Event broadcasting

Question:
How do Redis transactions work with MULTI/EXEC?
Answer:
Redis transactions group commands for atomic execution: **Basic Transaction:** MULTI SET account:1 100 SET account:2 200 DECRBY account:1 50 INCRBY account:2 50 EXEC **With WATCH (Optimistic Locking):** WATCH account:1 account:2 MULTI DECRBY account:1 50 INCRBY account:2 50 EXEC # Returns null if watched keys changed **Python Example:** import redis r = redis.Redis() # Basic transaction pipe = r.pipeline() pipe.multi() pipe.set('key1', 'value1') pipe.set('key2', 'value2') pipe.incr('counter') results = pipe.execute() # With watch with r.pipeline() as pipe: while True: try: pipe.watch('balance') current_balance = int(pipe.get('balance') or 0) if current_balance >= 100: pipe.multi() pipe.decrby('balance', 100) pipe.incr('purchases') pipe.execute() break else: pipe.unwatch() raise ValueError("Insufficient balance") except redis.WatchError: # Retry if key was modified continue **Key Points:** • All commands queued, executed atomically • WATCH provides optimistic concurrency control • DISCARD cancels transaction • Commands don't see intermediate results

Question:
What is Redis pipelining and how does it improve performance?
Answer:
Pipelining sends multiple commands without waiting for individual responses: **Without Pipelining:** # Each command waits for response (RTT per command) r.set('key1', 'value1') # RTT 1 r.set('key2', 'value2') # RTT 2 r.set('key3', 'value3') # RTT 3 # Total: 3 RTTs **With Pipelining:** # All commands sent together pipe = r.pipeline(transaction=False) pipe.set('key1', 'value1') pipe.set('key2', 'value2') pipe.set('key3', 'value3') results = pipe.execute() # Only 1 RTT **Bulk Operations:** # Insert 10000 keys efficiently pipe = r.pipeline(transaction=False) for i in range(10000): pipe.set(f'key:{i}', f'value:{i}') if i % 1000 == 0: # Execute in batches pipe.execute() pipe = r.pipeline(transaction=False) pipe.execute() # Execute remaining **Performance Benefits:** • Reduces network round trips • Higher throughput (10x+ improvement possible) • Lower latency for bulk operations • More efficient network utilization **Best Practices:** • Batch size: 100-1000 commands • Use for bulk operations • Don't pipeline commands that depend on previous results • Monitor memory usage during large pipelines

Question:
How do you implement Redis Lua scripting for atomic operations?
Answer:
Lua scripts execute atomically on Redis server: **Basic Script Execution:** # Simple Lua script EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mykey myvalue # Get and increment atomically EVAL "local val = redis.call('GET', KEYS[1]) or 0; redis.call('SET', KEYS[1], val + ARGV[1]); return val + ARGV[1]" 1 counter 5 **Script Caching:** # Load script and get SHA SCRIPT LOAD "return redis.call('GET', KEYS[1])" # Returns: "6b1bf486c81ceb7edf3c093f4c48582e38c0e791" # Execute by SHA EVALSHA 6b1bf486c81ceb7edf3c093f4c48582e38c0e791 1 mykey **Complex Example - Rate Limiting:** -- rate_limit.lua local key = KEYS[1] local window = tonumber(ARGV[1]) local limit = tonumber(ARGV[2]) local current_time = tonumber(ARGV[3]) -- Clean old entries redis.call('ZREMRANGEBYSCORE', key, 0, current_time - window) -- Count current requests local current_requests = redis.call('ZCARD', key) if current_requests < limit then -- Add current request redis.call('ZADD', key, current_time, current_time) redis.call('EXPIRE', key, window) return {1, limit - current_requests - 1} else return {0, 0} end **Python Usage:** rate_limit_script = r.register_script(open('rate_limit.lua').read()) # Check rate limit (100 requests per 60 seconds) result = rate_limit_script( keys=['user:123:requests'], args=[60, 100, int(time.time())] ) allowed, remaining = result if allowed: print(f"Request allowed. {remaining} remaining") else: print("Rate limit exceeded") **Benefits:** • Atomic execution • Reduced network traffic • Server-side logic • Better performance for complex operations

Question:
What are Redis memory optimization techniques?
Answer:
Redis memory optimization strategies: • Data Structure Optimization:** # Use hashes for small objects # Instead of: SET user:1000:name "John" SET user:1000:email "john@example.com" SET user:1000:age "30" # Use: HMSET user:1000 name "John" email "john@example.com" age "30" • Key Naming Strategies:** # Short, consistent key names # Bad: "user:profile:personal:information:1000" # Good: "u:p:1000" # Use hash tags for clustering SET {user:1000}:profile "data" SET {user:1000}:settings "config" • Memory Configuration:** # redis.conf optimizations maxmemory 2gb maxmemory-policy allkeys-lru # Compression settings hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 set-max-intset-entries 512 zset-max-ziplist-entries 128 • Data Expiration:** # Set TTL on temporary data r.setex('session:abc123', 3600, session_data) # 1 hour r.expire('cache:product:456', 1800) # 30 minutes # Lazy expiration r.set('temp:data', value) r.expire('temp:data', 300) # 5 minutes • Memory Analysis:** # Check memory usage INFO memory MEMORY USAGE mykey MEMORY STATS # Find large keys redis-cli --bigkeys redis-cli --memkeys **Best Practices:** • Monitor memory usage regularly • Use appropriate data structures • Set expiration on temporary data • Compress large values • Use memory-efficient key naming

Question:
How do you secure Redis in production environments?
Answer:
Redis security best practices: • Authentication:** # redis.conf requirepass your_strong_password_here # ACL (Redis 6+) user default off user app_user on >app_password ~app:* +@read +@write -@dangerous user admin_user on >admin_password ~* +@all • Network Security:** # Bind to specific interfaces bind 127.0.0.1 192.168.1.100 # Change default port port 6380 # Disable dangerous commands rename-command FLUSHDB "" rename-command FLUSHALL "" rename-command DEBUG "" • TLS/SSL Encryption:** # redis.conf port 0 tls-port 6380 tls-cert-file /path/to/redis.crt tls-key-file /path/to/redis.key tls-ca-cert-file /path/to/ca.crt • Client Connection:** # Python with SSL import redis r = redis.Redis( host='redis.example.com', port=6380, password='your_password', ssl=True, ssl_cert_reqs='required', ssl_ca_certs='/path/to/ca.crt' ) **Security Checklist:** • Enable authentication • Use ACLs for fine-grained access • Enable TLS encryption • Bind to specific interfaces • Change default port • Disable dangerous commands • Set up proper firewall rules

Question:
Explain Redis Sentinel for high availability setup.
Answer:
Redis Sentinel provides high availability and monitoring: **Architecture:** • Monitors master and replica instances • Automatic failover when master fails • Configuration provider for clients • Notification system for events **Sentinel Configuration:** # sentinel.conf port 26379 sentinel monitor mymaster 192.168.1.100 6379 2 sentinel auth-pass mymaster your_password sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 10000 sentinel parallel-syncs mymaster 1 **Client Connection (Python):** from redis.sentinel import Sentinel # Connect to Sentinels sentinel = Sentinel([ ('192.168.1.100', 26379), ('192.168.1.101', 26379), ('192.168.1.102', 26379) ], socket_timeout=0.1) # Get master and replica connections master = sentinel.master_for('mymaster', socket_timeout=0.1) replica = sentinel.slave_for('mymaster', socket_timeout=0.1) # Use connections master.set('key', 'value') # Write to master value = replica.get('key') # Read from replica **Monitoring Commands:** # Sentinel status redis-cli -p 26379 SENTINEL masters redis-cli -p 26379 SENTINEL slaves mymaster # Manual failover redis-cli -p 26379 SENTINEL failover mymaster **Best Practices:** • Deploy odd number of Sentinels (3, 5, 7) • Distribute Sentinels across different servers • Set appropriate timeouts • Monitor Sentinel logs • Test failover scenarios regularly

Question:
What are Redis Streams and how are they used for event sourcing?
Answer:
Redis Streams provide log-like data structure for event sourcing: **Basic Stream Operations:** # Add entries to stream XADD mystream * sensor-id 1234 temperature 19.8 humidity 67.2 XADD mystream * sensor-id 1235 temperature 20.1 humidity 65.8 # Read from stream XREAD COUNT 2 STREAMS mystream 0 XREAD BLOCK 5000 STREAMS mystream $ # Block for new entries # Read range XRANGE mystream - + # All entries **Consumer Groups:** # Create consumer group XGROUP CREATE mystream mygroup 0 MKSTREAM # Add consumers to group XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream > XREADGROUP GROUP mygroup consumer2 COUNT 1 STREAMS mystream > # Acknowledge processed messages XACK mystream mygroup 1609459200000-0 **Python Example - Event Processing:** import redis import json from datetime import datetime r = redis.Redis(decode_responses=True) # Producer - Add events def add_event(event_type, data): event = { 'type': event_type, 'timestamp': datetime.now().isoformat(), 'data': json.dumps(data) } return r.xadd('events', event) # Consumer - Process events def process_events(group_name, consumer_name): try: r.xgroup_create('events', group_name, id='0', mkstream=True) except redis.ResponseError: pass # Group already exists while True: messages = r.xreadgroup( group_name, consumer_name, {'events': '>'}, count=1, block=1000 ) for stream, msgs in messages: for msg_id, fields in msgs: # Process message event_type = fields['type'] data = json.loads(fields['data']) print(f"Processing {event_type}: {data}") # Acknowledge message r.xack('events', group_name, msg_id) **Use Cases:** • Event sourcing • Activity feeds • Sensor data collection • Chat applications • Audit logs • Real-time analytics **Advantages over Pub/Sub:** • Message persistence • Consumer groups for load balancing • Message acknowledgment • Replay capability

Question:
How do you use Redis as a message queue system?
Answer:
Redis can implement various message queue patterns: • Simple Queue with Lists:** import redis import json import time r = redis.Redis(decode_responses=True) # Producer def enqueue_job(queue_name, job_data): job = { 'id': str(int(time.time() * 1000)), 'data': job_data, 'created_at': time.time() } r.lpush(queue_name, json.dumps(job)) return job['id'] # Consumer def process_jobs(queue_name): while True: # Blocking pop (wait for jobs) result = r.brpop(queue_name, timeout=5) if result: queue, job_json = result job = json.loads(job_json) try: # Process job print(f"Processing job {job['id']}: {job['data']}") time.sleep(2) # Simulate work print(f"Job {job['id']} completed") except Exception as e: print(f"Job {job['id']} failed: {e}") • Priority Queue with Sorted Sets:** def enqueue_priority_job(queue_name, job_data, priority=0): job_id = str(int(time.time() * 1000000)) job = {'id': job_id, 'data': job_data} # Higher score = higher priority r.zadd(queue_name, {json.dumps(job): priority}) return job_id def dequeue_priority_job(queue_name): # Get highest priority job result = r.zpopmax(queue_name) if result: job_json, priority = result[0] return json.loads(job_json) return None • Delayed Jobs with Sorted Sets:** def enqueue_delayed_job(queue_name, job_data, delay_seconds): execute_at = time.time() + delay_seconds job = { 'id': str(int(time.time() * 1000000)), 'data': job_data } r.zadd(f"{queue_name}:delayed", {json.dumps(job): execute_at}) def process_delayed_jobs(queue_name): now = time.time() # Get jobs ready to execute jobs = r.zrangebyscore( f"{queue_name}:delayed", 0, now, withscores=True ) for job_json, score in jobs: # Move to main queue r.zrem(f"{queue_name}:delayed", job_json) r.lpush(queue_name, job_json) **Best Practices:** • Use reliable queues for critical jobs • Implement retry logic with exponential backoff • Monitor queue lengths and processing times • Use dead letter queues for failed jobs • Consider using Redis Streams for complex scenarios

Question:
How do you monitor and debug Redis performance issues?
Answer:
Redis monitoring and debugging strategies: • Built-in Monitoring Commands:** # General information INFO all INFO memory INFO stats INFO replication INFO clients # Real-time monitoring MONITOR # Shows all commands (use carefully in production) # Client connections CLIENT LIST CLIENT INFO # Slow query log SLOWLOG GET 10 SLOWLOG LEN SLOWLOG RESET • Key Performance Metrics:** import redis import time def get_redis_metrics(r): info = r.info() metrics = { # Memory 'used_memory': info['used_memory'], 'used_memory_human': info['used_memory_human'], 'mem_fragmentation_ratio': info['mem_fragmentation_ratio'], # Performance 'total_commands_processed': info['total_commands_processed'], 'instantaneous_ops_per_sec': info['instantaneous_ops_per_sec'], 'keyspace_hits': info['keyspace_hits'], 'keyspace_misses': info['keyspace_misses'], # Connections 'connected_clients': info['connected_clients'], 'blocked_clients': info['blocked_clients'] } # Calculate hit ratio total_hits = metrics['keyspace_hits'] + metrics['keyspace_misses'] if total_hits > 0: metrics['hit_ratio'] = metrics['keyspace_hits'] / total_hits return metrics • Memory Analysis:** # Find memory usage by key MEMORY USAGE mykey # Find largest keys redis-cli --bigkeys # Memory stats MEMORY STATS MEMORY DOCTOR • Performance Debugging:** # Latency monitoring def measure_latency(r, iterations=1000): start_time = time.time() for i in range(iterations): r.ping() end_time = time.time() avg_latency = (end_time - start_time) / iterations * 1000 print(f"Average latency: {avg_latency:.2f}ms") return avg_latency **Alerting Thresholds:** • Memory usage > 80% • Hit ratio < 90% • Slow queries > 10ms • Connected clients > 1000 • Memory fragmentation > 1.5 • Blocked clients > 0 **Best Practices:** • Set up comprehensive monitoring • Use slow query log • Monitor memory usage and fragmentation • Track key performance metrics • Set up alerts for critical thresholds

Question:
Explain Redis replication setup and best practices.
Answer:
Redis replication provides data redundancy and read scaling: **Master Configuration:** # redis-master.conf bind 192.168.1.100 port 6379 requirepass master_password masterauth master_password repl-diskless-sync no repl-ping-replica-period 10 **Replica Configuration:** # redis-replica.conf bind 192.168.1.101 port 6379 replicaof 192.168.1.100 6379 masterauth master_password requirepass replica_password replica-read-only yes **Dynamic Replication:** # Make server a replica REPLICAOF 192.168.1.100 6379 CONFIG SET masterauth master_password # Stop replication REPLICAOF NO ONE # Check replication status INFO replication **Python Client with Read/Write Splitting:** class RedisCluster: def __init__(self, master_host, replica_hosts, password): self.master = redis.Redis(host=master_host, password=password) self.replicas = [redis.Redis(host=h, password=password) for h in replica_hosts] self.replica_index = 0 def write(self, key, value, **kwargs): return self.master.set(key, value, **kwargs) def read(self, key): if not self.replicas: return self.master.get(key) replica = self.replicas[self.replica_index] self.replica_index = (self.replica_index + 1) % len(self.replicas) try: return replica.get(key) except redis.ConnectionError: return self.master.get(key) **Best Practices:** • Use dedicated network for replication • Configure appropriate timeouts • Monitor replication lag • Use diskless replication for fast networks • Test failover scenarios regularly

Question:
How do you tune Redis performance for high-throughput applications?
Answer:
Redis performance tuning strategies: • Configuration Optimization:** # redis.conf optimizations # Memory maxmemory 2gb maxmemory-policy allkeys-lru # Networking tcp-keepalive 300 timeout 0 tcp-backlog 511 # Persistence save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes # Slow log slowlog-log-slower-than 10000 slowlog-max-len 128 • Client-Side Optimizations:** # Connection pooling pool = redis.ConnectionPool( host='localhost', port=6379, max_connections=50, retry_on_timeout=True ) r = redis.Redis(connection_pool=pool) # Pipelining for bulk operations pipe = r.pipeline(transaction=False) for i in range(1000): pipe.set(f'key:{i}', f'value:{i}') results = pipe.execute() # Use appropriate data structures # Hash for objects r.hmset('user:1000', {'name': 'John', 'email': 'john@example.com'}) # Sorted sets for rankings r.zadd('leaderboard', {'player1': 1500, 'player2': 1200}) • Memory Optimization:** # Compression settings hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 set-max-intset-entries 512 zset-max-ziplist-entries 128 # Monitor memory usage INFO memory MEMORY USAGE key redis-cli --bigkeys • Monitoring and Alerting:** def monitor_performance(): info = r.info() # Key metrics to track ops_per_sec = info['instantaneous_ops_per_sec'] memory_usage = info['used_memory'] hit_ratio = info['keyspace_hits'] / (info['keyspace_hits'] + info['keyspace_misses']) connected_clients = info['connected_clients'] # Alert thresholds if ops_per_sec > 100000: print('High load detected') if hit_ratio < 0.9: print('Low cache hit ratio') if connected_clients > 1000: print('High client connections') • Scaling Strategies:** • Use Redis Cluster for horizontal scaling • Implement read replicas for read-heavy workloads • Use Redis Sentinel for high availability • Consider Redis modules for specialized use cases **Performance Testing:** # Benchmark Redis performance redis-benchmark -h localhost -p 6379 -n 100000 -c 50 redis-benchmark -t set,get -n 100000 -q

Question:
How does Redis Cluster handle data distribution and failover?
Answer:
Redis Cluster uses hash slots for data distribution and automatic failover: **Hash Slot Distribution:** • 16384 total hash slots (0-16383) • Each key mapped to slot using CRC16(key) % 16384 • Slots distributed across master nodes • Each master handles subset of slots **Cluster Setup:** # Create 6-node cluster (3 masters + 3 replicas) redis-cli --cluster create \ 192.168.1.100:7000 192.168.1.101:7000 192.168.1.102:7000 \ 192.168.1.100:7001 192.168.1.101:7001 192.168.1.102:7001 \ --cluster-replicas 1 **Node Configuration:** # redis-cluster.conf port 7000 cluster-enabled yes cluster-config-file nodes-7000.conf cluster-node-timeout 15000 cluster-announce-ip 192.168.1.100 **Client Implementation:** from rediscluster import RedisCluster startup_nodes = [ {"host": "192.168.1.100", "port": "7000"}, {"host": "192.168.1.101", "port": "7000"}, {"host": "192.168.1.102", "port": "7000"} ] rc = RedisCluster( startup_nodes=startup_nodes, decode_responses=True, skip_full_coverage_check=True ) # Multi-key operations with hash tags rc.set("{user:1000}:profile", "data") rc.set("{user:1000}:settings", "config") # Both keys go to same slot/node **Failover Process:** 1. Nodes ping each other every second 2. Node marked as PFAIL after timeout 3. Becomes FAIL when majority agrees 4. Replica detects master failure 5. Replica starts election 6. Gets votes from other masters 7. Becomes new master if majority votes **Manual Operations:** # Check cluster status redis-cli -c -p 7000 CLUSTER NODES redis-cli -c -p 7000 CLUSTER SLOTS # Manual failover redis-cli -c -p 7001 CLUSTER FAILOVER # Add new node redis-cli --cluster add-node 192.168.1.103:7000 192.168.1.100:7000 # Reshard slots redis-cli --cluster reshard 192.168.1.100:7000 **Best Practices:** • Odd number of masters (3, 5, 7) • At least 1 replica per master • Use hash tags for related keys • Monitor cluster state continuously • Plan for slot migration

Question:
What are Redis memory management and eviction policies?
Answer:
Redis memory management and eviction strategies: **Memory Policies:** # redis.conf maxmemory 2gb maxmemory-policy allkeys-lru **Eviction Policies:** • allkeys-lru**: Remove least recently used keys • allkeys-lfu**: Remove least frequently used keys • allkeys-random**: Remove random keys • volatile-lru**: Remove LRU keys with expire set • volatile-lfu**: Remove LFU keys with expire set • volatile-random**: Remove random keys with expire set • volatile-ttl**: Remove keys with shortest TTL • noeviction**: Return errors when memory limit reached **Memory Monitoring:** # Check memory usage INFO memory MEMORY USAGE key MEMORY STATS # Find memory-hungry keys redis-cli --bigkeys redis-cli --memkeys **Memory Optimization Techniques:** # 1. Use appropriate data structures # Hash for small objects (more memory efficient) r.hmset('user:1000', { 'name': 'John', 'email': 'john@example.com', 'age': 30 }) # 2. Set expiration on temporary data r.setex('session:abc123', 3600, session_data) r.expire('cache:product:456', 1800) # 3. Use compression for large values import gzip import json data = json.dumps(large_object) compressed = gzip.compress(data.encode()) r.set('large:object:1', compressed) # 4. Efficient key naming # Bad: "user:profile:personal:information:1000" # Good: "u:p:1000" **Memory Configuration:** # Compression settings hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 # Memory sampling maxmemory-samples 5 **Monitoring Script:** def monitor_memory(): info = r.info('memory') used_memory = info['used_memory'] max_memory = info.get('maxmemory', 0) fragmentation = info['mem_fragmentation_ratio'] if max_memory > 0: usage_percent = (used_memory / max_memory) * 100 if usage_percent > 80: print(f"High memory usage: {usage_percent:.1f}%") if fragmentation > 1.5: print(f"High fragmentation: {fragmentation:.2f}") # Check for large keys large_keys = [] for key in r.scan_iter(count=1000): size = r.memory_usage(key) if size and size > 1024 * 1024: # 1MB large_keys.append((key, size)) if large_keys: print(f"Found {len(large_keys)} large keys") **Best Practices:** • Set appropriate maxmemory limit • Choose eviction policy based on use case • Monitor memory usage and fragmentation • Use TTL on temporary data • Optimize data structures • Regular memory analysis

Question:
How do you implement Redis Modules and use RedisJSON?
Answer:
Redis Modules extend Redis with custom data types and commands, while RedisJSON adds native JSON support.\n\n• **What are Redis Modules?**\nPluggable extensions that add new functionality to Redis without modifying core code. Popular modules include RedisJSON, RediSearch, and RedisGraph.\n\n• **RedisJSON Benefits:**\nStores JSON as native data type, supports JSONPath queries, atomic updates on nested fields, and eliminates serialization overhead.\n\n• **Installation:**\nLoad module: redis-server --loadmodule ./rejson.so\nOr in config: loadmodule /path/to/rejson.so\n\n• **Basic RedisJSON Operations:**\nJSON.SET user:1000 . {"name":"John", "age":30}\nJSON.GET user:1000 .name\nJSON.SET user:1000 .age 31\nJSON.ARRAPPEND user:1000 .skills "Redis"\n\n• **Python Example:**\nimport rejson\nrj = rejson.Client()\nrj.jsonset("product:123", ".", {"name":"Laptop", "price":999})\nname = rj.jsonget("product:123", ".name")\n\n• **Use Cases:**\nDocument storage, configuration management, real-time analytics, API response caching, and user profiles.\n\n• **Performance Advantage:**\nDirect JSON manipulation without full document retrieval, atomic operations on nested data, and reduced network overhead.

Question:
How do you integrate Redis with microservices architecture?
Answer:
Redis serves as shared infrastructure for microservices, providing caching, session management, and inter-service communication.\n\n• **Shared Cache Layer:**\nCentral cache accessible by all services, reduces database load, improves response times, and ensures data consistency across services.\n\n• **Session Management:**\nDistributed sessions stored in Redis, enables stateless services, supports load balancing, and provides session persistence across deployments.\n\n• **Inter-Service Communication:**\nPub/Sub for real-time messaging, Redis Streams for event sourcing, and message queues for asynchronous processing.\n\n• **Implementation Example:**\nclass UserService:\n def get_user(self, user_id):\n cached = redis.get(f"user:{user_id}")\n if cached:\n return json.loads(cached)\n user = database.get_user(user_id)\n redis.setex(f"user:{user_id}", 3600, json.dumps(user))\n return user\n\n• **Distributed Locking:**\nCoordinates access to shared resources, prevents race conditions, ensures data integrity, and manages critical sections across services.\n\n• **Configuration Management:**\nCentralized config storage, real-time updates, feature flags, and environment-specific settings.\n\n• **Best Practices:**\nUse connection pooling, implement circuit breakers, monitor Redis health, secure with authentication, and plan for failover scenarios.

Question:
What are Redis security hardening techniques for production?
Answer:
Redis security involves authentication, network protection, command restrictions, and monitoring to prevent unauthorized access.\n\n• **Authentication Setup:**\nSet strong passwords with requirepass, use ACLs for fine-grained access control, and create user-specific permissions.\n\nrequirepass your_strong_password_here\nuser app_user on >app_password ~app:* +@read +@write -@dangerous\n\n• **Network Security:**\nBind to specific interfaces only, change default port, use firewalls, and implement VPN access for remote connections.\n\nbind 127.0.0.1 10.0.1.100\nport 6380\n\n• **Command Restrictions:**\nDisable dangerous commands like FLUSHALL, CONFIG, and KEYS in production to prevent accidental data loss.\n\nrename-command FLUSHALL ""\nrename-command CONFIG "CONFIG_secret_token"\n\n• **TLS Encryption:**\nEncrypt data in transit, verify client certificates, and use strong cipher suites for secure communication.\n\nport 0\ntls-port 6380\ntls-cert-file /path/to/redis.crt\n\n• **Monitoring and Auditing:**\nEnable logging, monitor failed authentication attempts, track command usage, and set up alerts for suspicious activity.\n\n• **File Permissions:**\nSecure Redis files with proper ownership and permissions to prevent unauthorized access to configuration and data files.\n\n• **Best Practices:**\nRegular security audits, keep Redis updated, use dedicated Redis users, implement backup encryption, and document security procedures.

Question:
How do you implement Redis backup and disaster recovery?
Answer:
Redis backup combines RDB snapshots and AOF logging with automated procedures for data protection and recovery.\n\n• **RDB Snapshots:**\nPoint-in-time backups that create compact binary files, fast to restore, ideal for scheduled backups and disaster recovery.\n\nsave 900 1 # Auto-save every 15 minutes if 1+ keys changed\nBGSAVE # Manual background snapshot\n\n• **AOF (Append Only File):**\nLogs every write operation, provides better durability, allows point-in-time recovery, but creates larger files.\n\nappendonly yes\nappendfsync everysec # Sync every second\n\n• **Automated Backup Script:**\n#!/bin/bash\nredis-cli BGSAVE\ncp /var/lib/redis/dump.rdb /backup/redis_20251005.rdb\naws s3 cp /backup/redis_20251005.rdb s3://backup-bucket/\n\n• **Replication for HA:**\nSet up master-replica configuration, automatic failover with Sentinel, and cross-datacenter replication for disaster recovery.\n\nreplicaof master_host 6379\nmasterauth master_password\n\n• **Recovery Procedures:**\nStop Redis, replace data files, restart service, and verify data integrity after restoration.\n\n• **Monitoring:**\nTrack backup completion, verify file integrity, monitor replication lag, and test restore procedures regularly.\n\n• **Best Practices:**\nCombine RDB and AOF, store backups offsite, encrypt backup files, document recovery procedures, and practice disaster scenarios.

Question:
How do you monitor Redis with Prometheus and Grafana?
Answer:
Redis monitoring uses exporters to collect metrics, Prometheus for storage, and Grafana for visualization and alerting.\n\n• **Redis Exporter Setup:**\nCollects Redis metrics and exposes them in Prometheus format, monitors multiple instances, and provides comprehensive statistics.\n\ndocker run -d --name redis-exporter \n -p 9121:9121 \n -e REDIS_ADDR=redis://localhost:6379 \n oliver006/redis_exporter\n\n• **Key Metrics to Monitor:**\nOperations per second, memory usage, hit ratio, connected clients, replication lag, and slow query count.\n\n• **Prometheus Configuration:**\nscrape_configs:\n - job_name: redis\n static_configs:\n - targets: ["redis-exporter:9121"]\n scrape_interval: 15s\n\n• **Grafana Dashboard:**\nVisualize performance trends, set up alerts for thresholds, create custom panels, and monitor multiple Redis instances.\n\n• **Alert Rules:**\nHigh memory usage (>80%), low hit ratio (<90%), connection spikes, replication failures, and slow query accumulation.\n\n• **Custom Metrics:**\nBusiness-specific counters, queue lengths, cache effectiveness, and application performance indicators.\n\n• **Benefits:**\nReal-time monitoring, historical analysis, proactive alerting, capacity planning, and performance optimization insights.\n\n• **Best Practices:**\nSet appropriate alert thresholds, create runbooks for common issues, monitor both system and business metrics, and regularly review dashboards.

Question:
How do you implement Redis time series data management?
Answer:
Redis handles time series data using RedisTimeSeries module or native data structures for storing and querying time-based data.\n\n• **RedisTimeSeries Module:**\nPurpose-built for time series data, supports automatic downsampling, retention policies, and efficient range queries.\n\nTS.CREATE temperature RETENTION 86400000 LABELS sensor_id 1\nTS.ADD temperature * 23.5\nTS.RANGE temperature 1609459200000 1609545600000\n\n• **Native Approach with Sorted Sets:**\nUse timestamps as scores, store values as members, leverage Redis built-in commands for time-based operations.\n\nZADD metrics:cpu:20210101 1609459200 75.5\nZRANGEBYSCORE metrics:cpu:20210101 1609459200 1609545600\n\n• **Data Aggregation:**\nCreate downsampled views, calculate averages over time windows, and maintain multiple resolution levels.\n\nTS.CREATERULE source_key dest_key AGGREGATION avg 3600000\n\n• **Python Implementation:**\nimport redis\nfrom redistimeseries.client import Client\n\nrts = Client()\nrts.create("cpu_usage", retention_msecs=86400000)\nrts.add("cpu_usage", "*", 75.5)\ndata = rts.range("cpu_usage", from_time="-1h")\n\n• **Use Cases:**\nIoT sensor data, application metrics, financial market data, system monitoring, and real-time analytics.\n\n• **Performance Benefits:**\nOptimized storage format, fast range queries, automatic data expiration, and built-in aggregation functions.\n\n• **Best Practices:**\nSet appropriate retention periods, use consistent naming conventions, implement proper indexing, and monitor memory usage.

Question:
What are Redis distributed lock patterns and implementations?
Answer:
Redis distributed locks coordinate access to shared resources across multiple processes or servers, preventing race conditions and ensuring data consistency.\n\n• **Why Use Distributed Locks?**\nPrevent concurrent modifications, ensure atomic operations across services, coordinate resource access, and maintain data integrity in distributed systems.\n\n• **Simple Lock Pattern:**\nUse SET with NX (not exists) and EX (expiration) for atomic lock acquisition with automatic cleanup.\n\nSET lock:resource:123 unique_token NX EX 30\nif result == "OK": lock acquired\n\n• **Safe Lock Release:**\nUse Lua script to ensure only lock owner can release, preventing accidental unlocks by other processes.\n\nlocal token = redis.call("GET", KEYS[1])\nif token == ARGV[1] then\n return redis.call("DEL", KEYS[1])\nend\n\n• **Python Implementation:**\nimport redis\nimport uuid\n\nclass RedisLock:\n def acquire(self):\n token = str(uuid.uuid4())\n result = redis.set(self.key, token, nx=True, ex=30)\n return result is not None\n \n def release(self):\n # Use Lua script for safe release\n\n• **Redlock Algorithm:**\nAcquire locks on majority of Redis instances (3, 5, 7) for higher reliability in multi-master setups.\n\n• **Best Practices:**\nAlways set expiration, use unique tokens, implement retry with backoff, monitor lock contention, and consider lock-free alternatives when possible.

Question:
How do you optimize Redis connection pooling strategies?
Answer:
Connection pooling reduces overhead by reusing connections, improves performance, and manages resource usage efficiently in high-traffic applications.\n\n• **Why Connection Pooling Matters:**\nReduces connection establishment overhead, manages concurrent access, prevents connection exhaustion, and improves application response times.\n\n• **Optimal Pool Configuration:**\nMax connections: 2x CPU cores for CPU-bound apps, higher for I/O-bound\nMin idle: 25% of max connections\nConnection timeout: 5-10 seconds\nIdle timeout: 300 seconds\n\n• **Python Connection Pool:**\nimport redis\n\npool = redis.ConnectionPool(\n host="localhost",\n port=6379,\n max_connections=50,\n retry_on_timeout=True,\n socket_keepalive=True,\n health_check_interval=30\n)\n\nredis_client = redis.Redis(connection_pool=pool)\n\n• **Node.js Optimization:**\nconst redis = new Redis({\n host: "localhost",\n maxRetriesPerRequest: 3,\n lazyConnect: true,\n keepAlive: 30000,\n connectTimeout: 10000\n});\n\n• **Monitoring Pool Health:**\nTrack active vs idle connections, monitor connection creation rate, alert on pool exhaustion, and measure connection latency.\n\n• **Performance Tips:**\nUse pipelining to reduce connection usage, implement connection warming, optimize network settings, and use Unix sockets for local connections.\n\n• **Best Practices:**\nSize pools based on load testing, monitor utilization, implement circuit breakers, use separate pools for different workloads, and validate connections regularly.

Question:
What are Redis data migration techniques between versions?
Answer:
Redis data migration ensures smooth transitions between versions, environments, or infrastructure changes while maintaining data integrity and minimizing downtime.\n\n• **Why Migration is Critical:**\nVersion upgrades, infrastructure changes, performance optimization, disaster recovery, and environment synchronization require careful data transfer.\n\n• **RDB-Based Migration:**\nFastest method for large datasets, creates point-in-time snapshots, minimal network usage, but requires downtime.\n\nBGSAVE # Create snapshot\nscp dump.rdb target_server:/var/lib/redis/\n# Stop target Redis, replace file, restart\n\n• **Replication-Based Migration:**\nZero-downtime approach, real-time synchronization, gradual traffic shifting, ideal for production systems.\n\nREPLICAOF source_host source_port # Set up replication\n# Wait for sync completion\nREPLICAOF NO ONE # Promote to master\n\n• **Live Migration with Dual Write:**\nApplication writes to both instances, gradual read traffic shift, rollback capability, requires application changes.\n\n• **Key-by-Key Migration:**\nMIGRATE target_host target_port key 0 5000\n# Atomic transfer with TTL preservation\n\n• **Python Migration Script:**\nfor key in source.scan_iter(match="user:*"):\n key_type = source.type(key)\n ttl = source.ttl(key)\n \n if key_type == "string":\n value = source.get(key)\n target.setex(key, ttl, value) if ttl > 0 else target.set(key, value)\n\n• **Validation Steps:**\nCompare key counts, sample data verification, performance testing, and application functionality validation.\n\n• **Best Practices:**\nTest in staging first, backup before migration, monitor progress, plan rollback procedures, and validate data integrity post-migration.

Question:
How do you troubleshoot Redis performance bottlenecks?
Answer:
Redis performance troubleshooting involves systematic analysis of metrics, identifying bottlenecks, and applying targeted optimizations to restore optimal performance.\n\n• **Common Performance Issues:**\nHigh memory usage, slow queries, network latency, blocking operations, memory fragmentation, and inadequate hardware resources.\n\n• **Essential Monitoring Commands:**\nINFO stats - Operations per second and hit ratio\nINFO memory - Memory usage and fragmentation\nSLOWLOG GET 10 - Identify slow queries\nCLIENT LIST - Check connection status\n\n• **Memory Analysis:**\nredis-cli --bigkeys # Find large keys\nMEMORY USAGE keyname # Check specific key size\nINFO memory | grep fragmentation # Check fragmentation ratio\n\n• **Performance Profiling:**\nimport redis\nimport time\n\ndef measure_latency(redis_client):\n start = time.time()\n redis_client.ping()\n return (time.time() - start) * 1000\n\n# Monitor latency trends\nlatencies = [measure_latency(r) for _ in range(100)]\navg_latency = sum(latencies) / len(latencies)\n\n• **Optimization Strategies:**\nUse pipelining for bulk operations, implement proper key expiration, optimize data structures, enable compression, and tune memory settings.\n\n• **System-Level Checks:**\nCPU usage (top, htop), memory pressure (free -h), disk I/O (iostat), network latency (ping), and swap usage (swapon -s).\n\n• **Configuration Tuning:**\nmaxmemory-policy allkeys-lru\ntcp-keepalive 300\nstop-writes-on-bgsave-error no\n\n• **Best Practices:**\nEstablish performance baselines, monitor key metrics continuously, test optimizations in staging, document changes, and maintain runbooks for common issues.

Question:
How do you integrate Redis with Kubernetes orchestration?
Answer:
Redis on Kubernetes provides scalable, resilient deployments with automated management, persistent storage, and service discovery for containerized applications.\n\n• **Why Redis on Kubernetes?**\nAutomatic scaling, self-healing, rolling updates, persistent storage, service discovery, and consistent deployment across environments.\n\n• **StatefulSet Deployment:**\nEnsures stable network identities, ordered deployment, and persistent storage for Redis instances.\n\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: redis\nspec:\n serviceName: redis\n replicas: 1\n template:\n spec:\n containers:\n - name: redis\n image: redis:7-alpine\n ports:\n - containerPort: 6379\n volumeMounts:\n - name: redis-data\n mountPath: /data\n\n• **Service Configuration:**\napiVersion: v1\nkind: Service\nmetadata:\n name: redis\nspec:\n selector:\n app: redis\n ports:\n - port: 6379\n type: ClusterIP\n\n• **Redis Operator Benefits:**\nAutomated cluster management, backup scheduling, monitoring integration, and high availability setup.\n\nkubectl apply -f redis-operator.yaml\n\n• **Application Connection:**\nimport redis\nimport os\n\nredis_host = os.getenv("REDIS_SERVICE_HOST", "redis")\nr = redis.Redis(host=redis_host, port=6379)\n\n• **Helm Chart Deployment:**\nhelm install my-redis bitnami/redis \n --set auth.password=mypassword \n --set master.persistence.size=8Gi\n\n• **Best Practices:**\nUse StatefulSets for persistence, implement resource limits, set up monitoring, configure persistent volumes, use Redis Operator for complex deployments, and secure with network policies.

Question:
What are Redis enterprise features and capabilities?
Answer:
Redis Enterprise provides advanced features for mission-critical applications, including active-active replication, auto-scaling, and enterprise-grade security.\n\n• **Key Enterprise Advantages:**\n99.999% uptime SLA, linear scalability, advanced security, multi-cloud deployment, and 24/7 enterprise support.\n\n• **Active-Active Geo-Replication:**\nMulti-master setup across regions, conflict-free data types (CRDTs), automatic conflict resolution, and global data consistency.\n\n• **Redis on Flash (RoF):**\nHot data in RAM, warm data on SSD, automatic tiering, significant cost reduction for large datasets, maintains Redis performance.\n\n• **Auto-Scaling Features:**\nAutomatic horizontal scaling, zero-downtime operations, predictive scaling, resource optimization, and intelligent shard rebalancing.\n\n• **Advanced Security:**\nRole-based access control (RBAC), LDAP integration, data encryption at rest and in transit, audit logging, and compliance certifications.\n\n• **Multi-Tenancy Support:**\nDatabase isolation, per-tenant monitoring, custom eviction policies, resource quotas, and tenant-specific backups.\n\n• **Enterprise Clustering:**\nLinear scalability to hundreds of nodes, cross-slot operations, zero-downtime maintenance, and advanced placement policies.\n\n• **Backup and Recovery:**\nIncremental backups, point-in-time recovery, cross-region replication, automated scheduling, and backup encryption.\n\n• **Monitoring and Management:**\nComprehensive dashboards, predictive analytics, capacity planning, performance tuning automation, and integration with monitoring systems.\n\n• **Use Cases:**\nReal-time personalization, high-frequency trading, global session management, IoT data processing, and mission-critical applications requiring maximum uptime.

Question:
How do you implement Redis performance benchmarking?
Answer:
Redis benchmarking measures performance characteristics, identifies bottlenecks, and validates system capacity under various load conditions.\n\n• **Why Benchmark Redis?**\nValidate performance expectations, identify optimal configurations, plan capacity, compare hardware options, and establish performance baselines.\n\n• **Built-in Benchmarking Tool:**\nredis-benchmark provides comprehensive testing with various parameters and realistic workload simulation.\n\nredis-benchmark -h localhost -p 6379 -n 100000 -c 50\nredis-benchmark -t set,get -n 100000 -q # Quiet mode\nredis-benchmark -P 16 -n 100000 -t set,get # Pipeline\n\n• **Key Parameters:**\n-c clients (concurrent connections)\n-n requests (total operations)\n-d data size (payload size)\n-t tests (specific operations)\n-P pipeline (batch requests)\n\n• **Custom Benchmarking:**\nimport redis\nimport time\n\ndef benchmark_operation(redis_client, operation, iterations=10000):\n start_time = time.time()\n \n for i in range(iterations):\n if operation == "set":\n redis_client.set(f"bench:key:{i}", f"value:{i}")\n elif operation == "get":\n redis_client.get(f"bench:key:{i % 1000}")\n \n total_time = time.time() - start_time\n ops_per_second = iterations / total_time\n \n return ops_per_second\n\n• **Pipeline Benchmarking:**\npipe = redis_client.pipeline()\nfor i in range(1000):\n pipe.set(f"pipe:key:{i}", f"value:{i}")\nresults = pipe.execute()\n\n• **Load Testing Tools:**\nmemtier_benchmark -s localhost -p 6379 -n 100000 -c 50\n# Advanced load testing with realistic patterns\n\n• **Metrics to Measure:**\nThroughput (ops/sec), latency (response time), memory usage, CPU utilization, and network bandwidth.\n\n• **Best Practices:**\nTest on production-like hardware, use realistic data sizes, measure under various loads, establish baselines, and automate regression testing.

Question:
What are Redis scalability patterns for large applications?
Answer:
Redis scalability patterns enable handling massive workloads through horizontal scaling, read replicas, intelligent caching, and architectural optimizations.\n\n• **Why Scalability Matters:**\nHandle growing user bases, manage increasing data volumes, maintain performance under load, and support global applications.\n\n• **Horizontal Scaling with Clustering:**\nRedis Cluster automatically shards data across nodes, provides linear scalability, and handles failover transparently.\n\n16384 hash slots distributed across masters\nAutomatic data partitioning\nClient-side routing for optimal performance\n\n• **Read Scaling with Replicas:**\nMultiple read replicas per master, geographic distribution, load balancing, and eventual consistency trade-offs.\n\nMaster handles writes\nReplicas serve read traffic\nLoad balancer distributes read requests\n\n• **Application-Level Sharding:**\nCustom partitioning logic, consistent hashing, business rule-based distribution, and cross-shard operation handling.\n\ndef get_shard(key):\n return hash(key) % num_shards\n\nwrite_redis = shards[get_shard(user_id)]\nwrite_redis.set(f"user:{user_id}", data)\n\n• **Caching Layer Architecture:**\nMulti-tier caching (L1: local, L2: Redis), cache-aside pattern, write-through/write-behind strategies, and intelligent cache warming.\n\n• **Performance Optimization:**\nPipelining for bulk operations, Lua scripting for atomic operations, connection multiplexing, and asynchronous processing.\n\n• **Auto-Scaling Implementation:**\nMonitor key metrics (memory, CPU, ops/sec), automatic node provisioning, data rebalancing, and predictive scaling.\n\n• **Best Practices:**\nDesign for horizontal scaling from start, implement proper monitoring, test scaling scenarios regularly, optimize for access patterns, and plan for graceful degradation.

Question:
How do you implement Redis cache warming strategies?
Answer:
Cache warming pre-populates Redis with frequently accessed data to ensure optimal performance, reduce database load, and improve user experience.\n\n• **Why Cache Warming is Important:**\nPrevents cache misses after restarts, ensures consistent performance, reduces database load spikes, and improves user experience during peak times.\n\n• **Proactive Warming Strategies:**\nScheduled warming during low-traffic periods, predictive warming based on usage patterns, and application startup warming.\n\n• **Application Startup Warming:**\nclass CacheWarmer:\n def warm_critical_data(self):\n # Warm user data\n active_users = db.get_active_users(limit=10000)\n for user in active_users:\n user_data = db.get_user(user.id)\n redis.setex(f"user:{user.id}", 3600, json.dumps(user_data))\n \n # Warm product catalog\n popular_products = db.get_popular_products(limit=5000)\n for product in popular_products:\n redis.setex(f"product:{product.id}", 7200, json.dumps(product))\n\n• **Scheduled Warming:**\nimport schedule\n\ndef daily_cache_warm():\n warmer.warm_product_catalog()\n warmer.warm_configuration_data()\n\nschedule.every().day.at("02:00").do(daily_cache_warm)\nschedule.every().hour.do(warmer.warm_user_data)\n\n• **Intelligent Warming:**\nAnalyze access patterns, predict future requests, warm seasonal data, and prioritize high-value content.\n\n• **Background Refresh:**\nMonitor TTL values, schedule refresh before expiration, use background workers, and implement non-blocking updates.\n\n• **Progressive Warming:**\nBatch processing with rate limiting, priority-based loading, progress tracking, and resource usage monitoring.\n\n• **Best Practices:**\nWarm during low-traffic periods, prioritize frequently accessed data, monitor warming effectiveness, implement progress tracking, and measure cache hit ratio improvements.

Question:
How do you implement Redis high availability with automatic failover?
Answer:
Redis high availability ensures continuous service through automatic failover, eliminating single points of failure and maintaining data consistency.\n\n• **Why High Availability Matters:**\nMinimizes downtime, ensures business continuity, maintains user experience, protects against hardware failures, and supports SLA requirements.\n\n• **Redis Sentinel Architecture:**\nMonitors master and replicas, detects failures automatically, performs failover elections, and provides service discovery for clients.\n\nMinimum 3 Sentinels for quorum\nAutomatic master promotion\nClient notification of topology changes\n\n• **Sentinel Configuration:**\nport 26379\nsentinel monitor mymaster 192.168.1.100 6379 2\nsentinel down-after-milliseconds mymaster 5000\nsentinel failover-timeout mymaster 10000\n\n• **Master-Replica Setup:**\n# Master\nrequirepass strongpassword\n\n# Replica\nreplicaof 192.168.1.100 6379\nmasterauth strongpassword\nreplica-read-only yes\n\n• **Client-Side Failover:**\nfrom redis.sentinel import Sentinel\n\nsentinel = Sentinel([("host1", 26379), ("host2", 26379)])\nmaster = sentinel.master_for("mymaster", password="pass")\nreplica = sentinel.slave_for("mymaster", password="pass")\n\n# Automatic failover handling\nmaster.set("key", "value") # Writes to current master\nvalue = replica.get("key") # Reads from replica\n\n• **Failover Process:**\nSentinels detect master failure, reach quorum agreement, elect new master, reconfigure replicas, and notify clients.\n\n• **Monitoring and Alerting:**\nTrack failover events, monitor replication lag, alert on topology changes, and validate data consistency.\n\n• **Best Practices:**\nDeploy Sentinels on separate servers, use odd numbers (3, 5, 7), test failover scenarios regularly, implement proper client retry logic, and document recovery procedures.
Study Tips
  • Read each question carefully
  • Try to answer before viewing the solution
  • Practice explaining concepts out loud
  • Review regularly to reinforce learning
Share & Practice

Found this helpful? Share with others!

Feedback