Redis ความพร้อมใช้งานสูงในการผลิต: ตัวดำเนินการ Sentinel, Cluster และ Kubernetes
Redis HA พร้อม Sentinel, โหมดคลัสเตอร์ และผู้ดำเนินการ Kubernetes
Redis เป็นแกนหลักของโครงสร้างพื้นฐานแอปพลิเคชันสมัยใหม่ โดยทำหน้าที่เป็นแคช, ที่จัดเก็บเซสชัน, นายหน้าข้อความ, ตัวจำกัดอัตรา, กลไกกระดานผู้นำ และไปป์ไลน์การวิเคราะห์แบบเรียลไทม์สำหรับแอปพลิเคชันนับล้านทั่วโลก อินสแตนซ์ Redis เดียวสามารถรองรับการดำเนินการนับแสนรายการต่อวินาทีด้วยเวลาแฝงที่ต่ำกว่ามิลลิวินาที แต่อินสแตนซ์เดียวก็เป็นจุดล้มเหลวเพียงจุดเดียวเช่นกัน เมื่อ Redis หยุดทำงาน แอปพลิเคชันจะประสบกับความล้มเหลวแบบเรียงซ้อน: แคชที่ล้นเหลือฐานข้อมูลแบ็กเอนด์ เซสชันสูญหาย ตัวจำกัดอัตราหยุดทำงาน และฟีเจอร์แบบเรียลไทม์ปิดตัวลง การสร้างการปรับใช้ Redis ที่มีความพร้อมใช้งานสูงไม่ใช่ทางเลือกสำหรับระบบที่ใช้งานจริง แต่เป็นข้อกำหนดทางวิศวกรรม
คู่มือนี้เป็นการเจาะลึกที่เน้นการใช้งานจริงอย่างครอบคลุมเกี่ยวกับความพร้อมใช้งานสูงของ Redis เราจะครอบคลุมพื้นฐานการจำลอง Redis (การจำลองแบบอะซิงโครนัส คำสั่ง WAIT และการซิงโครไนซ์ใหม่บางส่วน), Redis Sentinel สำหรับการเฟลโอเวอร์และการค้นพบบริการอัตโนมัติ, คลัสเตอร์ Redis สำหรับการปรับขนาดแนวนอนพร้อมการกระจายสล็อตแฮช, ตัวดำเนินการ Kubernetes (Spotahome, OpsTree และ Redis Enterprise), กลยุทธ์การคงอยู่ (สแน็ปช็อต RDB, AOF และการคงอยู่แบบไฮบริด), การใช้งานที่จัดการบนคลาวด์บน AWS ElastiCache, Azure Cache สำหรับ Redis และ GCP Memorystore, การปรับใช้ k3s แบบ Bare Metal พร้อม Rancher และ Longhorn, การจัดการหน่วยความจำและนโยบายการขับไล่, การเข้ารหัส TLS และการควบคุมการเข้าถึงตาม ACL, ลักษณะการทำงานของ Pub/Sub และ Streams ในการกำหนดค่า HA, โมดูล Redis (RedisJSON, RediSearch, RedisTimeSeries) ใน HA, การรวมการเชื่อมต่อและการกำหนดค่าไคลเอนต์สำหรับความยืดหยุ่นในการเปลี่ยนระบบ กลยุทธ์การสำรองและกู้คืน การตรวจสอบด้วย Redis INFO, Prometheus ผู้ส่งออก และแดชบอร์ด Grafana, Dragonfly และ KeyDB เป็นทางเลือกที่เข้ากันได้กับ Redis, การปรับแต่งประสิทธิภาพด้วยไปป์ไลน์, สคริปต์ Lua และการเพิ่มประสิทธิภาพหน่วยความจำ, สถานการณ์ความล้มเหลวทั่วไปและขั้นตอนการแก้ไขปัญหา และการวางแผนความจุและกลยุทธ์การปรับขนาด
Redis พื้นฐานการจำลอง
การจำลองRedis เป็นรากฐานในการสร้างสถาปัตยกรรมที่มีความพร้อมใช้งานสูงทั้งหมด อินสแตนซ์หลัก Redis ยอมรับการเขียนและเผยแพร่แบบอะซิงโครนัสไปยังอินสแตนซ์จำลองหนึ่งรายการขึ้นไป การจำลองจะรักษาสำเนาชุดข้อมูลของต้นแบบที่เกือบจะเรียลไทม์และให้บริการการสืบค้นการอ่าน โดยให้ทั้งความซ้ำซ้อนของข้อมูลและความสามารถในการปรับขนาดการอ่าน
ต่างจากการจำลองแบบสตรีมมิ่งแบบ WAL ของ PostgreSQL Redis ใช้โปรโตคอลการจำลองแบบตามคำสั่ง คำสั่งการเขียนทุกคำสั่งที่ดำเนินการบนต้นแบบจะถูกทำให้เป็นอนุกรมในสตรีมการจำลอง และส่งไปยังเรพลิกาที่เชื่อมต่อ ซึ่งดำเนินการคำสั่งเดียวกันกับชุดข้อมูลในเครื่อง วิธีการนี้เรียบง่ายและมีประสิทธิภาพ แต่มีนัยสำคัญต่อความสอดคล้อง เนื่องจากการจำลองเป็นแบบอะซิงโครนัสตามค่าเริ่มต้น มักจะมีหน้าต่างที่การเขียนที่ได้รับการยอมรับบนต้นแบบยังไม่ถึงแบบจำลองเสมอ
การจำลองแบบอะซิงโครนัสและคำสั่ง WAIT
ตามค่าเริ่มต้น การจำลองแบบ Redis เป็นแบบอะซิงโครนัสโดยสมบูรณ์ ต้นแบบรับทราบการเขียนถึงไคลเอนต์ทันทีหลังจากนำไปใช้ในเครื่อง โดยไม่ต้องรอแบบจำลองใด ๆ เพื่อยืนยันการรับ ซึ่งให้ปริมาณการประมวลผลการเขียนสูงสุด แต่ทำให้เกิดกรอบเวลาข้อมูลสูญหาย หากต้นแบบขัดข้องก่อนที่การเขียนจะไปถึงแบบจำลองใดๆ การเขียนนั้นจะสูญหายไป
คำสั่งWAITจัดเตรียมเรพลิเคชันดั้งเดิมแบบซิงโครนัส หลังจากออกการเขียน ไคลเอ็นต์สามารถเรียกWAIT numreplicas timeoutเพื่อบล็อกจนกว่าจำนวนเรพลิกาที่ระบุจะรับทราบการเขียน หรือการหมดเวลาหมดอายุ สิ่งนี้ไม่ได้ทำให้ Redis ซิงโครนัสอย่างสมบูรณ์ —WAITรับประกันว่าแบบจำลองได้รับข้อมูลเท่านั้น ไม่ใช่ว่าข้อมูลนั้นยังคงอยู่ในดิสก์บนแบบจำลอง อย่างไรก็ตาม จะช่วยลดช่วงข้อมูลสูญหายได้อย่างมาก
# Write a critical value and wait for 2 replicas to acknowledge
SET order:12345 '{"status":"confirmed","amount":599.99}'
WAIT 2 5000
# Returns the number of replicas that acknowledged within 5000ms
# Returns 0 if no replica acknowledged (timeout or no replicas connected)ใช้WAITแบบคัดเลือกสำหรับการเขียนที่สำคัญ (ธุรกรรมทางการเงิน การยืนยันคำสั่งซื้อ) ในขณะที่อนุญาตให้เขียนที่ไม่สำคัญ (การอัปเดตแคช การรีเฟรชเซสชัน) เพื่อดำเนินการแบบอะซิงโครนัส ความยืดหยุ่นต่อคำสั่งหลีกเลี่ยงโทษเวลาแฝงของการจำลองแบบซิงโครนัสแบบเต็ม
การซิงโครไนซ์บางส่วน (PSYNC)
เมื่อเรพลิกาตัดการเชื่อมต่อในช่วงสั้นๆ (เครือข่ายขัดข้อง ให้รีสตาร์ท) ไม่จำเป็นต้องถ่ายโอนชุดข้อมูลทั้งหมดเพื่อเข้าร่วมอีกครั้ง Redis จะรักษา Backlog การจำลองข้อมูล — บัฟเฟอร์แบบวงกลมของคำสั่งการเขียนล่าสุด — บนต้นแบบ เมื่อเรพลิกาเชื่อมต่อใหม่ ระบบจะส่งออฟเซ็ตการจำลองแบบไปยังต้นแบบ หากออฟเซ็ตยังอยู่ใน Backlog ต้นแบบจะส่งเฉพาะคำสั่งที่หายไป (ซิงค์ซ้ำบางส่วน) หากออฟเซ็ตอยู่นอก Backlog การซิงโครไนซ์ใหม่ทั้งหมดจะถูกทริกเกอร์ ซึ่งเกี่ยวข้องกับการสร้างและถ่ายโอนสแน็ปช็อต RDB
# redis.conf — Replication backlog configuration
repl-backlog-size 256mb # Size of the replication backlog buffer
repl-backlog-ttl 3600 # Seconds to retain backlog after last replica disconnects
repl-diskless-sync yes # Transfer RDB via socket instead of disk (faster for full sync)
repl-diskless-sync-delay 5 # Wait 5s for more replicas before starting diskless sync
repl-diskless-sync-period 0 # No periodic full sync
repl-diskless-load on-empty-db # Replica loads RDB from socket directly into memoryการกำหนดขนาด Backlog ของการจำลองอย่างถูกต้องถือเป็นสิ่งสำคัญ ควรมีขนาดใหญ่พอที่จะเก็บคำสั่งการเขียนทั้งหมดที่สร้างขึ้นระหว่างการตัดการเชื่อมต่อเรพลิกาที่คาดไว้นานที่สุด สำหรับอินสแตนซ์ Redis ที่ประมวลผลการรับส่งข้อมูลการเขียน 50MB/s งานในมือขนาด 256MB ครอบคลุมการเขียนประมาณ 5 วินาที ให้เพิ่มหากแบบจำลองของคุณอาจออฟไลน์เป็นระยะเวลานานขึ้น
การกำหนดค่าการจำลองแบบจำลองหลัก
# redis.conf — Master configuration
bind 0.0.0.0
port 6379
protected-mode no
requirepass strong_master_password
masterauth strong_master_password
# Persistence
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
# Replication
repl-backlog-size 256mb
repl-backlog-ttl 3600
repl-diskless-sync yes
min-replicas-to-write 1 # Refuse writes if fewer than 1 replica connected
min-replicas-max-lag 10 # Replica considered disconnected if lag > 10 seconds# redis.conf — Replica configuration
bind 0.0.0.0
port 6379
protected-mode no
requirepass strong_master_password
masterauth strong_master_password
replicaof master-host 6379
replica-read-only yes
replica-serve-stale-data yes # Serve (possibly stale) data during sync
replica-priority 100 # Lower values get promoted first by Sentinelการตั้งค่าmin-replicas-to-writeและmin-replicas-max-lagป้องกันไม่ให้ต้นแบบยอมรับการเขียน เมื่อไม่สามารถรับประกันความทนทานของข้อมูลในแบบจำลองได้ นี่คือเครือข่ายความปลอดภัยที่สำคัญ หากไม่มีสิ่งนี้ ต้นแบบที่แบ่งพาร์ติชันเครือข่ายจะยังคงยอมรับการเขียนที่จะหายไปเมื่อ Sentinel ส่งเสริมการจำลอง
Redis Sentinel: การเฟลโอเวอร์อัตโนมัติและการค้นพบบริการ
Redis Sentinel คือระบบแบบกระจายที่ตรวจสอบอินสแตนซ์ต้นแบบและแบบจำลอง Redis ตรวจจับความล้มเหลวของต้นแบบ ดำเนินการเฟลโอเวอร์อัตโนมัติโดยเลื่อนระดับแบบจำลองให้เป็นต้นแบบ และมอบการค้นพบบริการเพื่อให้ไคลเอ็นต์สามารถค้นหาต้นแบบปัจจุบันได้ตลอดเวลา Sentinel ทำงานเป็นกระบวนการที่แยกจากกันควบคู่ไปกับ Redis และทำงานผ่านโปรโตคอลที่เป็นเอกฉันท์ - องค์ประชุมของอินสแตนซ์ Sentinel ต้องยอมรับว่าไม่สามารถเข้าถึงต้นแบบได้ก่อนที่จะเริ่มเฟลโอเวอร์
การกำหนดค่าแมวมอง
Sentinel ต้องการอินสแตนซ์อย่างน้อยสามอินสแตนซ์เพื่อทนต่อความล้มเหลวของ Sentinel หนึ่งรายการและยังคงรักษาองค์ประชุมไว้ Sentinel แต่ละตัวจะตรวจสอบ Redis ต้นแบบคนเดียวกัน และสื่อสารกับ Sentinel อื่นๆ ผ่านทางระเบียบการซุบซิบเพื่อตกลงเกี่ยวกับสถานะสุขภาพของต้นแบบ
# /etc/redis/sentinel.conf — Sentinel instance configuration
port 26379
bind 0.0.0.0
protected-mode no
# Monitor the master named "mymaster" at 10.0.1.10:6379
# The quorum value (2) means 2 Sentinels must agree the master is down
sentinel monitor mymaster 10.0.1.10 6379 2
# Authentication
sentinel auth-pass mymaster strong_master_password
# Timing parameters
sentinel down-after-milliseconds mymaster 5000 # SDOWN after 5s of no PING response
sentinel failover-timeout mymaster 60000 # Max 60s for failover procedure
sentinel parallel-syncs mymaster 1 # Only 1 replica syncs from new master at a time
# Deny script execution for security
sentinel deny-scripts-reconfig yes
# Notification script (called on failover events)
# sentinel notification-script mymaster /opt/redis/notify.sh
# Client reconfiguration script (called when master changes)
# sentinel client-reconfig-script mymaster /opt/redis/reconfig.sh
# Logging
logfile /var/log/redis/sentinel.log
logevel notice
# Enable TLS for Sentinel communication
# tls-port 26379
# port 0
# tls-cert-file /etc/redis/tls/sentinel.crt
# tls-key-file /etc/redis/tls/sentinel.key
# tls-ca-cert-file /etc/redis/tls/ca.crt
# tls-replication yes
# tls-auth-clients optionalการตรวจจับความล้มเหลวของSentinel ทำงานในสองเฟส ขั้นแรก Sentinel แต่ละตัวจะทำเครื่องหมายต้นแบบเป็นSubjectively Down (SDOWN)เมื่อไม่ได้รับการตอบกลับ PING ที่ถูกต้องภายในdown-after-millisecondsจากนั้น เมื่อองค์ประชุมของ Sentinels ยอมรับว่าไม่สามารถเข้าถึงต้นแบบได้ ก็จะถูกทำเครื่องหมายเป็นObjectively Down (ODOWN)และกระบวนการเฟลโอเวอร์จะเริ่มต้นขึ้น Sentinel หนึ่งตัวได้รับเลือกให้เป็นผู้นำเฟลโอเวอร์ ซึ่งจะเลือกเรพลิกาที่ดีที่สุด (ตามลำดับความสำคัญ ออฟเซ็ตการจำลอง และ runid) เลื่อนระดับเป็นมาสเตอร์ กำหนดค่าเรพลิกาที่เหลืออยู่ใหม่เพื่อติดตามต้นแบบใหม่ และอัปเดตสถานะ Sentinel
การค้นหาบริการ Sentinel และการกำหนดค่าไคลเอ็นต์
ข้อได้เปรียบที่สำคัญของ Sentinel เหนือการตั้งค่าแบบจำลองหลักแบบคงที่คือการค้นหาบริการ ไคลเอนต์ไม่ได้เชื่อมต่อกับที่อยู่ Redis แบบคงที่ - พวกเขาขอ Sentinel เกี่ยวกับที่อยู่หลักปัจจุบันและสมัครรับการแจ้งเตือนเมื่อเกิดข้อผิดพลาด ไลบรารีไคลเอ็นต์ Redis หลักทุกรายการรองรับ Sentinel โดยกำเนิด
# Node.js — ioredis with Sentinel support
const Redis = require('ioredis');
const redis = new Redis({
sentinels: [
{ host: '10.0.1.20', port: 26379 },
{ host: '10.0.1.21', port: 26379 },
{ host: '10.0.1.22', port: 26379 }
],
name: 'mymaster',
password: 'strong_master_password',
sentinelPassword: 'sentinel_password',
db: 0,
retryStrategy(times) {
const delay = Math.min(times * 200, 5000);
return delay;
},
reconnectOnError(err) {
const targetError = 'READONLY';
if (err.message.includes(targetError)) {
return true; // Reconnect on READONLY error (failover happened)
}
return false;
},
maxRetriesPerRequest: 3,
enableReadyCheck: true,
connectTimeout: 10000,
lazyConnect: false
});
redis.on('connect', () => console.log('Connected to Redis master'));
redis.on('error', (err) => console.error('Redis error:', err));
redis.on('+switch-master', (msg) => {
console.log('Master switched:', msg);
});# Python — redis-py with Sentinel support
from redis.sentinel import Sentinel
import redis
sentinel = Sentinel(
[('10.0.1.20', 26379), ('10.0.1.21', 26379), ('10.0.1.22', 26379)],
socket_timeout=5,
password='strong_master_password',
sentinel_kwargs={'password': 'sentinel_password'}
)
# Get a connection to the current master (for writes)
master = sentinel.master_for(
'mymaster',
socket_timeout=5,
retry_on_timeout=True,
db=0
)
# Get a connection to a replica (for reads)
replica = sentinel.slave_for(
'mymaster',
socket_timeout=5,
db=0
)
# Usage
master.set('session:user123', '{"logged_in": true}')
result = replica.get('session:user123')
print(result)// Go — go-redis with Sentinel support
package main
import (
"context"
"fmt"
"time"
"github.com/redis/go-redis/v9"
)
func main() {
ctx := context.Background()
rdb := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "mymaster",
SentinelAddrs: []string{"10.0.1.20:26379", "10.0.1.21:26379", "10.0.1.22:26379"},
Password: "strong_master_password",
SentinelPassword: "sentinel_password",
DB: 0,
DialTimeout: 10 * time.Second,
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
PoolSize: 50,
MinIdleConns: 10,
MaxRetries: 3,
MinRetryBackoff: 200 * time.Millisecond,
MaxRetryBackoff: 5 * time.Second,
})
defer rdb.Close()
err := rdb.Set(ctx, "key", "value", 5*time.Minute).Err()
if err != nil {
fmt.Printf("Error: %v
", err)
return
}
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
fmt.Printf("Error: %v
", err)
return
}
fmt.Printf("key = %s
", val)
}คลัสเตอร์Redis: การปรับขนาดแนวนอนพร้อมช่องแฮช
แม้ว่า Sentinel จะให้ความพร้อมใช้งานสูงสำหรับชุดข้อมูลเดียว แต่ Redis Cluster ก็มีทั้ง HA และการปรับขนาดแนวนอน Redis คลัสเตอร์แบ่งพาร์ติชันข้อมูลระหว่างโหนดหลักหลายโหนดโดยใช้กลไกสล็อตแฮช — คีย์สเปซแบ่งออกเป็นสล็อตแฮช 16,384 ช่อง และต้นแบบแต่ละรายการจะรับผิดชอบชุดย่อยของสล็อตเหล่านั้น แต่ละต้นแบบมีแบบจำลองอย่างน้อยหนึ่งรายการสำหรับการเปลี่ยนระบบเมื่อเกิดข้อผิดพลาด คลัสเตอร์โดยรวมจัดให้มีการแบ่งส่วนข้อมูลอัตโนมัติ การเฟลโอเวอร์ในตัว และความสามารถในการปรับขนาดทั้งพื้นที่จัดเก็บข้อมูลและปริมาณงานเชิงเส้นโดยการเพิ่มโหนด
การตั้งค่าคลัสเตอร์ Redis
# Create a 6-node Redis Cluster (3 masters + 3 replicas)
# Each node needs a redis.conf with cluster-enabled
# redis.conf for each cluster node (adjust port per node)
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
requirepass cluster_password
masterauth cluster_password
bind 0.0.0.0
protected-mode no
repl-backlog-size 256mb
# Start all 6 Redis instances
redis-server /etc/redis/7000.conf
redis-server /etc/redis/7001.conf
# ... repeat for all 6 nodes
# Create the cluster
redis-cli --cluster create \
10.0.1.10:7000 10.0.1.11:7000 10.0.1.12:7000 \
10.0.1.13:7000 10.0.1.14:7000 10.0.1.15:7000 \
--cluster-replicas 1 \
-a cluster_password
# Verify cluster status
redis-cli -c -h 10.0.1.10 -p 7000 -a cluster_password cluster info
redis-cli -c -h 10.0.1.10 -p 7000 -a cluster_password cluster nodesการแบ่งส่วนใหม่และการดำเนินการแบบหลายคีย์
การทำ Resharding จะย้ายช่องแฮชระหว่างต้นแบบเพื่อปรับสมดุลข้อมูลหลังจากเพิ่มหรือลบโหนด ในระหว่างการแบ่งพาร์ติชันใหม่ คีย์ในช่องการย้ายข้อมูลอาจได้รับการเปลี่ยนเส้นทาง ASK ซึ่งไคลเอ็นต์จะจัดการอย่างโปร่งใส
# Add a new node to the cluster
redis-cli --cluster add-node 10.0.1.16:7000 10.0.1.10:7000 -a cluster_password
# Reshard slots to the new node
redis-cli --cluster reshard 10.0.1.10:7000 \
--cluster-from all \
--cluster-to NEW_NODE_ID \
--cluster-slots 4096 \
--cluster-yes \
-a cluster_password
# Rebalance the cluster automatically
redis-cli --cluster rebalance 10.0.1.10:7000 -a cluster_password
# Check cluster slot distribution
redis-cli -c -h 10.0.1.10 -p 7000 -a cluster_password cluster slotsการดำเนินการแบบมัลติคีย์ในคลัสเตอร์ Redis จะทำงานเฉพาะเมื่อคีย์ทั้งหมดที่เกี่ยวข้องอยู่ในช่องแฮชเดียวกัน ใช้แฮชแท็กเพื่อให้แน่ใจว่าคีย์ที่เกี่ยวข้องแมปกับช่องเดียวกัน:{user:123}.profileและ{user:123}.sessionsแฮชทั้งคู่บนuser:123รับประกันว่าจะไปอยู่ที่โหนดเดียวกัน ซึ่งเปิดใช้งาน MGET, MSET, ธุรกรรม และสคริปต์ Lua ในคีย์ที่เกี่ยวข้อง
# Hash tags ensure these keys are in the same slot
SET {order:5000}.details '{"item":"widget","qty":3}'
SET {order:5000}.payment '{"method":"card","status":"paid"}'
SET {order:5000}.shipping '{"carrier":"fedex","tracking":"FX123"}'
# Multi-key operations work because all keys share the {order:5000} hash tag
MGET {order:5000}.details {order:5000}.payment {order:5000}.shipping
# Transaction across same-slot keys
MULTI
SET {order:5000}.details '{"item":"widget","qty":3,"status":"confirmed"}'
SET {order:5000}.payment '{"method":"card","status":"captured"}'
EXECRedis โอเปอเรเตอร์สำหรับ Kubernetes
การรัน Redis ใน Kubernetes ต้องใช้ความระมัดระวังในการจัดการพื้นที่จัดเก็บข้อมูลถาวร ข้อมูลประจำตัวของเครือข่าย การเฟลโอเวอร์แบบค่อยเป็นค่อยไป และการจัดการการกำหนดค่า ตัวดำเนินการ Kubernetes เข้ารหัสความรู้ในการปฏิบัติงานนี้ลงในตัวควบคุมแบบกำหนดเองที่จัดการคลัสเตอร์ Redis อย่างชัดเจนผ่าน Custom Resource Definitions (CRD)
Spotahome Redis โอเปอเรเตอร์
ตัวดำเนินการ Spotahome (หรือที่เรียกว่าตัวดำเนินการ Redis) เป็นตัวดำเนินการที่เป็นผู้ใหญ่และใช้กันอย่างแพร่หลายสำหรับการปรับใช้ HA ที่ใช้ Redis Sentinel ใน Kubernetes จัดการชุดแบบจำลองต้นแบบ Redis ด้วยการเปลี่ยนระบบเมื่อเกิดข้อผิดพลาดแบบ Sentinel
# Install the Spotahome Redis Operator
helm repo add spotahome https://spotahome.github.io/redis-operator
helm install redis-operator spotahome/redis-operator \
--namespace redis-system --create-namespace
# RedisFailover CRD — 3 Redis instances + 3 Sentinels
apiVersion: databases.spotahome.com/v1
kind: RedisFailover
metadata:
name: redis-ha
namespace: production
spec:
sentinel:
replicas: 3
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
customConfig:
down-after-milliseconds: "5000"
failover-timeout: "60000"
redis:
replicas: 3
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
cpu: "4"
memory: 16Gi
storage:
persistentVolumeClaim:
metadata:
name: redis-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: longhorn
customConfig:
maxmemory: "6gb"
maxmemory-policy: "allkeys-lru"
save: "900 1 300 10 60 10000"
appendonly: "yes"
appendfsync: "everysec"
aof-use-rdb-preamble: "yes"
repl-backlog-size: "256mb"
exporter:
enabled: true
image: oliver006/redis_exporter:latest
args:
- --include-system-metricsOpsTree Redis โอเปอเรเตอร์
ตัวดำเนินการ OpsTree รองรับทั้งโทโพโลยี Redis Sentinel (HA แบบสแตนด์อโลน) และ Redis Cluster (sharded HA) ทำให้มีความหลากหลายมากขึ้นสำหรับกรณีการใช้งานที่แตกต่างกัน
# Install the OpsTree Redis Operator
helm repo add ot-helm https://ot-container-kit.github.io/helm-charts/
helm install redis-operator ot-helm/redis-operator \
--namespace redis-system --create-namespace
# Redis Cluster CRD — 3 masters + 3 replicas
apiVersion: redis.redis.opstreelabs.in/v1beta2
kind: RedisCluster
metadata:
name: redis-cluster
namespace: production
spec:
clusterSize: 3
clusterVersion: v7
persistenceEnabled: true
kubernetesConfig:
image: redis:7.2-alpine
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
cpu: "4"
memory: 16Gi
redisLeader:
replicas: 3
redisConfig:
additionalRedisConfig: |
maxmemory 6gb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec
redisFollower:
replicas: 3
redisConfig:
additionalRedisConfig: |
maxmemory 6gb
replica-read-only yes
storage:
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: longhorn
redisExporter:
enabled: true
image: quay.io/opstree/redis-exporter:v1.44.0Redis ตัวดำเนินการระดับองค์กร
Redis Enterprise มอบตัวดำเนินการ Kubernetes เชิงพาณิชย์พร้อมฟีเจอร์ขั้นสูง รวมถึงการจำลองทางภูมิศาสตร์แบบ Active-Active (CRDTs), รองรับโมดูล Redis, การจัดระดับอัตโนมัติ (RAM + แฟลช) และการจัดการคลัสเตอร์อัตโนมัติ เป็นตัวเลือกที่แนะนำสำหรับองค์กรที่ต้องการ SLA และการสนับสนุนระดับองค์กร
# Redis Enterprise Operator CRD
apiVersion: app.redislabs.com/v1
kind: RedisEnterpriseCluster
metadata:
name: redis-enterprise
namespace: redis-enterprise
spec:
nodes: 3
persistentSpec:
enabled: true
storageClassName: longhorn
volumeSize: 100Gi
redisEnterpriseNodeResources:
limits:
cpu: "8"
memory: 32Gi
requests:
cpu: "4"
memory: 16Gi
uiServiceType: ClusterIP
servicesRiggerSpec:
databaseServiceType: ClusterIP
---
apiVersion: app.redislabs.com/v1alpha1
kind: RedisEnterpriseDatabase
metadata:
name: redis-ha-db
namespace: redis-enterprise
spec:
memorySize: 10GB
replication: true
shardCount: 3
persistence: aofEverySecond
tlsMode: enabled
modulesList:
- name: search
version: latest
- name: json
version: latestกลยุทธ์การคงอยู่ของ: RDB, AOF และ Hybrid
Redis มีกลไกการคงอยู่สามแบบ การเลือกกลยุทธ์ที่เหมาะสมจะขึ้นอยู่กับวัตถุประสงค์จุดกู้คืน (RPO) ข้อกำหนดด้านประสิทธิภาพ และข้อจำกัดด้านพื้นที่จัดเก็บ
สแนปช็อต RDBสร้างสแนปช็อต ณ เวลาใดเวลาหนึ่งของชุดข้อมูลทั้งหมดตามช่วงเวลาที่กำหนดค่า มีขนาดกะทัดรัด โหลดเร็วเมื่อรีสตาร์ท และเหมาะสำหรับการสำรองข้อมูล อย่างไรก็ตาม ข้อมูลที่เขียนระหว่างสแนปช็อตจะสูญหายเมื่อเกิดข้อขัดข้อง RDB ใช้กระบวนการลูกที่แยกออกมา ดังนั้นการสร้างสแน็ปช็อตจึงไม่บล็อกเธรด Redis หลัก แต่ตัวแยกเองอาจทำให้เกิดความล่าช้าในชุดข้อมูลขนาดใหญ่เนื่องจากการจัดสรรหน่วยความจำแบบคัดลอกเมื่อเขียน
AOF (ผนวกเฉพาะไฟล์)บันทึกทุกการดำเนินการเขียนลงดิสก์ ให้ความทนทานที่ดีกว่า RDB มาก ด้วยappendfsync everysecคุณจะสูญเสียข้อมูลได้มากที่สุดหนึ่งวินาทีเมื่อเกิดข้อขัดข้อง ด้วยappendfsync alwaysคุณจะไม่เสียอะไรเลย แต่ต้องเสียประสิทธิภาพอย่างมาก ไฟล์ AOF มีขนาดใหญ่กว่า RDB และโหลดช้ากว่าเมื่อรีสตาร์ท
การคงอยู่แบบไฮบริด(แนวทางที่แนะนำ) รวมทั้งสองอย่างเข้าด้วยกัน:aof-use-rdb-preamble yesเขียนสแน็ปช็อต RDB ที่จุดเริ่มต้นของไฟล์ AOF ตามด้วยรายการ AOF สำหรับการเขียนครั้งต่อไป ทำให้มีเวลาเริ่มต้นที่รวดเร็ว (ส่วน RDB) พร้อมความทนทานสูง (ส่วน AOF)
# redis.conf — Hybrid persistence (recommended for production)
# RDB snapshots
save 900 1 # Snapshot if at least 1 write in 900 seconds
save 300 10 # Snapshot if at least 10 writes in 300 seconds
save 60 10000 # Snapshot if at least 10000 writes in 60 seconds
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis
# AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec # Best balance of durability and performance
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-use-rdb-preamble yes # Hybrid: RDB preamble + AOF tail
aof-timestamp-enabled yes # Enable timestamps for PITR (Redis 7+)
# Recovery options
rdb-del-sync-files no
aof-load-truncated yesการปรับใช้ Redis ที่จัดการบนคลาวด์
AWS ElastiCache สำหรับ Redis
AWS ElastiCache นำเสนอ Redis ที่มีการจัดการเต็มรูปแบบด้วยโหมด HA สองโหมด:Cluster Mode Disabled(ส่วนแบ่งข้อมูลเดี่ยว, การจำลองสูงสุด 5 รายการ, การเฟลโอเวอร์แบบ Sentinel) และCluster Mode Enabled(ส่วนแบ่งสูงสุดถึง 500 ส่วน โดยแต่ละแบบจำลองมีการจำลองสูงสุด 5 รายการ, การกระจายช่องแฮช) Global Datastore ให้บริการการจำลองแบบข้ามภูมิภาคสำหรับการกู้คืนระบบ
# AWS CLI — Create ElastiCache Redis Cluster Mode Enabled
aws elasticache create-replication-group \
--replication-group-id redis-ha-prod \
--replication-group-description "Production Redis HA Cluster" \
--engine redis \
--engine-version 7.1 \
--cache-node-type cache.r7g.2xlarge \
--num-node-groups 3 \
--replicas-per-node-group 2 \
--automatic-failover-enabled \
--multi-az-enabled \
--at-rest-encryption-enabled \
--transit-encryption-enabled \
--auth-token strong_auth_token \
--cache-subnet-group-name redis-subnet-group \
--security-group-ids sg-0123456789abcdef0 \
--snapshot-retention-limit 7 \
--snapshot-window "03:00-05:00" \
--preferred-maintenance-window "sun:05:00-sun:07:00" \
--cache-parameter-group-name redis-ha-params \
--log-delivery-configurations '[
{"LogType":"slow-log","DestinationType":"cloudwatch-logs","DestinationDetails":{"CloudWatchLogsDetails":{"LogGroup":"/aws/elasticache/redis-ha-prod"}}},
{"LogType":"engine-log","DestinationType":"cloudwatch-logs","DestinationDetails":{"CloudWatchLogsDetails":{"LogGroup":"/aws/elasticache/redis-ha-prod"}}}
]'
# Create Global Datastore for cross-region DR
aws elasticache create-global-replication-group \
--global-replication-group-id-suffix redis-global \
--primary-replication-group-id redis-ha-prod
# Add secondary region
aws elasticache create-replication-group \
--replication-group-id redis-ha-dr \
--replication-group-description "DR Redis in eu-west-2" \
--global-replication-group-id ldgnf-redis-global \
--cache-node-type cache.r7g.2xlarge \
--num-node-groups 3 \
--replicas-per-node-group 1 \
--region eu-west-2
# Custom parameter group for HA tuning
aws elasticache create-cache-parameter-group \
--cache-parameter-group-name redis-ha-params \
--cache-parameter-group-family redis7 \
--description "HA-optimised Redis 7 parameters"
aws elasticache modify-cache-parameter-group \
--cache-parameter-group-name redis-ha-params \
--parameter-name-values \
"ParameterName=maxmemory-policy,ParameterValue=allkeys-lru" \
"ParameterName=timeout,ParameterValue=300" \
"ParameterName=tcp-keepalive,ParameterValue=60" \
"ParameterName=activedefrag,ParameterValue=yes"แคชAzure สำหรับ Redis
แคชAzure สำหรับ Redis มีสามระดับ: พื้นฐาน (ไม่มีการจำลอง), มาตรฐาน (จำลอง) และพรีเมียม/องค์กร ระดับพรีเมี่ยมรองรับการทำคลัสเตอร์ การจำลองทางภูมิศาสตร์ ความซ้ำซ้อนของโซน การแทรก VNet และการคงอยู่ของข้อมูล ระดับองค์กรเพิ่มโมดูล Redis และการกระจายทางภูมิศาสตร์แบบ Active-Active
# Azure CLI — Create Premium Azure Cache for Redis with clustering
az redis create \
--resource-group redis-ha-rg \
--name redis-ha-prod \
--location westeurope \
--sku Premium \
--vm-size P3 \
--shard-count 3 \
--replicas-per-master 1 \
--zones 1 2 3 \
--minimum-tls-version 1.2 \
--redis-version 7
# Enable geo-replication (link primary to secondary)
az redis server-link create \
--name redis-ha-prod \
--resource-group redis-ha-rg \
--server-to-link /subscriptions/.../redis-ha-dr \
--replication-role Secondary
# Configure data persistence
az redis update \
--name redis-ha-prod \
--resource-group redis-ha-rg \
--set redisConfiguration.rdb-backup-enabled=true \
--set redisConfiguration.rdb-backup-frequency=60 \
--set redisConfiguration.rdb-storage-connection-string="DefaultEndpointsProtocol=https;..."
# Enable diagnostics
az monitor diagnostic-settings create \
--name redis-diagnostics \
--resource /subscriptions/.../redis-ha-prod \
--workspace /subscriptions/.../log-analytics-workspace \
--metrics '[{"category":"AllMetrics","enabled":true}]'GCP ที่เก็บหน่วยความจำสำหรับ Redis
GCP มี Memorystore สองระดับ:มาตรฐาน(อินสแตนซ์เดียวที่มีการจำลองเฟลโอเวอร์อัตโนมัติ) และRedis Cluster(คลัสเตอร์แบบแบ่งส่วนที่ได้รับการจัดการเต็มรูปแบบพร้อมการปรับขนาดอัตโนมัติ) ระดับมาตรฐานเหมาะสำหรับกรณีการใช้งาน HA ส่วนใหญ่ ในขณะที่คลัสเตอร์ Redis จะจัดการชุดข้อมูลขนาดใหญ่ที่ต้องการการปรับขนาดแนวนอน
# GCP — Create Standard tier Memorystore (HA with auto-failover)
gcloud redis instances create redis-ha-prod \
--size=26 \
--region=europe-west1 \
--zone=europe-west1-b \
--alternative-zone=europe-west1-c \
--tier=standard \
--redis-version=redis_7_2 \
--redis-config="maxmemory-policy=allkeys-lru,activedefrag=yes" \
--network=projects/my-project/global/networks/vpc-main \
--transit-encryption-mode=SERVER_AUTHENTICATION \
--enable-auth \
--persistence-mode=RDB \
--rdb-snapshot-period=12h \
--rdb-snapshot-start-time="2026-04-12T03:00:00Z" \
--maintenance-window-day=SUNDAY \
--maintenance-window-hour=4
# GCP — Create Memorystore Redis Cluster
gcloud redis clusters create redis-cluster-prod \
--region=europe-west1 \
--shard-count=3 \
--replica-count=1 \
--network=projects/my-project/global/networks/vpc-main \
--transit-encryption-mode=SERVER_AUTHENTICATIONการปรับใช้ Redis หลายภูมิภาค
การใช้งาน Redis หลายภูมิภาคถือเป็นสิ่งสำคัญสำหรับการกู้คืนระบบและการลดเวลาแฝงทั่วโลก วิธีการจะแตกต่างกันไปตามสถาปัตยกรรม: Redis Enterprise ใช้ Active-Active กับ CRDTs (ประเภทข้อมูลที่จำลองแบบไร้ข้อขัดแย้ง) สำหรับการเขียนแบบหลายต้นแบบที่แท้จริง ในขณะที่ Redis แบบโอเพ่นซอร์สและบริการที่จัดการบนคลาวด์ใช้การจำลองแบบแบบแอ็คทีฟ-พาสซีฟพร้อมแบบจำลองการอ่านในภูมิภาครอง
Bare Metal k3s/Rancher พร้อมแตรยาว
สำหรับองค์กรที่ใช้ฮาร์ดแวร์ของตนเอง การปรับใช้ Redis HA บน Bare Metal k3s ให้การควบคุมโครงสร้างพื้นฐานเต็มรูปแบบ ลดการล็อกอินของผู้จำหน่ายระบบคลาวด์ และคุ้มค่ามากขึ้นอย่างมากสำหรับการปรับใช้ขนาดใหญ่ k3s เป็นการกระจาย Kubernetes ที่มีน้ำหนักเบาและได้รับการรับรอง ซึ่งเหมาะสำหรับสภาพแวดล้อม Edge และ Bare Metal ในขณะที่ Rancher มีระนาบการจัดการสำหรับการดำเนินงานแบบหลายคลัสเตอร์
การติดตั้งk3s และการปรับใช้ตัวดำเนินการ Redis
# Install k3s on the first server node
curl -sfL https://get.k3s.io | K3S_TOKEN=redis-cluster-token \
INSTALL_K3S_EXEC="server --cluster-init --disable traefik --disable servicelb" sh -
# Join additional server nodes
curl -sfL https://get.k3s.io | K3S_TOKEN=redis-cluster-token \
K3S_URL=https://10.0.0.1:6443 \
INSTALL_K3S_EXEC="server" sh -
# Install Longhorn for distributed block storage
helm repo add longhorn https://charts.longhorn.io
helm install longhorn longhorn/longhorn \
--namespace longhorn-system --create-namespace \
--set defaultSettings.defaultDataPath=/mnt/longhorn \
--set defaultSettings.replicaCount=3 \
--set defaultSettings.storageMinimalAvailablePercentage=15
# Install MetalLB for bare-metal LoadBalancer services
helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb --namespace metallb-system --create-namespace
# Configure MetalLB IP address pool
kubectl apply -f - <Redis HA Helm ค่าสำหรับ k3s
# values-redis-ha.yaml — Helm values for Redis HA on k3s/Longhorn
redis:
replicas: 3
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
cpu: "4"
memory: 16Gi
storage:
persistentVolumeClaim:
metadata:
name: redis-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: longhorn
customConfig:
maxmemory: "6gb"
maxmemory-policy: "allkeys-lru"
save: "900 1 300 10 60 10000"
appendonly: "yes"
appendfsync: "everysec"
aof-use-rdb-preamble: "yes"
repl-backlog-size: "256mb"
tcp-keepalive: "60"
timeout: "300"
hz: "10"
activedefrag: "yes"
exporter:
enabled: true
image: oliver006/redis_exporter:latest
sentinel:
replicas: 3
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
customConfig:
down-after-milliseconds: "5000"
failover-timeout: "60000"
parallel-syncs: "1"
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values:
- redis
topologyKey: kubernetes.io/hostnameนโยบายการจัดการหน่วยความจำและการขับไล่Redis จัดเก็บข้อมูลทั้งหมดไว้ในหน่วยความจำ ทำให้การจัดการหน่วยความจำเป็นปัญหาด้านการปฏิบัติงานที่สำคัญที่สุด เมื่อ Redis ถึงขีดจำกัดmaxmemoryที่กำหนดค่าไว้ จะต้องตัดสินใจว่าจะทำอย่างไรกับคำสั่งเขียนขาเข้า นโยบายการไล่ออกจะควบคุมพฤติกรรมนี้
# redis.conf — Memory management
maxmemory 6gb
maxmemory-policy allkeys-lru
# Available eviction policies:
# noeviction — Return errors on writes when memory limit reached
# allkeys-lru — Evict least recently used keys (general-purpose cache)
# allkeys-lfu — Evict least frequently used keys (better for skewed access patterns)
# volatile-lru — Evict LRU keys with TTL set
# volatile-lfu — Evict LFU keys with TTL set
# volatile-ttl — Evict keys with shortest TTL first
# allkeys-random — Evict random keys
# volatile-random — Evict random keys with TTL set
# Active defragmentation (Redis 4.0+)
activedefrag yes
active-defrag-enabled yes
active-defrag-ignore-bytes 100mb
active-defrag-threshold-lower 10
active-defrag-threshold-upper 100
active-defrag-cycle-min 1
active-defrag-cycle-max 25
active-defrag-max-scan-fields 1000
# Memory usage monitoring
# redis-cli INFO memory
# Key metrics:
# used_memory — Total bytes allocated by Redis
# used_memory_rss — Resident set size (OS-level memory)
# mem_fragmentation_ratio — RSS / used_memory (should be close to 1.0)
# maxmemory — Configured memory limit
# evicted_keys — Total keys evicted due to maxmemoryสำหรับการปรับใช้ HA ให้ตั้งค่าmaxmemoryเป็นประมาณ 75% ของ RAM ที่พร้อมใช้งานของโหนด ส่วนที่เหลืออีก 25% รองรับบัฟเฟอร์เอาต์พุตการจำลอง, บัฟเฟอร์การเขียนซ้ำ AOF, หน่วยความจำการคัดลอกเมื่อเขียนระหว่างสแน็ปช็อต RDB และโอเวอร์เฮดของระบบปฏิบัติการ สำหรับพ็อดขนาด 16GB ให้ตั้งค่าหน่วยความจำสูงสุดเป็น 12GB สำหรับเซิร์ฟเวอร์ Bare Metal ขนาด 64GB ให้ตั้งค่าเป็น 48GB
TLS และ ACL
การใช้งานการผลิต Redis จะต้องเข้ารหัสข้อมูลระหว่างทางด้วย TLS และบังคับใช้การควบคุมการเข้าถึงแบบละเอียดด้วย ACL (รายการควบคุมการเข้าถึง) ที่นำมาใช้ใน Redis 6.0
# redis.conf — TLS configuration
tls-port 6380
port 0 # Disable non-TLS port entirely
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
tls-auth-clients optional # Require client certificates (mutual TLS)
tls-replication yes # Encrypt replication traffic
tls-cluster yes # Encrypt cluster bus traffic
tls-protocols "TLSv1.3" # Only allow TLS 1.3
# ACL configuration (Redis 6.0+)
# user on|off [>password] [~pattern] [+command|-command] [&channel]
user default off # Disable the default user
user admin on >strong_admin_pass ~* +@all
user appuser on >app_pass ~app:* ~session:* ~cache:* +@read +@write +@connection -@admin -@dangerous
user readonly on >readonly_pass ~* +@read +@connection -@write -@admin
user replicator on >repl_pass +psync +replconf +ping
# Load ACL from external file
aclfile /etc/redis/users.acl Pub/Sub และสตรีมในการตั้งค่า HA
Redis Pub/Sub และ Streams มีพฤติกรรมแตกต่างออกไปในการกำหนดค่า HA การทำความเข้าใจความแตกต่างเหล่านี้ถือเป็นสิ่งสำคัญสำหรับการสร้างระบบที่ขับเคลื่อนด้วยเหตุการณ์ที่เชื่อถือได้
ข้อความPub/Subเป็นแบบ fire-and-forget — ข้อความเหล่านั้นจะไม่คงอยู่ ไม่จำลองแบบ และไม่ถูกบัฟเฟอร์ ในการตั้งค่า HA ที่ใช้ Sentinel สมาชิกที่เชื่อมต่อกับระบบหลักจะได้รับข้อความตามปกติ แต่ในระหว่างการเกิดข้อผิดพลาด สมาชิกหลักรายใหม่จะไม่มีความรู้เกี่ยวกับการสมัครสมาชิกก่อนหน้านี้ ลูกค้าจะต้องสมัครสมาชิกใหม่หลังจากเชื่อมต่อใหม่ ด้วยคลัสเตอร์ Redis ข้อความ Pub/Sub จะถูกถ่ายทอดไปยังโหนดทั้งหมดในคลัสเตอร์ ดังนั้นสมาชิกที่เชื่อมต่อกับโหนดใดๆ จะได้รับข้อความที่เผยแพร่ (แม้ว่าจะสร้างการรับส่งข้อมูลระหว่างโหนดก็ตาม)
Redis สตรีมเป็นโครงสร้างข้อมูลที่ทำซ้ำอย่างต่อเนื่อง ซึ่งให้การส่งข้อความที่เชื่อถือได้ในสภาพแวดล้อม HA รายการสตรีมจะถูกจำลองแบบเป็นแบบจำลองผ่านกลไกการจำลองแบบปกติ อยู่รอดจากการเฟลโอเวอร์ และสนับสนุนกลุ่มผู้บริโภคด้วยซีแมนทิกส์การจัดส่งอย่างน้อยหนึ่งครั้ง สำหรับการรับส่งข้อความ HA ควรเลือกใช้ Streams มากกว่า Pub/Sub เสมอ
# Redis Streams with consumer groups — HA-safe message processing
# Create a stream and consumer group
XGROUP CREATE events:orders orders-processors $ MKSTREAM
# Produce events
XADD events:orders * action "order_placed" order_id "12345" amount "599.99"
XADD events:orders * action "order_placed" order_id "12346" amount "149.99"
# Consume events (in consumer group — at-least-once delivery)
XREADGROUP GROUP orders-processors worker-1 COUNT 10 BLOCK 5000 STREAMS events:orders >
# Acknowledge processed events
XACK events:orders orders-processors 1681234567890-0
# Check pending messages (unacknowledged)
XPENDING events:orders orders-processors - + 10
# Claim abandoned messages (from a dead consumer)
XAUTOCLAIM events:orders orders-processors worker-2 60000 0-0 COUNT 10
# Trim stream to prevent unbounded growth
XTRIM events:orders MAXLEN ~ 100000โมดูลRedis ใน HA
โมดูลRedis ขยาย Redis ด้วยโครงสร้างข้อมูลและฟังก์ชันพิเศษ สามรายการที่ได้รับความนิยมสูงสุด ได้แก่ RedisJSON, RediSearch และ RedisTimeSeries ทำงานร่วมกับการจำลองแบบและ Sentinel แต่มีข้อควรพิจารณาเฉพาะในการปรับใช้ HA
# redis.conf — Loading modules
loadmodule /opt/redis-stack/lib/rejson.so
loadmodule /opt/redis-stack/lib/redisearch.so
loadmodule /opt/redis-stack/lib/redistimeseries.so
# Modules are replicated to replicas via the command stream
# Ensure the same modules are installed on all nodes (master + replicas)
# RedisJSON — store and query JSON documents
JSON.SET user:1001 $ '{"name":"Alice","email":"alice@example.com","orders":42}'
JSON.GET user:1001 $.name
# RediSearch — full-text search with indexing
FT.CREATE idx:users ON JSON PREFIX 1 user: SCHEMA $.name AS name TEXT $.email AS email TAG $.orders AS orders NUMERIC
FT.SEARCH idx:users "@name:Alice"
# RedisTimeSeries — time-series data
TS.CREATE metrics:cpu:node1 RETENTION 86400000 LABELS host node1 metric cpu
TS.ADD metrics:cpu:node1 * 73.5
TS.RANGE metrics:cpu:node1 - + AGGREGATION avg 60000เมื่อรัน Redis Stack (ชุดโมดูล) ใน HA ตรวจสอบให้แน่ใจว่าโหนดทั้งหมด — ต้นแบบและเรพลิกา — มีการติดตั้งเวอร์ชันโมดูลที่เหมือนกัน คำสั่งของโมดูลจะถูกจำลองแบบผ่านสตรีมการจำลองแบบมาตรฐาน ดังนั้นแบบจำลองจะต้องสามารถดำเนินการได้ หลังจากเกิดข้อผิดพลาด ดัชนี RediSearch จะอยู่บนแบบจำลองที่ได้รับการเลื่อนระดับและให้บริการคำค้นหาทันที
การรวมการเชื่อมต่อและการกำหนดค่าไคลเอ็นต์สำหรับ HA
การรวมการเชื่อมต่อที่เหมาะสมถือเป็นสิ่งสำคัญสำหรับประสิทธิภาพและความยืดหยุ่นของ Redis HA พูลการเชื่อมต่อช่วยลดค่าใช้จ่ายในการสร้างการเชื่อมต่อ TCP จัดเตรียมลอจิกการลองใหม่อัตโนมัติ และเปิดใช้งานการจัดการเฟลโอเวอร์อย่างค่อยเป็นค่อยไป
# Node.js — ioredis connection pool with cluster mode
const Redis = require('ioredis');
// Cluster mode connection
const cluster = new Redis.Cluster(
[
{ host: '10.0.1.10', port: 7000 },
{ host: '10.0.1.11', port: 7000 },
{ host: '10.0.1.12', port: 7000 }
],
{
redisOptions: {
password: 'cluster_password',
connectTimeout: 10000,
maxRetriesPerRequest: 3
},
scaleReads: 'slave', // Route reads to replicas
clusterRetryStrategy(times) {
return Math.min(times * 200, 5000);
},
slotsRefreshTimeout: 2000,
slotsRefreshInterval: 5000,
enableOfflineQueue: true,
enableReadyCheck: true,
natMap: {} // For NAT/port-forwarded environments
}
);
cluster.on('error', (err) => console.error('Cluster error:', err));
cluster.on('node error', (err, address) => {
console.error(`Node ${address} error:`, err);
});# Python — redis-py connection pool with cluster mode
from redis.cluster import RedisCluster
from redis.backoff import ExponentialBackoff
from redis.retry import Retry
retry = Retry(ExponentialBackoff(cap=5, base=0.1), retries=5)
rc = RedisCluster(
startup_nodes=[
{"host": "10.0.1.10", "port": 7000},
{"host": "10.0.1.11", "port": 7000},
{"host": "10.0.1.12", "port": 7000}
],
password="cluster_password",
decode_responses=True,
read_from_replicas=True,
retry=retry,
retry_on_timeout=True,
socket_timeout=5,
socket_connect_timeout=5,
max_connections=50,
health_check_interval=30
)
rc.set("key", "value")
print(rc.get("key"))// Go — go-redis cluster client with connection pooling
package main
import (
"context"
"time"
"github.com/redis/go-redis/v9"
)
func NewRedisCluster() *redis.ClusterClient {
return redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{
"10.0.1.10:7000",
"10.0.1.11:7000",
"10.0.1.12:7000",
},
Password: "cluster_password",
ReadOnly: true,
RouteRandomly: true,
RouteByLatency: false,
PoolSize: 50,
MinIdleConns: 10,
DialTimeout: 10 * time.Second,
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
PoolTimeout: 10 * time.Second,
MaxRetries: 5,
MinRetryBackoff: 200 * time.Millisecond,
MaxRetryBackoff: 5 * time.Second,
})
}กลยุทธ์การสำรองและกู้คืน
แม้จะมีการจำลองแบบ HA การสำรองข้อมูลเป็นประจำยังจำเป็นสำหรับการกู้คืนความเสียหาย การปฏิบัติตามข้อกำหนด และการป้องกันข้อผิดพลาดเชิงตรรกะ (FLUSHALL โดยไม่ได้ตั้งใจ การเขียนแอปพลิเคชันที่ไม่ถูกต้อง) การสำรองข้อมูล Redis อิงตามสแน็ปช็อต RDB และไฟล์ AOF
#!/bin/bash
# redis-backup.sh — Automated Redis backup script
REDIS_HOST="10.0.1.10"
REDIS_PORT="6379"
REDIS_PASS="strong_master_password"
BACKUP_DIR="/backups/redis"
S3_BUCKET="s3://redis-backups-prod"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
# Trigger RDB snapshot on the master
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -a "$REDIS_PASS" BGSAVE
# Wait for background save to complete
while [ "$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASS LASTSAVE)" = "$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASS LASTSAVE)" ]; do
sleep 1
done
sleep 2
# Copy the RDB file
RDB_FILE=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -a "$REDIS_PASS" CONFIG GET dir | tail -1)
cp "${RDB_FILE}/dump.rdb" "${BACKUP_DIR}/dump_${DATE}.rdb"
# Compress and upload to S3
gzip "${BACKUP_DIR}/dump_${DATE}.rdb"
aws s3 cp "${BACKUP_DIR}/dump_${DATE}.rdb.gz" "${S3_BUCKET}/daily/dump_${DATE}.rdb.gz" \
--storage-class STANDARD_IA
# Cleanup old local backups
find "$BACKUP_DIR" -name "dump_*.rdb.gz" -mtime +$RETENTION_DAYS -delete
# Verify backup integrity
redis-check-rdb "${BACKUP_DIR}/dump_${DATE}.rdb.gz" && \
echo "Backup verified: dump_${DATE}.rdb.gz" || \
echo "ERROR: Backup verification failed!"
echo "Backup complete: ${BACKUP_DIR}/dump_${DATE}.rdb.gz"# Restore from RDB backup
# 1. Stop Redis
systemctl stop redis
# 2. Replace the RDB file
gunzip /backups/redis/dump_20260412_030000.rdb.gz
cp /backups/redis/dump_20260412_030000.rdb /data/redis/dump.rdb
chown redis:redis /data/redis/dump.rdb
# 3. Disable AOF temporarily (if enabled) to prevent AOF overriding RDB on startup
redis-cli -a password CONFIG SET appendonly no
# 4. Start Redis (loads RDB)
systemctl start redis
# 5. Re-enable AOF and rewrite it from the loaded data
redis-cli -a password CONFIG SET appendonly yes
redis-cli -a password BGREWRITEAOFการตรวจสอบด้วย Redis INFO, Prometheus และ Grafana
การตรวจสอบที่ครอบคลุมเป็นรากฐานของความเป็นเลิศในการปฏิบัติงานสำหรับ Redis HA Redis เปิดเผยตัวชี้วัดภายในที่หลากหลายผ่านคำสั่งINFOซึ่งผู้ส่งออก Prometheus Redis แปลเป็นตัวชี้วัดอนุกรมเวลาสำหรับแดชบอร์ด Grafana และการแจ้งเตือน
# Key Redis INFO sections for HA monitoring
redis-cli -a password INFO replication
# role:master
# connected_slaves:2
# slave0:ip=10.0.1.11,port=6379,state=online,offset=1234567,lag=0
# slave1:ip=10.0.1.12,port=6379,state=online,offset=1234560,lag=1
# master_replid:abc123...
# master_repl_offset:1234567
# repl_backlog_size:268435456
# repl_backlog_first_byte_offset:1000000
redis-cli -a password INFO memory
# used_memory:6442450944
# used_memory_human:6.00G
# used_memory_rss:6879707136
# mem_fragmentation_ratio:1.07
# maxmemory:6442450944
# maxmemory_policy:allkeys-lru
# evicted_keys:12345
redis-cli -a password INFO stats
# total_connections_received:50000
# total_commands_processed:12345678
# instantaneous_ops_per_sec:85432
# keyspace_hits:11000000
# keyspace_misses:1345678
# expired_keys:500000
# evicted_keys:12345
redis-cli -a password INFO clients
# connected_clients:150
# blocked_clients:0
# maxclients:10000# Prometheus Redis Exporter deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-exporter
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: redis-exporter
template:
metadata:
labels:
app: redis-exporter
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9121"
spec:
containers:
- name: redis-exporter
image: oliver006/redis_exporter:latest
args:
- --redis.addr=redis://redis-ha-master:6379
- --redis.password=$(REDIS_PASSWORD)
- --include-system-metrics
- --is-cluster
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: password
ports:
- containerPort: 9121
name: metrics
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi# PrometheusRule for Redis HA alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: redis-ha-alerts
namespace: monitoring
spec:
groups:
- name: redis-availability
rules:
- alert: RedisDown
expr: redis_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Redis instance {{ $labels.instance }} is down"
- alert: RedisReplicaDisconnected
expr: redis_connected_slaves < 2
for: 2m
labels:
severity: warning
annotations:
summary: "Redis master has fewer than 2 connected replicas"
- alert: RedisReplicationLagHigh
expr: redis_replication_lag > 5
for: 3m
labels:
severity: warning
annotations:
summary: "Redis replication lag exceeds 5 seconds on {{ $labels.instance }}"
- alert: RedisMemoryUsageHigh
expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "Redis memory usage above 90% on {{ $labels.instance }}"
- alert: RedisEvictionsHigh
expr: rate(redis_evicted_keys_total[5m]) > 100
for: 5m
labels:
severity: warning
annotations:
summary: "Redis evicting keys at >100/s on {{ $labels.instance }}"
- alert: RedisKeyspaceHitRateLow
expr: redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total) < 0.8
for: 10m
labels:
severity: info
annotations:
summary: "Redis cache hit rate below 80% on {{ $labels.instance }}"
- alert: RedisSentinelDown
expr: redis_sentinel_master_status != 1
for: 1m
labels:
severity: critical
annotations:
summary: "Redis Sentinel reports master unhealthy"
- name: redis-performance
rules:
- alert: RedisSlowlogGrowing
expr: increase(redis_slowlog_length[5m]) > 10
for: 5m
labels:
severity: warning
annotations:
summary: "Redis slow log growing rapidly on {{ $labels.instance }}"
- alert: RedisConnectionsNearLimit
expr: redis_connected_clients / redis_config_maxclients > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Redis connected clients above 80% of maxclients"Dragonfly และ KeyDB: ทางเลือกอื่นที่เข้ากันได้กับ Redis
แม้ว่า Redis จะเป็นที่เก็บข้อมูลในหน่วยความจำที่โดดเด่น แต่ทางเลือกที่เข้ากันได้กับ Redis สองทางเลือกก็ได้รับความนิยมในกรณีการใช้งานเฉพาะ
แมลงปอ
Dragonfly เป็นการทดแทน Redis แบบมัลติเธรดที่ทันสมัย โดยมีจุดมุ่งหมายที่จะทดแทนแบบดรอปอินในขณะที่ใช้ประโยชน์จากคอร์ CPU ที่มีอยู่ทั้งหมด Redis แบบดั้งเดิมเป็นแบบเธรดเดียวสำหรับการประมวลผลคำสั่ง — Dragonfly ใช้สถาปัตยกรรมที่ไม่มีการแชร์กับหลายเธรดเพื่อให้ได้ปริมาณงานที่สูงขึ้นอย่างมากบนเครื่องแบบมัลติคอร์ รองรับโปรโตคอล Redis คำสั่ง Redis ส่วนใหญ่ และสามารถแทนที่ Redis ได้โดยไม่ต้องเปลี่ยนแปลงแอปพลิเคชัน
# Run Dragonfly as a Redis replacement
docker run -d --name dragonfly \
-p 6379:6379 \
-v /data/dragonfly:/data \
docker.dragonflydb.io/dragonflydb/dragonfly \
--maxmemory 12gb \
--proactor_threads 8 \
--dbfilename dump.rdb \
--requirepass strong_password
# Dragonfly in Kubernetes
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: dragonfly
namespace: production
spec:
replicas: 1
selector:
matchLabels:
app: dragonfly
template:
metadata:
labels:
app: dragonfly
spec:
containers:
- name: dragonfly
image: docker.dragonflydb.io/dragonflydb/dragonfly:latest
args:
- --maxmemory=12gb
- --proactor_threads=8
- --requirepass=strong_password
- --snapshot_cron=*/30 * * * *
ports:
- containerPort: 6379
resources:
requests:
cpu: "4"
memory: 16Gi
limits:
cpu: "8"
memory: 16Gi
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: longhorn
resources:
requests:
storage: 100Giข้อได้เปรียบที่สำคัญของDragonfly: แบบมัลติเธรด (ทรูพุต 25 เท่าบน 8 คอร์ เทียบกับ Redis แบบเธรดเดี่ยว), ประสิทธิภาพหน่วยความจำที่ดีขึ้น (ใช้ตารางแฮช Dash แทน Redis dict), สแน็ปช็อตในตัวโดยไม่มีค่าโสหุ้ย fork() และการสนับสนุนดั้งเดิมสำหรับชุดข้อมูลขนาดใหญ่ อย่างไรก็ตาม ในปี 2026 การรองรับการจำลองแบบของ Dragonfly ยังคงอยู่ในช่วงเติบโต โดยรองรับการจำลองแบบแบบหลักแต่ยังไม่มีระบบเฟลโอเวอร์อัตโนมัติที่เทียบเท่ากับ Sentinel สำหรับ HA ให้ใช้การตรวจสอบสภาพ Kubernetes และนโยบายการรีสตาร์ท StatefulSet หรือปรับใช้หลังโหลดบาลานเซอร์ด้วยการเฟลโอเวอร์ระดับแอปพลิเคชัน
คีย์DB
KeyDB เป็นทางแยกแบบมัลติเธรดของ Redis ที่ดูแลโดย Snap (บริษัทที่อยู่เบื้องหลัง Snapchat) มันเข้ากันได้อย่างสมบูรณ์กับ Redis และเพิ่มมัลติเธรด, การจำลองแบบที่ใช้งานอยู่ (มัลติมาสเตอร์), การจัดระดับพื้นที่เก็บข้อมูล FLASH และการหมดอายุของคีย์ย่อย การจำลองแบบแอคทีฟและแอคทีฟของ KeyDB นั้นน่าสนใจเป็นพิเศษสำหรับ HA โดยอินสแตนซ์ KeyDB สองตัวสามารถรับการเขียนพร้อมกันและทำซ้ำซึ่งกันและกัน โดยให้การเฟลโอเวอร์แบบไม่ต้องหยุดทำงาน
# keydb.conf — Multi-threaded configuration with active replication
server-threads 4 # Use 4 threads for command processing
bind 0.0.0.0
port 6379
requirepass strong_password
masterauth strong_password
# Active-active replication (multi-master)
active-replica yes
replicaof peer-host 6379 # Bidirectional replication
# On the peer node, configure the reverse:
# replicaof this-host 6379
# FLASH storage tiering (for datasets larger than RAM)
# storage-provider flash /mnt/flash-storage 100
# maxmemory 16gb
# Will keep hot data in RAM and spill cold data to SSD
# SubKey expiration (unique to KeyDB)
# Allows setting TTL on hash fields, not just top-level keys
# EXPIREMEMBER myhash field1 3600KeyDB เป็นตัวเลือกที่ดีเมื่อคุณต้องการการจำลองแบบหลายต้นแบบสำหรับการกระจายทางภูมิศาสตร์หรือการบำรุงรักษาแบบไม่ต้องหยุดทำงาน หรือเมื่อคุณต้องการทรูพุตที่สูงกว่า Redis แบบเธรดเดียวที่สามารถให้ได้ แต่ต้องการอยู่ใกล้กับฐานโค้ด Redis มากกว่า Dragonfly
การปรับแต่งประสิทธิภาพ
งานวางท่อ
Pipelining รวมชุดคำสั่งหลายคำสั่งไว้ในเครือข่ายเดียวแบบไปกลับ ช่วยลดเวลาแฝงสำหรับการดำเนินการจำนวนมากได้อย่างมาก แทนที่จะรอแต่ละคำตอบก่อนส่งคำสั่งถัดไป ไคลเอนต์จะส่งคำสั่งทั้งหมดในครั้งเดียวและอ่านคำตอบทั้งหมดพร้อมกัน
# Python — Pipelining with redis-py
import redis
import time
r = redis.Redis(host='10.0.1.10', port=6379, password='password', decode_responses=True)
# Without pipelining: 1000 round-trips
start = time.time()
for i in range(1000):
r.set(f'key:{i}', f'value:{i}')
print(f'Without pipeline: {time.time() - start:.3f}s')
# With pipelining: 1 round-trip for 1000 commands
start = time.time()
pipe = r.pipeline(transaction=False)
for i in range(1000):
pipe.set(f'key:{i}', f'value:{i}')
pipe.execute()
print(f'With pipeline: {time.time() - start:.3f}s')
# Typically 5-10x fasterการเขียนสคริปต์ Lua
สคริปต์Lua ดำเนินการแบบอะตอมมิกบนเซิร์ฟเวอร์ Redis ซึ่งช่วยลดการเดินทางไปกลับสำหรับการดำเนินการที่ซับซ้อน และรับประกันว่าจะไม่มีคำสั่งอื่นใดดำเนินการระหว่างการทำงานของสคริปต์ ในคลัสเตอร์ Redis ตรวจสอบให้แน่ใจว่าคีย์ทั้งหมดที่เข้าถึงโดยสคริปต์ Lua อยู่ในช่องแฮชเดียวกันโดยใช้แฮชแท็ก
# Lua script for atomic rate limiting
# KEYS[1] = rate limit key
# ARGV[1] = max requests
# ARGV[2] = window in seconds
local current = redis.call('INCR', KEYS[1])
if current == 1 then
redis.call('EXPIRE', KEYS[1], ARGV[2])
end
if current > tonumber(ARGV[1]) then
return 0 -- Rate limited
end
return 1 -- Allowed
# Load and execute
redis-cli -a password EVAL "\
local current = redis.call('INCR', KEYS[1]) \
if current == 1 then redis.call('EXPIRE', KEYS[1], ARGV[2]) end \
if current > tonumber(ARGV[1]) then return 0 end \
return 1" 1 ratelimit:user:123 100 60การเพิ่มประสิทธิภาพหน่วยความจำ
# redis.conf — Memory optimisation settings
# Use ziplist encoding for small hashes, lists, sorted sets
hash-max-listpack-entries 128
hash-max-listpack-value 64
list-max-listpack-size -2 # 8KB per node
zset-max-listpack-entries 128
zset-max-listpack-value 64
set-max-intset-entries 512
# Lazy freeing (avoid blocking on large key deletion)
lazyfree-lazy-eviction yes
lazyfree-lazy-expire yes
lazyfree-lazy-server-del yes
lazyfree-lazy-user-del yes
lazyfree-lazy-user-flush yes
# jemalloc tuning
# MALLOC_CONF="background_thread:true,dirty_decay_ms:5000,muzzy_decay_ms:5000"
# Analyse memory usage
redis-cli -a password MEMORY DOCTOR
redis-cli -a password MEMORY STATS
redis-cli -a password --bigkeys
redis-cli -a password --memkeysสถานการณ์ความล้มเหลวทั่วไปและการแก้ไขปัญหา
สถานการณ์ที่ 1: Master ล้มเหลว Sentinel ส่งเสริมการจำลอง
# Diagnosis
redis-cli -p 26379 SENTINEL master mymaster
# Check: flags should show 's_down' or 'o_down' if master is unreachable
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# Returns the current master address (should be the promoted replica)
# Check Sentinel logs for failover events
tail -f /var/log/redis/sentinel.log
# Look for: +sdown, +odown, +try-failover, +elected-leader,
# +failover-state-select-slave, +selected-slave,
# +failover-state-send-slaveof-noone, +failover-endสถานการณ์ที่ 2: แยกสมองกับผู้เชี่ยวชาญสองคน
# Diagnosis: check if min-replicas-to-write is configured
redis-cli -a password CONFIG GET min-replicas-to-write
redis-cli -a password CONFIG GET min-replicas-max-lag
# Prevention: configure min-replicas on all masters
redis-cli -a password CONFIG SET min-replicas-to-write 1
redis-cli -a password CONFIG SET min-replicas-max-lag 10
# If split-brain occurred: identify the stale master
# Compare replication offsets — the master with the higher offset has more data
redis-cli -h master1-ip -a password INFO replication | grep master_repl_offset
redis-cli -h master2-ip -a password INFO replication | grep master_repl_offset
# Force the stale master to become a replica
redis-cli -h stale-master-ip -a password REPLICAOF correct-master-ip 6379สถานการณ์สมมติที่ 3: Resync Storm เต็มรูปแบบหลังจากพาร์ติชันเครือข่าย
# Diagnosis: check replication backlog
redis-cli -a password INFO replication | grep repl_backlog
# If repl_backlog_first_byte_offset is ahead of replica's offset, full sync triggers
# Prevention: increase backlog size
redis-cli -a password CONFIG SET repl-backlog-size 512mb
# Monitor for full syncs
redis-cli -a password INFO stats | grep sync_full
redis-cli -a password INFO stats | grep sync_partial_ok
redis-cli -a password INFO stats | grep sync_partial_errสถานการณ์ที่ 4: หน่วยความจำหมดและ OOM ฆ่า
# Diagnosis
redis-cli -a password INFO memory
# Check: used_memory vs maxmemory, mem_fragmentation_ratio
redis-cli -a password MEMORY DOCTOR
# Returns advice on memory issues
# Prevention: set proper maxmemory and eviction
redis-cli -a password CONFIG SET maxmemory 12gb
redis-cli -a password CONFIG SET maxmemory-policy allkeys-lru
# Find large keys consuming memory
redis-cli -a password --bigkeys
redis-cli -a password --memkeys --memkeys-samples 100
# Emergency: manually evict keys
redis-cli -a password SCAN 0 COUNT 1000 TYPE string
# Identify and DEL unnecessary large keysสถานการณ์ที่ 5: คำสั่งที่ช้าปิดกั้นการจำลองแบบ
# Diagnosis: check slowlog
redis-cli -a password SLOWLOG GET 20
redis-cli -a password SLOWLOG LEN
# Check for blocking commands
redis-cli -a password CLIENT LIST | grep -E 'cmd=(keys|sort|smembers)'
# Prevention: configure slowlog threshold
redis-cli -a password CONFIG SET slowlog-log-slower-than 10000 # 10ms
redis-cli -a password CONFIG SET slowlog-max-len 256
# Rename dangerous commands
rename-command KEYS "" # Disable KEYS entirely
rename-command FLUSHALL "" # Disable FLUSHALL
rename-command FLUSHDB "" # Disable FLUSHDB
rename-command DEBUG "" # Disable DEBUGการวางแผนความจุและกลยุทธ์การปรับขนาด
การวางแผนความจุสำหรับ Redis HA เกี่ยวข้องกับการประมาณความต้องการหน่วยความจำ แบนด์วิดท์เครือข่าย และการใช้งาน CPU ทั่วทั้งโหนดหลักและโหนดจำลอง ตัววัดหลักในการวางแผนคือขนาดชุดข้อมูล การดำเนินการต่อวินาที ขนาดคีย์/ค่าเฉลี่ย และค่าใช้จ่ายในการจำลองข้อมูล
# Capacity estimation formulas
# Memory per node:
# Base dataset size (use redis-cli DBSIZE and MEMORY USAGE on a sample)
# + Replication output buffer: ~64MB per replica
# + AOF rewrite buffer: ~64MB during rewrites
# + Copy-on-write overhead during BGSAVE: up to 2x during heavy writes
# + Client output buffers: ~1KB per client
# + OS overhead: ~1-2GB
# Rule of thumb: maxmemory = 75% of available RAM
# Network bandwidth:
# Replication: write_throughput_bytes * num_replicas
# Client traffic: ops_per_sec * avg_response_size
# Full sync: dataset_size (one-time during replica bootstrap or failover)
# Example sizing for 20GB dataset, 100K ops/sec:
# RAM per node: 20GB data + 4GB buffers + 2GB OS = 26GB -> 32GB node (75% = 24GB maxmemory)
# CPU: 1 core handles ~100K ops/sec for simple commands (GET/SET)
# Network: 100K ops * 1KB avg = 100MB/s client + 50MB/s replication = 150MB/s per master
# Scaling decision tree:
# Need more read throughput? -> Add replicas (up to 5 per master)
# Need more write throughput? -> Redis Cluster (add shards)
# Need more memory? -> Redis Cluster (distribute dataset across shards)
# Need lower latency? -> Reduce network hops (co-locate, use unix sockets)
# Need global distribution? -> Multi-region replication or Redis Enterprise Active-Activeการปรับขนาดแนวนอนด้วยคลัสเตอร์ Redis
# Add shards to an existing Redis Cluster
# 1. Start new Redis nodes
redis-server /etc/redis/new-master.conf
redis-server /etc/redis/new-replica.conf
# 2. Add the new master to the cluster
redis-cli --cluster add-node new-master:7000 existing-node:7000 -a password
# 3. Add the new replica to follow the new master
redis-cli --cluster add-node new-replica:7000 existing-node:7000 \
--cluster-slave --cluster-master-id NEW_MASTER_ID -a password
# 4. Reshard slots to the new master
redis-cli --cluster reshard existing-node:7000 \
--cluster-from all --cluster-to NEW_MASTER_ID \
--cluster-slots 4096 --cluster-yes -a password
# 5. Verify the new slot distribution
redis-cli -c -h existing-node -p 7000 -a password CLUSTER SLOTS
# Remove a shard (scale down)
# 1. Reshard all slots away from the node
redis-cli --cluster reshard existing-node:7000 \
--cluster-from REMOVING_NODE_ID --cluster-to TARGET_NODE_ID \
--cluster-slots 5461 --cluster-yes -a password
# 2. Remove the empty node
redis-cli --cluster del-node existing-node:7000 REMOVING_NODE_ID -a passwordข้อควรพิจารณาในการปรับขนาดแนวตั้ง# When to scale vertically vs horizontally:
# Scale UP (bigger instances) when:
# - Dataset fits in single-node memory
# - Workload uses multi-key operations (MGET, SUNION, Lua across keys)
# - Operational simplicity is more important than cost efficiency
# - Using Redis modules that don't support Cluster mode well
# Scale OUT (more shards) when:
# - Dataset exceeds single-node memory
# - Write throughput exceeds single-thread capacity (~200K ops/sec)
# - You need per-shard isolation for multi-tenant workloads
# - Cost per GB of RAM is a concern (many smaller nodes vs few large ones)
# Cloud instance recommendations:
# AWS: cache.r7g.xlarge (4 vCPU, 26GB) to cache.r7g.16xlarge (64 vCPU, 419GB)
# Azure: P1 (6GB) to P5 (120GB) per shard
# GCP: 5GB to 300GB per instance (Memorystore Standard)
# Bare metal:
# CPU: 2-4 cores dedicated to Redis (single-threaded, but background tasks use extra cores)
# RAM: 32-128GB per node (NVMe for swap-as-last-resort)
# Network: 10Gbps minimum, 25Gbps for large datasets
# Storage: NVMe SSD for AOF/RDB persistence (IOPS matters for fsync)สรุป
ความพร้อมใช้งานสูงRedis ไม่ใช่ตัวเลือกการกำหนดค่าเพียงตัวเดียว แต่เป็นการออกแบบระบบที่ครอบคลุมที่ครอบคลุมตั้งแต่โทโพโลยีการจำลอง การตรวจจับความล้มเหลว การเฟลโอเวอร์อัตโนมัติ การกำหนดค่าไคลเอนต์ กลยุทธ์การคงอยู่ การจัดการหน่วยความจำ ความปลอดภัย การตรวจสอบ และขั้นตอนการปฏิบัติงาน สถาปัตยกรรม HA ที่เหมาะสมนั้นขึ้นอยู่กับความต้องการเฉพาะของคุณ
สำหรับแอปพลิเคชันส่วนใหญ่Redis Sentinelที่มีอินสแตนซ์ Sentinel สามอินสแตนซ์ที่ตรวจสอบต้นแบบและแบบจำลองสองรายการมอบโซลูชัน HA ที่ผ่านการพิสูจน์แล้วและผ่านการทดสอบการต่อสู้พร้อมระบบเฟลโอเวอร์อัตโนมัติภายในเวลาไม่ถึง 30 วินาที เมื่อคุณต้องการสเกลแนวนอนที่เกินกว่าปริมาณงานหรือความจุหน่วยความจำของต้นแบบตัวเดียวRedis Clusterจะกระจายชุดข้อมูลไปยังชาร์ดหลาย ๆ ชาร์ด ในขณะที่ยังคงรักษาการเฟลโอเวอร์ในตัวต่อชาร์ด สำหรับสภาพแวดล้อม Kubernetes ตัวดำเนินการเช่นSpotahomeและOpsTreeเข้ารหัสแนวทางปฏิบัติที่ดีที่สุดในการปฏิบัติงานเป็น CRD ที่เปิดเผย ในขณะที่Redis Enterpriseมอบตัวเลือกที่มีฟีเจอร์หลากหลายที่สุดพร้อมการจำลองทางภูมิศาสตร์แบบ Active-Active และการสนับสนุนโมดูล
บริการที่จัดการบนคลาวด์ —AWS ElastiCache,Azure Cache สำหรับ Redis, และGCP Memorystore— ขจัดภาระการดำเนินงานของการรันโครงสร้างพื้นฐาน Redis แต่มาพร้อมกับความยืดหยุ่นที่ลดลงและต้นทุนที่สูงขึ้นตามขนาด สำหรับองค์กรที่มีโครงสร้างพื้นฐานแบบ Bare Metalk3s พร้อม Rancher และ Longhornมอบทางเลือกโอเพ่นซอร์สที่ไม่ขึ้นอยู่กับคลาวด์โดยสมบูรณ์ โดยนำเสนอ HA ระดับองค์กรโดยไม่ต้องผูกมัดกับผู้จำหน่าย
ทางเลือกอื่น เช่นDragonflyและKeyDBคุ้มค่าแก่การประเมินสำหรับกรณีการใช้งานเฉพาะ — Dragonfly สำหรับการประมวลผลแบบมัลติเธรดแบบดิบบนเครื่องขนาดใหญ่ และ KeyDB สำหรับการจำลองแบบ multi-master แบบแอคทีฟและแอคทีฟ ทั้งสองเข้ากันได้กับ Redis และสามารถใช้เป็นอุปกรณ์ทดแทนแบบดรอปอินได้ในหลายสถานการณ์
ไม่ว่าคุณจะเลือกสถาปัตยกรรมแบบใด พื้นฐานการปฏิบัติงานจะยังคงที่: กำหนดค่าการคงอยู่ที่เหมาะสม (RDB + AOF แบบไฮบริด), บังคับใช้min-replicas-to-writeเพื่อป้องกันการสูญเสียข้อมูลแบบ split-brain, ปรับขนาด Replication Backlog ของคุณสำหรับปริมาณการเขียนของคุณ, เข้ารหัสการรับส่งข้อมูลทั้งหมดด้วย TLS, บังคับใช้การเข้าถึงที่มีสิทธิพิเศษน้อยที่สุดด้วย ACL, ตรวจสอบความล่าช้าในการจำลองและการใช้หน่วยความจำด้วย Prometheus และ Grafana, สำรองข้อมูลสแน็ปช็อต RDB เพื่อนอกสถานที่ที่มีความคงทน พื้นที่เก็บข้อมูลและ — ที่สำคัญที่สุด — ทดสอบการเฟลโอเวอร์ของคุณเป็นประจำ ระบบเฟลโอเวอร์ที่ไม่เคยทดสอบคือระบบที่ใช้งานไม่ได้ ดำเนินการฝึกซ้อมเฟลโอเวอร์รายเดือน อัดฉีดความล้มเหลวด้วยเครื่องมือทางวิศวกรรมที่วุ่นวาย และวัดเวลาการกู้คืนจริงของคุณ ความมั่นใจที่คุณได้รับจากการทดสอบอย่างเป็นระบบคือสิ่งที่แยกการใช้งาน Redis ที่จะเอาตัวรอดจากเหตุการณ์การผลิตจากเหตุการณ์ที่เปลี่ยนความล้มเหลวของเซิร์ฟเวอร์ไปสู่การหยุดทำงานทั่วทั้งบริษัท