Redis
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> Redis

làm thế nào để xử lý phiên hết hạn dựa trên redis?

Vì vậy, bạn cần ứng dụng của mình được thông báo khi một phiên hết hạn trong Redis.

Mặc dù Redis không hỗ trợ tính năng này, nhưng bạn có thể sử dụng một số thủ thuật để triển khai tính năng này.

Cập nhật:Từ phiên bản 2.8.0, Redis không hỗ trợ http://redis.io/topics/notifications này

Đầu tiên, mọi người đang nghĩ về nó:điều này vẫn đang được thảo luận, nhưng nó có thể được thêm vào phiên bản Redis trong tương lai. Xem các vấn đề sau:

  • https://github.com/antirez/redis/issues/83
  • https://github.com/antirez/redis/issues/594

Bây giờ, đây là một số giải pháp bạn có thể sử dụng với các phiên bản Redis hiện tại.

Giải pháp 1:vá Redis

Trên thực tế, việc thêm một thông báo đơn giản khi Redis thực hiện hết hạn khóa không khó lắm. Nó có thể được thực hiện bằng cách thêm 10 dòng vào tệp db.c của mã nguồn Redis. Đây là một ví dụ:

https://gist.github.com/3258233

Bản vá ngắn này đăng một khóa vào danh sách #expired nếu khóa đã hết hạn và bắt đầu bằng ký tự '@' (lựa chọn tùy ý). Nó có thể dễ dàng được điều chỉnh theo nhu cầu của bạn.

Sau đó, việc sử dụng các lệnh EXPIRE hoặc SETEX để đặt thời gian hết hạn cho các đối tượng phiên của bạn và viết một daemon nhỏ lặp lại trên BRPOP để hủy hàng từ danh sách "#expired" và truyền thông báo trong ứng dụng của bạn là điều không cần thiết.

Một điểm quan trọng là phải hiểu cơ chế hết hạn hoạt động như thế nào trong Redis. Trên thực tế, có hai đường dẫn khác nhau để hết hạn, cả hai đều hoạt động cùng một lúc:

  • Cơ chế lười biếng (thụ động). Việc hết hạn có thể xảy ra mỗi khi một khóa được truy cập.

  • Cơ chế hoạt động. Công việc nội bộ thường xuyên (ngẫu nhiên) lấy mẫu một số khóa đã đặt hết hạn, cố gắng tìm những khóa sắp hết hạn.

Lưu ý rằng bản vá ở trên hoạt động tốt với cả hai đường dẫn.

Hệ quả là thời gian hết hạn của Redis không chính xác. Nếu tất cả các khóa đã hết hạn, nhưng chỉ một khóa sắp hết hạn và nó không được truy cập, công việc hết hạn hoạt động có thể mất vài phút để tìm khóa và hết hạn. Nếu bạn cần một số thông báo chính xác thì đây không phải là cách để thực hiện.

Giải pháp 2:mô phỏng hết hạn với zsets

Ý tưởng ở đây là không dựa vào cơ chế hết hạn khóa Redis mà hãy mô phỏng nó bằng cách sử dụng một chỉ mục bổ sung cộng với một daemon thăm dò. Nó có thể hoạt động với phiên bản Redis 2.6 chưa sửa đổi.

Mỗi khi một phiên được thêm vào Redis, bạn có thể chạy:

MULTI
SET <session id> <session content>
ZADD to_be_expired <current timestamp + session timeout> <session id>
EXEC

Tập hợp được sắp xếp to_be_expired chỉ là một cách hiệu quả để truy cập các khóa đầu tiên sẽ hết hạn. Một daemon có thể thăm dò ý kiến ​​trên to_be_expired bằng cách sử dụng tập lệnh phía máy chủ Lua sau:

local res = redis.call('ZRANGEBYSCORE',KEYS[1], 0, ARGV[1], 'LIMIT', 0, 10 )
if #res > 0 then
   redis.call( 'ZREMRANGEBYRANK', KEYS[1], 0, #res-1 )
   return res
else
   return false
end

Lệnh khởi chạy tập lệnh sẽ là:

EVAL <script> 1 to_be_expired <current timestamp>

Daemon sẽ nhận được nhiều nhất 10 vật phẩm. Đối với mỗi người trong số họ, nó phải sử dụng lệnh DEL để loại bỏ các phiên và thông báo cho ứng dụng. Nếu một mục thực sự đã được xử lý (tức là trả về của tập lệnh Lua không trống), thì daemon sẽ lặp lại ngay lập tức, nếu không, trạng thái chờ 1 giây có thể được đưa ra.

Nhờ tập lệnh Lua, có thể khởi chạy một số trình duyệt thăm dò song song (tập lệnh đảm bảo rằng một phiên nhất định sẽ chỉ được xử lý một lần, vì các khóa được xóa khỏi to_be_expired bởi chính tập lệnh Lua).

Giải pháp 3:sử dụng bộ hẹn giờ được phân phối bên ngoài

Một giải pháp khác là dựa vào một bộ đếm thời gian phân tán bên ngoài. Hệ thống xếp hàng nhẹ bằng cây đậu là một khả năng tốt cho việc này

Mỗi khi một phiên được thêm vào hệ thống, ứng dụng sẽ đăng ID phiên vào hàng đợi cây đậu với độ trễ tương ứng với thời gian hết phiên. Một daemon đang lắng nghe hàng đợi. Khi nó có thể xếp hàng lại một mục, điều đó có nghĩa là một phiên đã hết hạn. Nó chỉ phải làm sạch phiên trong Redis và thông báo cho ứng dụng.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Đọc dữ liệu từ Redis sang Flink

  2. Redis không chọn các sự kiện phát sóng trong Laravel 5.1

  3. đợi tất cả lời hứa kết thúc trong nodejs với bluebird

  4. Tính khả dụng cao với Redis Sentinels:Kết nối với Redis Master / Slave Sets

  5. Rdbtools tại Redis Conf18