Kiến Trúc Nội Tại Và Cơ Chế Triển Khai Của Hệ Thống Cache Redis

Hệ Thống Cấu Trúc Dữ Liệu Và Đối Tượng

Sử dụng chuỗi động đơn giản (SDS - Simple Dynamic String) làm nền tảng cho việc lưu trữ văn bản là điểm khác biệt lớn của Redis so với C truyền thống. Cấu trúc dữ liệu này được định nghĩa để tối ưu hóa hiệu suất và an toàn bộ nhớ.

typedef struct redis_dynamic_string_header {
    // Số lượng byte đã sử dụng cho nội dung thực tế
    unsigned int stored_length;
    // Số lượng byte chưa dùng đến trong bộ đệm
    unsigned int unused_space;
    // Mảng chứa dữ liệu chuỗi
    char data_buffer[];
} redis_sds_header;

Một số đặc điểm cốt lõi của cấu trúc trên:

  • Nếu thuộc tính bộ đệm chưa dùng bằng 0, hệ thống không cấp phát thêm khoảng trống dư thừa.
  • Thuộc tính độ dài lưu trữ thông tin chính xác về ký tự mà không cần duyệt qua mảng.
  • Dữ liệu cuối cùng luôn được đóng dấu bằng ký tự null '\0' theo chuẩn C, giúp tương thích với các thư viện xử lý chuỗi sẵn có.
  • Việc quản lý bộ đệm được tự động hóa bởi các hàm API, ngăn chặn lỗi tràn bộ nhớ (buffer overflow).
  • SDS hỗ trợ lưu trữ nhị phân (binary-safe), nghĩa là nó xử lý mọi dữ liệu dưới dạng byte mà không giả định đây chỉ là văn bản ASCII.

Khác với chuỗi C truyền thống có độ phức tạp O(N) khi lấy độ dài, SDS cho phép truy xuất kích thước nhanh chóng ở mức O(1). Khi mở rộng, cơ chế này cũng giảm thiểu số lần phân bổ lại bộ nhớ thông qua chiến lược phân bổ trước (预分配) và thu hồi bộ nhớ thụ động (惰性释放).

Cấu trúc Danh sách Liên Kết (Linked List)

Để quản lý danh sách phần tử, Redis sử dụng cấu trúc nút liên kết hai chiều. Mỗi nút trỏ đến cả nút trước và nút sau, đồng thời giữ con trỏ trỏ vào giá trị thực.

typedef struct linked_list_node {
    struct linked_list_node *prev_ptr;
    struct linked_list_node *next_ptr;
    void *node_value;
} linked_list_node_t;

Toàn bộ danh sách được bao bọc bởi một cấu trúc quản lý duy nhất, chứa tham chiếu tới đầu và cuối, tổng số lượng nút, cùng các hàm tùy chỉnh để sao chép hoặc giải phóng dữ liệu bên trong.

Bảng Hash (Dictionary)

Dòng chảy dữ liệu chính của Redis dựa trên bảng hash. Cấu trúc bảng hash bao gồm mảng các nút con và các tham số kiểm soát kích thước.

typedef struct hash_table_structure {
    dict_entry **table_array;
    unsigned long current_capacity;
    unsigned long capacity_mask;
    unsigned long active_items_count;
} redis_dict_ht;

Các nút trong bảng hash (dictEntry) lưu trữ cặp khóa-giá trị và sử dụng cơ chế nối tiếp (chaining) qua con trỏ next để xử lý va chạm khóa (collision). Khi kích thước dữ liệu thay đổi vượt ngưỡng tải (load factor), cơ chế tái băm (rehash) sẽ được kích hoạt.

Cấu trúc Dãy Chéo (Skip List)

Đối với tập hợp sắp xếp (Sorted Set), Redis tận dụng cấu trúc dãy chéo để đảm bảo thao tác chèn và tìm kiếm hiệu quả O(log N).

typedef struct skip_node {
    struct skip_level {
        struct skip_node *forward;
        unsigned int span;
    } levels[];
    struct skip_node *backward;
    double score_val;
    robj *element_ref;
} skip_node;

Mỗi lớp trong dãy chéo chứa con trỏ tiến về phía sau và độ跨度 (span), giúp việc nhảy giữa các phần tử trở nên nhanh hơn so với danh sách liên kết đơn thuần.

Tập Hợp Số nguyên (Int Set) và Bảng Nén (Zip List)

Khi dữ liệu tập hợp nhỏ gọn, Redis ưu tiên dùng Int Set để tiết kiệm RAM. Nếu dữ liệu không phải số nguyên hoặc quá lớn, nó chuyển sang dùng Hash Table. Tương tự, Zip List (Compressed List) được dùng cho List và Hash khi số lượng ít và kích thước nhỏ, giúp nén nhiều mục vào một khối bộ nhớ liên tục.

