Cơ Chế Lưu Trữ Dữ Liệu, Nhân Bản Và Xử Lý Sự Cố Bộ Nhớ Đệm Trong Redis

1. Phân Tích Cấu Hình redis.conf

Tệp cấu hình redis.conf điều khiển toàn bộ hành vi của máy chủ Redis. Dưới đây là các nhóm thiết lập quan trọng cần nắm rõ khi vận hành hệ thống:

1.1. Đơn Vị Và Import

Redis không phân biệt hoa thường ở các đơn vị bộ nhớ (KB, MB, GB). Bạn cũng có thể nạp chồng cấu hình từ tệp khác thông qua chỉ thị include để phân tách cấu hình theo môi trường.

1.2. Mạng Và Bảo Mật

# Giới hạn địa chỉ IP lắng nghe
bind 192.168.1.100 127.0.0.1
# Bật chế độ bảo vệ, ngăn truy cập trái phép khi chưa đặt mật khẩu
protected-mode yes
# Cổng dịch vụ
port 6380
# Thiết lập mật khẩu xác thực
requirepass "MyStr0ngP@ssw0rd!"

1.3. Vận Hành Hệ Thống

# Chạy nền (lưu ý: đặt 'no' khi triển khai qua Docker hoặc systemd)
daemonize yes
# Đường dẫn lưu PID
pidfile /var/run/redis_instance.pid
# Mức độ ghi nhật ký: debug, verbose, notice, warning
loglevel notice
# Tệp nhật ký
logfile "/var/log/redis/server.log"
# Số lượng cơ sở dữ liệu logic
databases 16

1.4. Chiến Lược Bộ Nhớ

# Giới hạn RAM tối đa
maxmemory 2gb
# Chính sách trục xuất dữ liệu khi đạt ngưỡng
maxmemory-policy allkeys-lru
# Giới hạn kết nối đồng thời
maxclients 5000

2. Cơ Chế Persistent (Lưu Trữ Dữ Liệu)

Vì Redis hoạt động hoàn toàn trên RAM, việc đồng bộ trạng thái dữ liệu xuống đĩa cứng là bắt buộc để tránh mất mát khi sự cố xảy ra. Hệ thống hỗ trợ hai phương thức chính:

2.1. RDB (Redis Database Backup)

RDB tạo các bản chụp (snapshot) toàn bộ dataset tại các thời điểm xác định. Quá trình này sử dụng cơ chế fork() để tạo tiến trình con, giúp tiến trình chính không bị chặn bởi thao tác I/O đĩa.

# Cấu hình trigger tạo snapshot
save 1200 5   # 1200 giây nếu có ít nhất 5 key thay đổi
save 600 50   # 600 giây nếu có ít nhất 50 key thay đổi
save 30 5000  # 30 giây nếu có ít nhất 5000 key thay đổi

# Nén tệp RDB để tiết kiệm dung lượng (tốn thêm CPU)
rdbcompression yes
# Kiểm tra tính toàn vẹn khi đọc/ghi
rdbchecksum yes
# Thư mục lưu trữ tệp dump.rdb
dir /data/redis_backup

Đặc điểm kỹ thuật:

  • Kích hoạt: Tự động theo luật save, lệnh SAVE/BGSAVE, FLUSHALL, hoặc khi tắt dịch vụ gracefully.
  • Phục hồi: Đặt tệp dump.rdb vào thư mục được chỉ định bởi dir, Redis sẽ tự động nạp khi khởi động.
  • Ưu điểm: Tệp nhỏ, phục hồi nhanh, phù hợp sao lưu định kỳ và khôi phục thảm họa.
  • Nhược điểm: Có thể mất dữ liệu trong khoảng thời gian giữa hai lần snapshot. Tiến trình fork() tốn RAM tạm thời (Copy-on-Write).

2.2. AOF (Append Only File)

AOF ghi lại tuần tự mọi lệnh ghi (write) vào một tệp nhật ký. Khi khởi động lại, Redis sẽ phát lại (replay) các lệnh này để khôi phục trạng thái.

# Bật chế độ AOF
appendonly yes
# Tên tệp nhật ký
appendfilename "redis_changes.aof"
# Chính sách đồng bộ đĩa
# always: Ghi ngay lập tức (an toàn nhất, chậm nhất)
# everysec: Ghi mỗi giây (cân bằng giữa hiệu năng và an toàn)
# no: Phó mặc cho hệ điều hành
appendfsync everysec

Đặc điểm kỹ thuật:

  • Khi cả RDB và AOF cùng bật, Redis ưu tiên nạp AOF khi khởi động để đảm bảo tính mới nhất của dữ liệu.
  • Nếu tệp AOF bị hỏng do ghi dở dang, có thể dùng công cụ redis-check-aof --fix để cắt bỏ phần lỗi và giữ lại dữ liệu hợp lệ.
  • Ưu điểm: Độ bền dữ liệu cao, mất mát tối đa 1 giây (với everysec).
  • Nhược điểm: Tệp lớn hơn RDB, tốc độ phục hồi chậm hơn do phải phát lại tuần tự các lệnh. Redis định kỳ chạy BGREWRITEAOF để nén tệp.

3. Mô Hình Pub/Sub

