2011-12-28 29 views
27

Tôi có thể hoàn toàn tắt, nhưng sự hiểu biết của tôi về cách các cửa hàng bộ nhớ cache được sử dụng để hoạt động trước khi họ bắt đầu thêm các tính năng bền bỉ, là các mục sẽ hết hạn dựa trên ttl của chúng. Và nếu các cửa hàng bắt đầu để lấp đầy RAM có sẵn, họ sẽ từng có thuật toán của họ cho hết hạn "quan trọng" phím trong cửa hàng.Redis hoạt động như thế nào khi RAM bắt đầu lấp đầy?

Bây giờ tôi đọc rằng Redis có các tính năng liên tục. Nhưng bạn có thể tắt chúng đi. Giả sử bạn tắt tính kiên trì, điều gì sẽ xảy ra khi RAM tràn đầy? Redis quyết định những gì hết hạn?

Tôi hy vọng sẽ có nhiều dữ liệu không có TTL và muốn đảm bảo an toàn để Redis tìm ra những gì hết hạn.

Trả lời

35

Tôi không nghĩ rằng câu hỏi có liên quan đến quản lý bộ nhớ ảo, nhưng thêm về hết các mục trong Redis, đó là một chủ đề hoàn toàn khác nhau.

Trái với memcached, Redis không chỉ là bộ nhớ cache. Vì vậy, người dùng có nghĩa vụ phải chọn về chính sách gỡ bỏ mục sử dụng các cơ chế khác nhau. Bạn có thể đuổi tất cả các đồ của bạn, hoặc chỉ một phần của chúng.

Chính sách chung nên được chọn trong file cấu hình với các thông số maxmemory và maxmemory-chính sách, decribed dưới đây:

# Don't use more memory than the specified amount of bytes. 
# When the memory limit is reached Redis will try to remove keys with an 
# EXPIRE set. It will try to start freeing keys that are going to expire 
# in little time and preserve keys with a longer time to live. 
# Redis will also try to remove objects from free lists if possible. 
# 
# If all this fails, Redis will start to reply with errors to commands 
# that will use more memory, like SET, LPUSH, and so on, and will continue 
# to reply to most read-only commands like GET. 
# 
# WARNING: maxmemory can be a good idea mainly if you want to use Redis as a 
# 'state' server or cache, not as a real DB. When Redis is used as a real 
# database the memory usage will grow over the weeks, it will be obvious if 
# it is going to use too much memory in the long run, and you'll have the time 
# to upgrade. With maxmemory after the limit is reached you'll start to get 
# errors for write operations, and this may even lead to DB inconsistency. 
# 
maxmemory <bytes> 

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory 
# is reached? You can select among five behavior: 
# 
# volatile-lru -> remove the key with an expire set using an LRU algorithm 
# allkeys-lru -> remove any key accordingly to the LRU algorithm 
# volatile-random -> remove a random key with an expire set 
# allkeys->random -> remove a random key, any key 
# volatile-ttl -> remove the key with the nearest expire time (minor TTL) 
# noeviction -> don't expire at all, just return an error on write operations 
# 
# Note: with all the kind of policies, Redis will return an error on write 
#  operations, when there are not suitable keys for eviction. 
# 
#  At the date of writing this commands are: set setnx setex append 
#  incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd 
#  sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby 
#  zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby 
#  getset mset msetnx exec sort 
# 
# The default is: 
# 
maxmemory-policy volatile-lru 

# LRU and minimal TTL algorithms are not precise algorithms but approximated 
# algorithms (in order to save memory), so you can select as well the sample 
# size to check. For instance for default Redis will check three keys and 
# pick the one that was used less recently, you can change the sample size 
# using the following configuration directive. 
# 
maxmemory-samples 3 

Sau đó, cá nhân hàng hết hạn có thể được thiết lập bằng cách sử dụng lệnh sau: EXPIRE EXPIREAT Thuộc tính hết hạn cho mỗi mục hữu ích với các chính sách dễ bay hơi *. Hết hạn cũng có thể được xóa bằng cách sử dụng PERSIST.

Thuộc tính hết hạn thêm chi phí bộ nhớ nhỏ, vì vậy nó chỉ nên được sử dụng nếu được yêu cầu.

Cuối cùng, điều đáng nói là một phần của đối tượng không thể hết hạn, chỉ toàn bộ đối tượng. Ví dụ: toàn bộ danh sách hoặc tập hợp tương ứng với một khóa có thể hết hạn, nhưng không thể danh sách cá nhân hoặc mục được đặt.

+0

Tuyệt vời, cảm ơn. Vì vậy, thuật toán LRU defaul chính xác là những gì tôi muốn. Chỉ cần thiết lập nó để nó là một máy chủ 'nhà nước'. – joedevon

2

Vui lòng đọc chương Virtual Memory từ tài liệu Redis. Phần liên quan:

