Redis là một kho dữ liệu key-value mạnh mẽ, vượt trội với các công việc có độ trễ thấp và thông lượng cao. Tốc độ của nó được cho là do ba yếu tố chính, cùng chúng mình tìm hiểu nhé!!!

Tags: #system design, #microservice, #redis, #backend

Redis, viết tắt của Remote Dictionary Server là một hệ thống lưu trữ dữ liệu key-value trong bộ nhớ mã nguồn mở dùng để lưu trữ dữ liệu có cấu trúc, có thể sử dụng như một database, bộ nhớ cache hay một message broker.

Điểm đặc biệt của Redis nằm ở khả năng lưu trữ toàn bộ dữ liệu trong bộ nhớ RAM, thay vì trên ổ cứng như các hệ thống cơ sở dữ liệu truyền thống.

Với khả năng xử lý hàng trăm nghìn yêu cầu mỗi giây, Redis đã trở thành công cụ không thể thiếu trong việc xây dựng các ứng dụng thời gian thực, hệ thống bộ nhớ đệm (cache) hiệu suất cao, và nhiều ứng dụng khác đòi hỏi tốc độ xử lý dữ liệu vượt trội.

Trong bài viết này, chúng ta sẽ cùng nhau khám phá 3 yếu tố then chốt tạo nên tốc độ vượt trội của Redis:

Lưu trữ dữ liệu trong RAM.
Cấu trúc dữ liệu được tối ưu hóa.
IO Multiplexing & Single-threaded.

Chúng mình có tạo Group cho các bạn cùng chia sẻ và học hỏi về thiết kế hệ thống nha 😄😄😄

Các bạn tham gia để gây dựng cộng đồng System Design Việt Nam thật lớn mạnh nhé 😍😍😍

Cộng Đồng System Design Việt Nam: https://www.facebook.com/groups/sydexa




Lưu trữ dữ liệu trong RAM

Redis nổi bật với khả năng lưu trữ dữ liệu trong RAM , khác biệt so với các hệ quản trị cơ sở dữ liệu truyền thống như PostgreSQL, MySQL hay Cassandra vốn lưu trữ dữ liệu trên ổ đĩa.Trong khi các cơ sở dữ liệu truyền thống sử dụng các cấu trúc dữ liệu trên đĩa như B+ tree hoặc B tree để tối ưu hóa việc truy xuất dữ liệu, Redis hoạt động trực tiếp trên bộ nhớ RAM. Điều này mang lại lợi thế to lớn về mặt tốc độ:

Việc lấy dữ liệu từ RAM nhanh hơn hàng nghìn lần so với truy xuất từ ổ đĩa.
Các cơ sở dữ liệu truyền thống cần gọi đến I/O để đọc dữ liệu từ đĩa, gây ra độ trễ đáng kể. Redis bỏ qua bước này, dữ liệu được lấy trực tiếp từ bộ nhớ.


Cấu trúc dữ liệu được tối ưu hoá

Sức mạnh của Redis không chỉ nằm ở việc lưu trữ dữ liệu trong RAM mà còn ở khả năng cung cấp một loạt các cấu trúc dữ liệu được tối ưu hóa cho hiệu suất cao.

Strings: Cấu trúc dữ liệu cơ bản nhất, có thể lưu trữ string, integer ,float hoặc dữ liệu nhị phân. Redis có thể làm việc với cả string, từng phần của string, cũng như tăng/giảm giá trị của integer, float.
Lists: List là một danh sách của strings, sắp xếp theo thứ tự insert. Redis có thể thêm một phần tử vào đầu hoặc cuối list. List phù hợp cho các bài toán cần thao tác với các phần tử gần đầu và cuối vì việc truy xuất này là cực nhanh, cho dù insert cả triệu phần tử. Tuy nhiên nhược điểm là việc truy cập vào các phần tử ở giữa list rất chậm.
Sets: tập hợp các string (không được sắp xếp). Redis hỗ trợ các thao tác thêm, đọc, xóa từng phần tử, kiểm tra sự xuất hiện của phần tử trong tập hợp. Ngoài ra Redis còn hỗ trợ các phép toán tập hợp, gồm intersect/union/difference.
Sorted Sets: là kiểu dữ liệu tương tự như sets nhưng được sắp xếp theo 1 floating-point number.
Hashed: lưu trữ hash table của các cặp key-value, trong đó key được sắp xếp ngẫu nhiên, không theo thứ tự nào cả. Redis hỗ trợ các thao tác thêm, đọc, xóa từng phần tử, cũng như đọc tất cả giá trị.
Ngoài ra còn các kiểu dữ liệu khác như Streams, Geospatial indexes, Bitmaps, Bitfields, HyperLogLog, có thể tìm hiểu thêm tại Understand Redis data types.

