- vừa được xem lúc

Time-To-Live (TTL) trong Redis hoạt động như nào?

0 0 18

Người đăng: System Design VN

Theo Viblo Asia

Redis là một công nghệ cool ngầu. Nó giải quyết nhiều bài toán khó về caching và distributed system (hệ phân tán). Ngoài ra, nó còn support nhiều cấu trúc dữ liệu đáp ứng cho nhiều use case khác nhau và nhiều algorithm ẩn bên trong.

Hôm nay mình và các bạn sẽ cùng tìm hiểu:

  • Time-To-Live (TTL) trong Redis hoạt động như nào?
  • Những vấn đề mà các cách tiếp cận gặp phải
  • Best Practices khi đặt TTL

Định nghĩa Time-To-Live (TTL)

Time-To-Live là khái niệm phổ biến được sử dụng trong 2 lĩnh vực:

  • Mạng máy tính (Computer Networking): Mỗi packet (network layer) chứa 1 trường TTL dùng để đếm số router (hop) mà packet có thể đi qua được. Khi đi qua mỗi router (hop), TTL sẽ bị trừ đi 1 đơn vị. Nếu TTL = 0 thì packet sẽ bị drop.
  • Bộ nhớ đệm (Caching): TTL ám chỉ khoảng thời gian mà dữ liệu được lưu trước khi dữ liệu đó bị xoá đi. Việc xoá dữ liệu này phản ánh dữ liệu có thể còn không hợp lệ và giúp giải phóng bộ nhớ.

Time-To-Live trong Redis hoạt động như nào?

Khi một key được cài đặt Time-To-Live, sau khoảng thời gian TTL đó, key đó sẽ tự động được xoá đi.

Cách tiếp cận ban đầu

Redis sử dụng và kết hợp đồng thời 2 cách để xoá key khi hết hạn:

Passive Way:

Redis không xoá key ngay khi hết hạn. Cho tới khi ta lấy (GET) key đó, Redis mới check key đã hết hạn chưa. Nếu đã hết hạn thì sẽ trả về null trước rồi xoá key đó đi một cách bất đồng bộ.

Cách này khá đơn giản nhưng gặp 1 vấn đề. Đó là có những key mà sẽ bao giờ được động tới, như vậy nó sẽ chiếm không gian nhớ. Để khắc phục tình trạng này, Redis kết hợp với Active Way - xoá chủ động.

Active Way:

Redis thực hiện job xoá key chủ động 10 lần / giây (trong code gọi là activeExpireCycle)

  • Bước 1: Lấy random 20 keys có gắn TTL. Trong có thể có keys hết hạn và key chưa hết hạn.
  • Bước 2: Thử xoá 20 keys đó
  • Bước 3: Nếu có nhiều hơn 25% của 20 keys bị hết hạn, lặp lại bước 1.

Do Redis hoạt động dựa trên single-thread, khi job xoá key chủ động chạy thì sẽ block các request khác. Do đó, Redis có cấu hình timeout cho job này tránh tình trạng bị treo do quá nhiều key đồng thời hết hạn.

Việc kết hợp 2 cách này hoạt động rất tốt trong hầu hết các trường hợp thực tế. Tuy nhiên vẫn có trường số lượng key expire lớn và việc lấy sampling random khiến job activeExpireCycle hoạt động không hiệu quả. Mọi người có thể đọc thêm ở reference [4].

Cách tiếp cận mới

Redis khắc phục nhược điểm của cách tiếp cận trên bằng cách: các key sẽ được sắp xếp bởi thời gian hết hạn (expiration time) và lưu trong Sorted Set (ZSET) giúp cho việc tìm kiếm key hết hạn nhanh chóng hơn.

*Lưu ý: Có người nói key được sort bởi Radix Tree. Nhưng phần này mình thấy trong code và document không nói rõ ràng. Nếu bạn biết chính xác keys được sort như nào thì comment bên dưới giúp mình để mọi người rõ hơn nhé.

Best Practices khi đặt TTL

  • Dựa trên yêu cầu nghiệp vụ: dựa vào ý nghĩa của dữ liệu mà ta đặt TTL cho phù hợp. Ví dụ dữ liệu về session thì có TTL ngắn hơn so với static content như ảnh, đường dẫn, …
  • Đối với những TTL dài thì ta cần random các giá trị này để chúng được dải đều ra. Tránh tình trạng “thundering herd" xảy ra khi tất cả key đồng thời hết hạn, gây ra load cao ở các tầng app và DB
  • Sử dụng đúng kiểu dữ liệu: Không phải tất cả kiểu dữ liệu điều có cơ chế TTL giống nhau. Ví dụ, List và Set hỗ trợ TTL theo từng phần tử, còn Sorted Set và Hash thì không.
  • Chú ý cấu hình Eviction Policy dựa trên yêu cầu của hệ thống. Khi Redis ăn hết mem, nó sẽ evict key dựa trên cấu hình (LRU, LFU, …)
  • Nếu không có yêu cầu đặc biệt từ nghiệp vụ thì thông thường nên đặt TTL ngắn để tránh chiếm mem và dữ liệu được update.
  • Nếu bạn có bổ sung thêm best practice thì comment bên dưới giúp mình nhé.

📚️ Ronin Engineer: https://ronin-engineer.github.io/register-post

🏢 System Design VN: https://fb.com/groups/systemdesign.vn


Tham Khảo

[1] https://redis.com/ebook/part-2-core-concepts/chapter-3-commands-in-redis/3-7-other-commands/3-7-3-expiring-keys/

[2] https://redis.io/commands/expire/

[3] https://github.com/redis/redis/blob/7.0.12/src/expire.c

[4] https://blog.twitter.com/engineering/en_us/topics/infrastructure/2019/improving-key-expiration-in-redis

Bình luận

Bài viết tương tự

- vừa được xem lúc

Caching đại pháp 2: Cache thế nào cho hợp lý?

Caching rất dễ. Mình không nói đùa đâu, caching rất là dễ. Ai cũng có thể làm được chỉ sau 10 phút đọc tutorial. Nó cũng giống như việc đứa trẻ lên 3 đã có thể cầm bút để vẽ vậy.

0 0 126

- vừa được xem lúc

Caching đại pháp 1: Nấc thang lên level của developer

Bí quyết thành công trong việc đáp ứng hệ thống triệu user của những công ty lớn (và cả công ty nhỏ). Tại sao caching lại là kỹ thuật tối quan trọng để phù phép ứng dụng rùa bò của chúng ta thành siêu phẩm vạn người mê.

0 0 82

- vừa được xem lúc

Cache dữ liệu Nodejs với Redis

Một tí gọi là lý thuyết để anh em tham khảo. Cache là gì. Lợi ích của việc cache data. .

0 0 111

- vừa được xem lúc

Nguyên tắc hoạt động của redis server

Sự ra đời của Redis. . Câu chuyện bắt đầu khi tác giả của Redis, Salvatore Sanfilippo. (nickname: antirez), cố gắng làm những công việc gần như là không.

0 0 97

- vừa được xem lúc

Viết ứng dụng chat realtime với Laravel, VueJS, Redis và Socket.IO, Laravel Echo

Xin chào tất cả các bạn, đây là một trong những bài post đầu tiên của mình. Sau bao năm toàn đi đọc các blog tích luỹ được chút kiến thức của các cao nhân trên mạng.

0 0 918

- vừa được xem lúc

Tìm hiểu tổng quan về Redis

1. Lời mở đầu.

0 0 368