VM-max-bộ nhớ thiết Thiết lập vm-max-bộ nhớ xác định có bao nhiêu bộ nhớ Redis là miễn phí để sử dụng trước khi bắt đầu các giá trị trao đổi trên đĩa.

Về cơ bản nếu không đạt đến giới hạn bộ nhớ này, sẽ không có đối tượng nào được đổi chỗ, Redis sẽ làm việc với tất cả các đối tượng trong bộ nhớ như bình thường. Một khi giới hạn này được nhấn tuy nhiên, đủ các đối tượng được hoán đổi để trả lại bộ nhớ vào ngay dưới giới hạn.

Các đối tượng hoán đổi chủ yếu là các đối tượng có độ tuổi cao nhất (nghĩa là số giây kể từ khi chúng chưa được sử dụng), nhưng "khả năng hoán đổi" của một đối tượng cũng tỷ lệ với logarit của kích thước trong trí nhớ. Vì vậy, mặc dù các đối tượng cũ được ưa thích, các đối tượng lớn hơn được hoán đổi trước khi chúng cùng độ tuổi.

CẢNH BÁO: Vì không thể hoán đổi khóa, Redis sẽ không thể tôn trọng cài đặt vm-max-memory nếu chỉ riêng các phím đang sử dụng nhiều không gian hơn giới hạn.

Giá trị tốt nhất cho cài đặt này là đủ RAM để giữ "bộ làm việc" của dữ liệu. Trong điều kiện thực tế, chỉ cần cung cấp cho Redis nhiều bộ nhớ nhất có thể, và trao đổi sẽ hoạt động tốt hơn.

CẬP NHẬT Đối với Redis 2.4 (nó có vẻ như các tài liệu chính thức trên trang web Redis không được cập nhật lên phiên bản đó), nó không được khuyến khích sử dụng VM.

redis.conf nói:

### WARNING! Virtual Memory is deprecated in Redis 2.4 
### The use of Virtual Memory is strongly discouraged. 
+0

Vì bộ nhớ VIrtual không được dùng nữa, cách tốt nhất để sử dụng bộ nhớ trên đĩa khi giới hạn bộ nhớ RAM là bao nhiêu? – harsimranb

+1

@harsimranb Đừng. Nếu bạn đến giai đoạn mà bạn cần đĩa, bạn đã sử dụng sai Redis (hoặc bạn nên tăng RAM, tùy thuộc vào trường hợp sử dụng của bạn). –

2

Hoặc đặt TTL (và để Redis xử lý hết hạn cho bạn) hoặc đăng các mục của bạn bằng dữ liệu cũ của bạn, có thể được lưu dưới dạng bộ ZSET (dấu thời gian, khóa) mà bạn có thể thực hiện bộ nhớ cache của riêng mình theo nhu cầu của riêng bạn.

8

Didier có quyền chỉ ra cách thực hiện điều này. Chỉ cần chỉ ra một số yếu tố bổ sung (một trong số đó dường như bị bỏ qua trong bài đăng của anh ấy):

  1. Chỉ định kích thước bộ nhớ tối đa chiếm hầu hết bộ nhớ sẵn có trên nút đó (để lại một số cho hệ điều hành và các quy trình khác) một số bộ đệm). Điều này sẽ đảm bảo rằng nội dung không bao giờ được phân trang và các hoạt động như vậy là nhanh.
    1. Nếu bạn không đặt TTL/khóa hết hạn thông qua ứng dụng, thì điều quan trọng là bạn sử dụng phương pháp "allkeys-lru". Nếu không, Redis sẽ không hết hiệu lực (vì không có khóa nào dễ bay hơi) và bạn sẽ bắt đầu gặp lỗi khi tất cả bộ nhớ được sử dụng hết - về cơ bản bạn sẽ không thể thực hiện thêm bất kỳ thao tác nào.
    2. Khi sử dụng LRU để loại bỏ phím, điều quan trọng là để thiết lập các thiết lập sau:

maxmemory-mẫu 10

Đây là số lượng mẫu mà Redis sẽ mất và sau đó loại bỏ chìa khóa LRU trong số này. Giá trị mặc định là 3 nhưng cho tất cả các mục đích thực tế, điều này quá thấp - và có thể có nghĩa là các khóa cũ hơn vẫn có thể tồn tại. Đặt giá trị này quá cao sẽ là chi phí cho Redis. Bạn có thể muốn thử nghiệm với cài đặt này một chút trước khi cài đặt. Chúng tôi đang sử dụng giá trị 10.

+0

Cảm ơn sự bổ sung hữu ích. – joedevon

+0

Bạn hoàn toàn đúng @Gur, tôi vừa thử nghiệm nó với các giá trị maxmemory và maxmemory-policy khác nhau. –

Các vấn đề liên quan