Rails フラグメント キャッシュにおける memcached のワイルドカード有効期限の欠如を回避する

StackOverflow https://stackoverflow.com/questions/4013763

質問

ログインしているユーザーと匿名ユーザーの両方がいる Rails 3 サイトにフラグメント キャッシュを追加する作業を行っており、サイト全体に表示されるコンテンツがいつ更新されるかに基づいて、ページの一部の有効期限が切れる時期を制御する必要があります。この作業の途中で、memcached がexpire_fragment の正規表現をサポートしていないことが判明したので、現在これを回避する方法を探しています。

匿名ユーザーにとって、これは大きな問題ではありません。「frontpage-new-shows」や「schedule-weekly-forecast-10/24/10」のようなキャッシュ キーを作成し、番組モデルに新しいエントリが作成されたとき、または番組が来週中に放送されるときに期限切れにします。スイーパーを介して変更されます。それはうまくいきます。

私の問題は、ログインしているユーザーにあります。それぞれ独自にカスタマイズされたスケジュールがあるため、私のキーは「schedule-user-jschuur-10/10/24」のようになり、jschuur がアカウントのユーザー名になります。日付ベースの規則では自然に期限切れになることは理解していますが、その日(または週)のスケジュール内の何かに番組関連の変更が発生した場合、その日中にキャッシュされたスケジュールのすべてのフラグメントを明示的に期限切れにしたいと考えています。

結局のところ、memcached はここで必要な種類のワイルドカード有効期限 (schedule-user-.*-10/10/24) を実行できません。これは、発行されたすべてのキーを memcached の中央検索キーに保存する、または memcached に送信したキーに基づいて Rails/Ruby に何らかの方法で内部的にこれを実行させる、ある種のソリューションが必要であることを意味します。

前者の方が良い解決策だと思います。私の質問は、これを最も効率的な方法で行うにはどうすればよいかということです。そうすれば、DB にヒットすることなく節約された時間をすべて吹き飛ばすことがなくなります。配列またはハッシュを memcached に保存し、全体を取得し、一致する場合は if をループして、それらを削除してハッシュを保存し直すだけです。数百人、あるいは千人のユーザーにとってはうまく機能するように思えますが、これが本当に最善の方法なのでしょうか?

誰かがすでにこの問題に取り組み、解決策をリリースしましたか?

考慮すべき点の 1 つは、現在、ほとんどすべてのキャッシュが、次のようなまだ実行されていない ActiveRelations の準備済みクエリを対象としたビュー内のステートメントで行われていることです。

<% if current_user %>
  <% if current_user.saved_shows_count %>
    <% cache "schedule-user-#{current_user.username}-#{(Time.now + 3.hours).to_date.end_of_week.strftime('%D')}" do %>
      <% if @shows.any? %>
        <%= render :partial => "schedule/schedule", :locals => { :shows => @shows } %>
      <% end %>
    <% end %>
...

このサイトは Heroku でホストされており、クライアントとして dalli gem を使用しています。

役に立ちましたか?

解決

編集: dalli gemで書かれたように、これにはいくつかの問題があり、読み取りを実行すると「マーシャルデータが短すぎる」または「memcache内のマーシャルされたデータが無効です」が発生します。あなたにもそれが当てはまるかどうかはわかりません。

少しハック的ではありますが、名前空間を使用してから名前空間を増やし、それを使用して作成されたすべてのキーを無効にすることができます。これを行うには、まずイニシャライザ (または任意の場所) で名前空間を設定します。 Rails.cache.write("frontpage-new-shows-namespace", "1", {:raw => true}). 。各キャッシュを設定するときに追加します Rails.cache.read("frontpage-new-shows-namespace") 好きな場所にハッシュキーを入力します (場所は特に重要ではありません)。名前空間で作成されたすべてのキャッシュ キーを期限切れにするのは、次のように簡単です。 Rails.cache.increment("frontpage-new-shows-namespace", 1). 。追加できるかもしれません Rails.cache.read("frontpage-new-shows-namespace") グローバル変数として使用し、キャッシュ キーを作成するための memcache 検索を排除し、キャッシュ名前空間の増分を行うたびにこの変数を更新します。

頑張ってください。お役に立てば幸いです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top