IO Multiplexing & Single-threaded

I/O Multiplexing

I/O Multiplexing là kĩ thuật cho phép Redis theo dõi nhiều kết nối (sockets) cùng lúc. Các hoạt động I/O thường chậm hơn nhiều so với các xử lý trong RAM, nếu phải đợi tuần tự các hoạt động này thực thi xong thì hiệu suất sẽ bị giảm đáng kể.

Do đó, Redis đã sử dụng các cơ chế của hệ điều hành như epoll (Linux) hoặc kqueue (FreeBSD) để thực hiện I/O Multiplexing một cách hiệu quả. Khi có dữ liệu sẵn sàng trên bất kỳ socket nào, Redis sẽ xử lý nó ngay lập tức mà không phải chờ đợi các socket khác.

Event Loop (Vòng lặp sự kiện)

Hoạt động: Redis chạy một vòng lặp sự kiện liên tục theo dõi các sockets. Khi có dữ liệu sẵn sàng, nó sẽ được chuyển vào hàng đợi xử lý (task queue).
Phân loại: Vòng lặp sự kiện phân loại dữ liệu thành các loại khác nhau (ví dụ: đọc dữ liệu từ socket, chấp nhận kết nối mới) và gửi chúng đến các trình xử lý tương ứng.

Single Thread (Đơn luồng)

Redis áp dụng mô hình đơn luồng, nghĩa là tất cả các lệnh đều được xử lý bởi một luồng duy nhất. Điều này mang lại nhiều lợi ích:

Loại bỏ hoàn toàn overhead từ việc chuyển đổi ngữ cảnh (context switching) giữa các luồng.
Tránh được các vấn đề phức tạp liên quan đến đồng bộ hóa và cạnh tranh tài nguyên(locking).

Mô hình này hoạt động hiệu quả vì các thao tác của Redis chủ yếu diễn ra trong bộ nhớ RAM, với tốc độ xử lý ở mức nano giây hoặc micro giây, nhanh hơn nhiều so với thời gian I/O thông thường (mili giây).

Kết hợp các yếu tố:

I/O Multiplexing đảm bảo Redis không bị trì hoãn bởi các hoạt động I/O chậm chạp.
Single Thread loại bỏ overhead, tối ưu hóa hiệu suất.
Event Loop điều phối và quản lý hiệu quả các tác vụ.

Vậy Redis có phải đơn luồng không?

Câu trả lời là không. Redis sử dụng một luồng duy nhất chỉ để xử lý nhiều kết nối client và thực thi các lệnh. Nó sử dụng các background thread cho các tác vụ như persistence và replication.

Redis có lợi khi sử dụng nhiều luồng cho các kết nối client không?

Vì hầu hết các hoạt động đều diễn ra ở bộ nhớ trong và không liên quan đến network I/O mạng hay file I/O, Redis sẽ không có bất kỳ cải thiện đáng chú ý nào về hiệu suất. Hơn nữa, sử dụng nhiều luồng sẽ đi kèm với tăng chi phí.

Chuyển đổi ngữ cảnh luồng dẫn đến overhead. Ngoài ra, việc sử dụng lock và monitor sẽ làm tăng thêm độ phức tạp trong code.

Kết luận

Redis là một kho dữ liệu key-value mạnh mẽ, vượt trội với các công việc có độ trễ thấp và thông lượng cao. Tốc độ của nó được cho là do ba yếu tố chính:

Lưu trữ dữ liệu trong bộ nhớ: Redis lưu trữ tất cả dữ liệu trong bộ nhớ, mang lại lợi thế về tốc độ đáng kể so với các cơ sở dữ liệu truyền thống.
Cấu trúc dữ liệu được tối ưu hóa: Redis hỗ trợ các cấu trúc dữ liệu hiệu quả cao như lists, strings, sorted set, v.v.
Multiplexing I/O: Redis xử lý hiệu quả một số lượng lớn các kết nối client đồng thời bằng cách sử dụng single thread và multiplexing I/O với epoll().



Chúng mình có tạo Group cho các bạn cùng chia sẻ và học hỏi về thiết kế hệ thống nha 😄😄😄

Các bạn tham gia để gây dựng cộng đồng System Design Việt Nam thật lớn mạnh nhé 😍😍😍

Cộng Đồng System Design Việt Nam: https://www.facebook.com/groups/sydexa

SYDEXA
We learn, we share, we grow together!

About

  • Sydexa

Resources

  • Docs
  • Sydexa Hub

Contact

  • For Work
  • Report

Members

  • Sign in
  • Sign up
  • Portal
@ Sydexa 2024. All copyrights reserved