2017-04-12 12 views
10

나는 어떻게두 번째 Rails 메모리 내 저장소 캐시를 만들려면 어떻게해야합니까?

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 

내 질문은 ... 나는 currenlty 예를 들어,이 내 state.rb 모델에, DB 쿼리 결과를 캐시 메모리 캐시 레일을 사용하고 있습니다 5. 레일을 할 수 있습니다 사용하고 있습니다 나는 위의 쿼리 캐시를 방해하지 않는 두 번째 메모리 캐시 (인터넷에서 다운로드 한 파일을 저장하는 데 필요한 캐시)를 만듭니다. 내 파일 캐시의 항목이 내 쿼리 캐시의 항목을 축출하도록하지 않습니다.

+0

다른 키만 사용 하시겠습니까? –

+0

그래도 다른 키를 사용하면 단일 캐시에 경쟁 항목이없는 것입니까? 나는 질의를 저장하는 데 사용되는 LRU 엔트리를 축출하기 위해 파일을 저장하는 키를 원한다. 아마 캐시를 이해하지 못할 수도있다. – Dave

답변

7

예, 레일즈에서이 작업을 수행 할 수 있습니다. 두 번째 캐시를 만들어 앱에서 전역 변수로 사용할 수있게 한 다음 컨텍스트에 따라 적절한 캐시를 호출해야합니다. 각 캐시에는 자체 메모리 덩어리 (기본적으로 32MB)가 할당되며 한 캐시가 가득 차면 다른 캐시에는 영향을주지 않습니다. 이는 ActiveSupport::Cache::MemoryStore.new으로 완료됩니다.

나는 두 개의 캐시가 서로 영향을주지 않는다는 것을 보여줄 것입니다 :

먼저 캐시를 테스트하는 데 사용되는 두 개의 텍스트 파일, 하나 10메가바이트 한 30메가바이트 생성 :

dd if=/dev/zero of=10M bs=1m count=10 
dd if=/dev/zero of=30M bs=1m count=30 
을 레일 콘솔을 열고 문자열로 다음을 읽어

:

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

스토어 ten 캐시 :

데이터가 캐시 된 16,
Rails.cache.fetch("ten") { ten }; 0 

확인 : 캐시에

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

스토어 thirty :이 저장되지 않았습니다

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

확인 (캐시에 저장하기에 너무 큰 문자열로 확장 된 경우) :

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

전체 캐시를 확인했습니다 :

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

이제 두 번째 캐시를 생성하고 원래 캐시와 같은 동작을 확인 : storeRails.cache :

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 

지금 두 개의 빈 캐시가 있습니다. 의 그들이 독립적 인 확인하자

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" 

을 두 캐시가 마지막 store.fetch 호출이 모두 캐시를 체포했을 다음 방해합니다. 그것은 단지 store을 체포합니다.같은 당신이 Rails.cache 것 방법

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

전화 새로운 캐시를 코드에서 :

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

의 일부를

는 초기화 config/initializers/cache.rb를 만들고 추가, 앱에서 두 번째 캐시를 구현하려면 자세한 내용은 this answer에서 가져 왔습니다. 새 캐시는 추가 옵션을 지원합니다. 캐시 사용자 정의에 대한 자세한 내용은 MemoryStoreCaching with Rails을 확인하십시오.

이 솔루션은 작은 응용 프로그램에서도 작동합니다. MemoryStore 문서에서이 댓글 참고 : 당신이 (당신이 mongrel_cluster 또는 Phusion 여객를 사용하는 경우의 경우) 레일 서버 프로세스에 여러 개의 루비를 실행하는 경우

를, 다음이 레일 서버 프로세스 인스턴스가 승리한다는 것을 의미 캐시 데이터를 서로 공유 할 수 없으며이 시나리오에서 가장 적합한 캐시가 아닐 수 있습니다.

+0

나는 내 대답을 준비 할 때 이것을 대답하려고했다. 이미 봤어. 훌륭한 설명! –