2013-07-15 5 views
8

私は、HerokuでホストされているDragonflyrack/cacheの組み合わせを使用しています。Herokuのラック/キャッシュで1MBを超えるファイルをキャッシュする方法は?

私はアップロードされたアセットにDragonflyを使用しています。サムネイルはオンザフライで処理され、memcached(Memcachier addon経由)からの高速配信のためにラック/キャッシュに格納されます。

通常の静的資産は、memcachedのラック/キャッシュを介してキャッシュされます。

私の問題は、アップロードされたファイルが1MBを超えると、アプリケーションで500のエラーが発生するということです。

2013-07-15T10:38:27.040992+00:00 app[web.1]: DalliError: Value too large, memcached can only store 1048576 bytes per key [key: d49c36d5db74ef45e957cf169a0b27b83b9e84de, size: 1502314] 
2013-07-15T10:38:27.052255+00:00 app[web.1]: cache: [GET /media/BAhbBlsHOgZmSSIdNTA3Njk3ZWFiODBmNDEwMDEzMDAzNjA4BjoGRVQ/WTW_A5Flyer_HealthcareMedicalObsGynae_WEB.pdf] miss, store 
2013-07-15T10:38:27.060583+00:00 app[web.1]: !! Unexpected error while processing request: undefined method `each' for nil:NilClass 

Memcacheのは、1メガバイトの限界を持っているので、私の資産がキャッシュされなかった理由を私は理解できますが、私はむしろそれが資産を提供壊れていなかったでしょう。

このエラーがどこから来ているのかわかりません。おそらく他のラックミドルウェアの1つからですか?

最大ファイルサイズを大きくしても影響はありません。

config.cache_store = :dalli_store, ENV["MEMCACHIER_SERVERS"].split(","), {¬ 
    :username  => ENV["MEMCACHIER_USERNAME"],¬ 
    :password  => ENV["MEMCACHIER_PASSWORD"],¬ 
    :value_max_bytes => 5242880 # 5MB¬ 
} 

長期的には、私はHerokuののオフ資産のこの種の移動は賢明な動きであることを知っているが、それは迅速な仕事ではありません。

間違いなくHerokuでこれらの資産を提供するにはどうすればよいですか?

答えて

7

私は@jordelverと同じ問題を持っていたとDragonfly::Responseをパッチ猿によってラウンドmemcachierの限界を得ることができた:

基本的に
module Dragonfly 
    class Response 
    private 
    def cache_headers 
     if job.size > 1048576 
     { 
      "Cache-Control" => "no-cache, no-store", 
      "Pragma" => "no-cache" 
     } 
     else 
     { 
      "Cache-Control" => "public, max-age=31536000", # (1 year) 
      "ETag" => %("#{job.signature}") 
     } 
     end 
    end 
    end 
end 

、サイズが1048576バイト以上であれば、キャッシュなしのヘッダーを送信します。

# in config/environments/development.rb 
config.action_dispatch.rack_cache = { 
    metastore: 'file:/var/cache/rack/meta', 
    entitystore: 'file:tmp/cache/rack/body' 
} 

そして、それは動作します:

+0

このソリューションは正常に私のために働いた。ありがとう! – Francois

+1

FYI猿のパッチを適用せずにヘッダーを変更するためのAPIがあります。http://markevans.github.io/dragonfly/configuration/( "response_header"ビット) –

9

@ jordelverの質問とは逆に、私はdalliの:value_max_bytesオプションを設定すると動作することがわかります。私はRack :: Cacheをわずかに異なる方法で設定していますが、これはおそらく違いがあります。

これは私のproduction.rbは、ラックを構成するために含まれているものです::キャッシュ:上記で

client = Dalli::Client.new(ENV["MEMCACHIER_SERVERS"], 
          :username => ENV["MEMCACHIER_USERNAME"], 
          :password => ENV["MEMCACHIER_PASSWORD"], 
          :value_max_bytes => 10485760) 
config.action_dispatch.rack_cache = { 
    :metastore => client, 
    :entitystore => client 
} 
config.static_cache_control = "public, max-age=2592000" 

、多少の誤差は1メガバイトを超える値のためにログに出力されますが、彼らは5xxのエラーが発生することはありませんクライアントにとっては、単にキャッシュミスです。

P.S私はMemCachierのために働いています:)これを整理することに興味があります。それが動作すれば教えてください。

+0

私の場合は、value_max_bytesの値を高く設定しても機能しませんでした。 – Francois

+0

これはちょっと違う問題の正しい方向に私を向ける助けになりました。デビッドに感謝します:) – robotmay

+0

このようにするには、ラックキャッシュ宝石をインストールする必要があります。通常は 'environments/development.rb'で' config.cache_store =:dalli_store'を追加してdalliを有効にします。ここでvalue_max_bytesを指定できますか?ありがとうございました –

0

は私のapplication.jsので、私がやったrack-cacheには大きすぎました!

memcacheにメタデータを格納しますが、ファイルシステム内の実際のファイルはメモリに格納しません。

+1

これは、あなたがHerokuで実行している場合はお勧めできません。 Dynosはメタストアを共有しますが、ファイルシステムは共有しません。つまり、ファイルがメタストアに基づいてキャッシュされることはありますが、ファイルシステムには存在しないため、見つからないことがあります。 – jordelver

+0

Memcacheにファイルを保存することをおすすめしますか? – Dorian

+0

そしてBTW、これは 'development.rb'です – Dorian