Hệ Thống Cơ Sở Dữ Liệu Đơn Node

Bộ nhớ tạm thời của Redis lưu trữ tất cả các database con trong một mảng trạng thái. Mỗi database con đều sở hữu một không gian khóa riêng biệt.

Quản Lý Thời Hạn Sống (TTL)

Keys có thể được gắn thời gian sống tự động thông qua các lệnh như EXPIRE. Chiến lược xóa keys hết hạn kết hợp giữa phương pháp từ chối (lazy deletion) khi truy cập và quét định kỳ (periodic delete) để cân bằng giữa CPU và bộ nhớ.

Persistence: RDB và AOF

Để đảm bảo an toàn dữ liệu khi tắt máy, Redis cung cấp hai cơ chế ghi ra đĩa:

  1. RDB (ReDIS Backup): Tạo snapshot toàn bộ trạng thái tại một thời điểm cụ thể. Quá trình thường diễn ra song song với tiến trình con để tránh block server.
  2. AOF (Append Only File): Ghi lại từng lệnh ghi nhận. Có ba chế độ đồng bộ hóa: always (an toàn nhất), everysec (cân bằng), hoặc no (tùy thuộc OS).

Khi restart, nếu có cả RDB và AOF, Redis ưu tiên phục hồi từ AOF vì độ mới của dữ liệu cao hơn.

Cơ Chế Xử Lý Sự Kiện

Server vận hành dựa trên Reactor pattern với vòng lặp sự kiện (event loop). Nó lắng nghe các socket sự kiện (file event) và các sự kiện theo giờ (time event) để xử lý lịch trình, dọn dẹp tài nguyên và cập nhật bộ đếm.

Mở Rộng Đa Node: Sao Chép, Sentinel Và Cluster

Sao Chép (Replication)

Một master node gửi dữ liệu đến slave node thông qua cơ chế truyền tải. Ban đầu là full sync qua RDB file, sau đó là incremental updates. Để giảm thiểu lỗi mất kết nối, Redis sử dụng cơ chế Partial Sync qua复制积压缓冲区 (replication backlog).

Sentinel: Giám Sát Cao

Sentinel hệ thống giúp giám sát tình trạng của master/slave. Nếu master fail, Sentinel tự động bầu chọn một slave lên làm master mới (Failover). Nó hoạt động bằng cách trao đổi tin nhắn PING/PONG và thực hiện bỏ phiếu để đạt đa số (quorum).

Clustering: Chia Nhánh Dữ Liệu

Cấu trúc Cluster chia 16384 slots để phân phối dữ liệu trên nhiều node. Client khi gửi lệnh sẽ tính CRC16(key) % 16384 để xác định slot thuộc về node nào. Nếu node nhận không đúng slot, nó trả về lỗiMOVED kèm địa chỉ IP đúng để client tự chuyển hướng.

Sự di chuyển dữ liệu (resharding) được thực hiện online qua công cụ redis-trib, cho phép di chuyển slot từ nguồn sang đích mà không downtime hệ thống.

Các Tính Năng Chuyên Biệt

Xử Lý Lệnh Lua

Cho phép chạy script Lua trực tiếp trên server để tăng tốc độ thực thi tập lệnh. Script được cache lại dựa trên SHA1 hash để tránh load lại mã nguồn nhiều lần. Các lệnh EVAL và EVALSHA được dùng để thực thi hoặc gọi script đã cache.

事务 (Transactions) & Optmistic Locking

Redis hỗ trợ MULTI/EXEC nhưng không có rollback. WATCH command được dùng để theo dõi các keys, nếu key bị sửa trước khi EXEC thì transaction sẽ hủy bỏ (optimistic locking).

发布/订阅 (Pub/Sub) & Bit Map

Cơ chế Pub/Sub hoạt động qua channels và patterns, gửi tin tức ngay lập tức tới người đăng ký. Ngoài ra, BITOPS cung cấp các phép tính bit (AND, OR, XOR) trên các chuỗi bit array cực kỳ nhanh, hữu ích cho việc lưu thẻ bài (bloom filter) hoặc đếm độc quyền.

Ghi Chậm (Slow Log) & Giám Sát (Monitor)

Sys admin có thể dùng SLOWLOG GET để xem các lệnh tiêu tốn nhiều thời gian xử lý. MONITOR cho phép nhìn thấy luồng lệnh real-time đang chạy trên server, hữu ích cho debug nhưng không nên dùng cho production do ảnh hưởng hiệu năng.

Thẻ: Redis sdstr dictionary skip-list replication

Đăng vào ngày 19 tháng 5 lúc 00:14