2017-04-12 29 views
10

Tôi đang sử dụng Rails 5. Tôi currenlty sử dụng Rails bộ nhớ cache trong bộ nhớ cache db kết quả truy vấn, ví dụ, đây là trong mô hình state.rb tôi ...Làm cách nào để tạo bộ đệm lưu trữ trong bộ nhớ trong Rails thứ hai?

def self.cached_find_by_iso_and_country_id(iso, country_id) 
    if iso 
     Rails.cache.fetch("#{iso.strip.upcase} #{country_id}") do 
     find_by_iso_and_country_id(iso.strip.upcase, country_id) 
     end 
    end 
    end 

Câu hỏi của tôi là, làm thế nào có thể Tôi tạo bộ nhớ cache Rails thứ hai trong bộ nhớ (tôi cần một bộ nhớ để lưu trữ các tệp mà tôi đã tải xuống từ Internet) mà không ảnh hưởng đến bộ nhớ cache truy vấn mà tôi có ở trên? Tôi không muốn các mục trong bộ nhớ cache tệp của mình gây ra các mục trong bộ đệm truy vấn của tôi bị xóa.

+0

Chỉ cần sử dụng một khóa khác? –

+0

Vâng, nhưng nếu tôi sử dụng một khóa khác thì hiện tại không có các mục cạnh tranh trong một bộ nhớ cache đơn? Tôi không muốn chìa khóa của tôi để lưu trữ các tập tin để loại bỏ các mục LRU được sử dụng để lưu trữ các truy vấn ... có lẽ tôi không hiểu bộ nhớ cache mặc dù. – Dave

Trả lời

7

Có, bạn có thể thực hiện việc này với Rails. Bạn cần phải tạo một bộ nhớ cache thứ hai và làm cho nó có sẵn trong ứng dụng của bạn như là một biến toàn cầu, sau đó gọi bộ nhớ cache thích hợp tùy thuộc vào ngữ cảnh. Mỗi bộ nhớ cache được gán riêng bộ nhớ riêng của nó (mặc định là 32 MB) và nếu một bộ nhớ đệm được lấp đầy nó sẽ không ảnh hưởng đến bộ đệm ẩn khác. Việc này được thực hiện với ActiveSupport::Cache::MemoryStore.new.

tôi sẽ chứng minh rằng hai bộ nhớ đệm không ảnh hưởng lẫn nhau:

Thứ nhất, tạo ra hai tập tin văn bản sẽ được sử dụng để kiểm tra bộ nhớ cache, một 10 MB và một 30 MB:

dd if=/dev/zero of=10M bs=1m count=10 
dd if=/dev/zero of=30M bs=1m count=30 

Mở Rails giao diện điều khiển và đọc những thành chuỗi:

ten = File.read("10M"); 0 
thirty = File.read("30M"); 0 

cửa hàng ten trong bộ nhớ cache:

01.
Rails.cache.fetch("ten") { ten }; 0 

Xác nhận các dữ liệu được lưu trữ:

Rails.cache.fetch("ten")[0..10] 
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" 

cửa hàng thirty trong bộ nhớ cache:

Rails.cache.fetch("thirty") { thirty }; 0 

Xác nhận này không được lưu (quá lớn để lưu trong bộ nhớ cache khi mở rộng như là một chuỗi) :

Rails.cache.fetch("thirty")[0..10] 
NoMethodError: undefined method `[]' for nil:NilClass 

Xác nhận điều này đã xóa toàn bộ bộ nhớ cache:

Rails.cache.fetch("ten")[0..10] 
NoMethodError: undefined method `[]' for nil:NilClass 

Bây giờ tạo ra một bộ nhớ cache thứ hai và xác nhận nó cư xử giống hệt với bộ nhớ cache gốc:

store = ActiveSupport::Cache::MemoryStore.new 
store.fetch("ten") { ten }; 0 
store.fetch("ten")[0..10] 
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" 
store.fetch("thirty") { thirty }; 0 
store.fetch("thirty")[0..10] 
NoMethodError: undefined method `[]' for nil:NilClass 
store.fetch("ten")[0..10] 
NoMethodError: undefined method `[]' for nil:NilClass 

Bây giờ có hai cache trống: storeRails.cache. Hãy xác nhận họ là độc lập:

Rails.cache.fetch("ten") { ten }; 0 
Rails.cache.fetch("ten")[0..10] 
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" 
store.fetch("thirty") { thirty }; 0 # bust the `store' cache 
Rails.cache.fetch("ten")[0..10] 
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" 

Nếu hai cache can thiệp thì store.fetch cuộc gọi cuối cùng sẽ vỡ cả cache. Nó chỉ chuyển đổi store.

Để thực hiện một bộ nhớ cache thứ hai trong ứng dụng của bạn, tạo ra một initializer config/initializers/cache.rb và thêm:

$cache = ActiveSupport::Cache::MemoryStore.new 

Gọi cache mới trong mã của bạn giống như cách bạn sẽ Rails.cache:

$cache.fetch("foo") { "bar" } 

Một số những chi tiết này được lấy từ this answer. Bộ nhớ cache mới hỗ trợ các tùy chọn bổ sung; kiểm tra MemoryStoreCaching with Rails để biết thêm thông tin về tùy chỉnh bộ nhớ cache.

Giải pháp này sẽ hoạt động đối với các ứng dụng nhỏ. Lưu ý nhận xét này từ MemoryStore tài liệu:

Nếu bạn đang chạy nhiều Ruby on Rails quá trình máy chủ (đó là trường hợp nếu bạn đang sử dụng mongrel_cluster hoặc Phusion tải hành khách), sau đó điều này có nghĩa rằng trường hợp Rails quá trình máy chủ thắng Không thể chia sẻ dữ liệu bộ nhớ cache với nhau và điều này có thể không phải là bộ nhớ cache thích hợp nhất trong kịch bản đó.

+0

Tôi chuẩn bị trả lời câu hỏi này khi tôi đang chuẩn bị câu trả lời của mình. Nhìn thấy bạn đã làm. Giải thích tuyệt vời! –

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