Redis hỗ trợ cơ chế xuất bản/đăng ký tin nhắn theo thời gian thực, hoạt động dựa trên các kênh (channel) mà không cần lưu trữ trung gian.

# Terminal 1: Đăng ký nhận tin
SUBSCRIBE system_alerts

# Terminal 2: Gửi tin nhắn đến kênh
PUBLISH system_alerts "CPU overload detected on node-3"

Lưu ý: Pub/Sub không lưu trữ tin nhắn. Nếu subscriber ngắt kết nối, các tin nhắn gửi trong thời gian đó sẽ bị mất vĩnh viễn. Đối với hàng đợi bền vững, nên sử dụng Redis Streams hoặc Lists.

4. Nhân Bản Dữ Liệu (Replication)

4.1. Thiết Lập Master-Slave

Mặc định, mọi instance Redis đều đóng vai trò Master. Để cấu hình nhân bản, chỉ cần trỏ Slave về Master:

# Trên node Slave
REPLICAOF 192.168.1.10 6380
# Kiểm tra trạng thái đồng bộ
INFO replication

Nếu Master có mật khẩu, Slave cần cấu hình masterauth "MyStr0ngP@ssw0rd!" trong tệp conf. Master chịu trách nhiệm ghi, Slave chỉ đọc. Dữ liệu được đồng bộ một chiều.

4.2. Nguyên Lý Đồng Bộ

  • Full Resynchronization: Khi Slave kết nối lần đầu hoặc mất kết nối vượt quá kích thước backlog buffer, Master tạo RDB snapshot và gửi toàn bộ dataset. Slave nạp vào RAM.
  • Partial Resynchronization: Sau khi đồng bộ đầy đủ, Master chỉ gửi các lệnh ghi mới phát sinh (incremental) dựa trên replication offset, giảm tải mạng và CPU.

4.3. Chế Độ Sentinel (Giám Sát Tự Động)

Sentinel là tiến trình độc lập giám sát cụm Redis, tự động thực hiện failover khi Master gặp sự cố mà không cần can thiệp thủ công.

# sentinel.conf
sentinel monitor redis-cluster-01 192.168.1.10 6380 2
sentinel down-after-milliseconds redis-cluster-01 5000
sentinel failover-timeout redis-cluster-01 15000

Khởi chạy tiến trình giám sát: redis-sentinel ./sentinel.conf

Cơ chế chuyển đổi:

  • Subjective Down (SDOWN): Một Sentinel phát hiện Master không phản hồi sau khoảng thời gian cấu hình.
  • Objective Down (ODOWN): Khi đủ số lượng Sentinel (quorum) xác nhận lỗi, hệ thống bầu chọn Leader Sentinel để thực hiện failover.
  • Slave có độ ưu tiên cao nhất và dữ liệu mới nhất được thăng cấp thành Master mới. Master cũ khi online lại sẽ tự động hạ cấp thành Slave của Master mới.

5. Xử Lý Các Vấn Đề Bộ Nhớ Đệm

5.1. Cache Penetration (Xuyên Thủng)

Xảy ra khi yêu cầu truy vấn dữ liệu không tồn tại cả trong cache lẫn database, khiến mọi request đều đâm thẳng xuống DB, gây quá tải.

Giải pháp:

  • Bloom Filter: Sử dụng cấu trúc dữ liệu xác suất để lọc nhanh các key không hợp lệ trước khi truy vấn cache.
  • Cache Null Object: Lưu giá trị rỗng vào Redis với TTL ngắn (ví dụ: 30-60s) để chặn các request lặp lại cùng một key không tồn tại.

5.2. Cache Breakdown (Đánh Thủng)

Một key nóng (hot key) hết hạn đúng lúc có lượng truy cập cực lớn đổ về, khiến tất cả request đồng loạt query database để rebuild cache.

Giải pháp:

  • Thiết lập TTL dài hoặc không hết hạn cho các key thực sự nóng, cập nhật giá trị nền định kỳ.
  • Sử dụng Distributed Lock (ví dụ: SET resource_name random_value NX PX 30000) để chỉ cho phép một thread duy nhất query DB và ghi cache, các thread còn lại chờ hoặc đọc dữ liệu cũ.

5.3. Cache Avalanche (Sụp Đổ Dây Chuyền)

Hàng loạt key đồng loạt hết hạn cùng thời điểm, hoặc toàn bộ cụm Redis sập, gây quá tải đột ngột cho hệ thống lưu trữ phía sau.

Giải pháp:

  • Phân tán TTL: Thêm giá trị ngẫu nhiên (random jitter) vào thời gian hết hạn của mỗi key để tránh đồng bộ.
  • High Availability Cluster: Triển khai Redis Cluster hoặc Sentinel để loại bỏ single point of failure và phân tải request.
  • Rate Limiting & Degradation: Áp dụng giới hạn tần suất truy cập (token bucket/leaky bucket) và cơ chế hạ cấp dịch vụ khi DB chịu tải cao.
  • Data Warming: Nạp trước dữ liệu quan trọng vào cache trước giờ cao điểm hoặc sau khi khởi động lại dịch vụ.

Thẻ: Redis rdb-persistence aof-persistence redis-sentinel master-slave-replication

Đăng vào ngày 27 tháng 9 lúc 13:58