web-dev-qa-db-ja.com

HerokuDeployでMemcachedをクリアする

RailsアプリをHerokuにデプロイするときにMemcachedを自動的にクリアする最良の方法は何ですか?

ホームページをキャッシュしていますが、変更を加えて再デプロイすると、ページがキャッシュから提供され、更新が組み込まれません。

これを完全に自動化したいと思います。デプロイするたびにherokuコンソールのキャッシュをクリアする必要はありません。

ありがとう!

33
Solomon

GitHubとHerokuPush、データベースの移行、アプリケーションのメンテナンスモードのアクティブ化、キャッシュのクリアアクションを自動化するbashスクリプトを使用してアプリケーションをデプロイします。

このスクリプトでは、キャッシュをクリアするコマンドは次のとおりです。

heroku run --app YOUR_APP_NAME Rails runner -e production Rails.cache.clear

これは、HerokuToolbeltパッケージのCeladonCedarで機能します。これはRakeベースのソリューションではないことはわかっていますが、非常に効率的です。

注:environmentコマンドのrunner/-eオプションはproductionで実行されるため、必ずdevelopmentに設定してください。さもないと。

編集:数日後、Herokuでこのコマンドの問題が発生しました(Rails3.2.21)。 Originの問題を確認する時間がありませんでしたが、-e productionを削除することでうまくいきました。コマンドが成功しない場合は、代わりに次のコマンドを実行してください。

heroku run --app YOUR_APP_NAME Rails runner Rails.cache.clear
32
Fabrice Carrega

[セラドンシダースタックについて]

-[2012年6月18日更新-これは機能しなくなりました。別の回避策を見つけることができるかどうかを確認します]

これらのデプロイ後のフックを処理するために私が見つけた最もクリーンな方法は、slugのコンパイル中にすでに呼び出されているassets:precompileタスクをラッチすることです。アイデアのためのasset_syncGemに賛成:

Rake::Task["assets:precompile"].enhance do
  # How to invoke a task that exists elsewhere
  # Rake::Task["assets:environment"].invoke if Rake::Task.task_defined?("assets:environment")

  # Clear cache on deploy
  print "Clearing the Rails memcached cache\n"
  Rails.cache.clear
end

これをlib/tasks/heroku_deploy.rakeファイルに入れるだけで、うまくピックアップされます。

23
Hollownest

最終的に行ったのは、herokuにデプロイしてキャッシュをクリアする新しいrakeタスクを作成することでした。 deploy.rakeファイルを作成しました。これは次のとおりです。

namespace :deploy do

    task :production do
        puts "deploying to production"
        system "git Push heroku"
        puts "clearing cache"
        system "heroku console Rails.cache.clear"
        puts "done"
    end

end

ここで、git Push herokuと入力する代わりに、rake deploy:productionと入力します。

8
Solomon

2013年1月25日:これはRails 3.2.11 app running on Ruby 1.9.3 on Cedar

Gemfileに次の行を追加して、Ruby 1.9.3:

Ruby '1.9.3'

次の内容でlib/tasks/clear_cache.rakeという名前のファイルを作成します。

if Rake::Task.task_defined?("assets:precompile:nondigest")
  Rake::Task["assets:precompile:nondigest"].enhance do
    Rails.cache.clear
  end
else
  Rake::Task["assets:precompile"].enhance do
    # Rails 3.1.1 will clear out Rails.application.config if the env vars
    # Rails_GROUP and Rails_ENV are not defined. We need to reload the
    # assets environment in this case.
    # Rake::Task["assets:environment"].invoke if Rake::Task.task_defined?("assets:environment")
    Rails.cache.clear
  end
end

最後に、アプリでheroku labs:enable user-env-compileを実行して、プリコンパイルの一部としてその環境を利用できるようにすることもお勧めします。

7
Mike

'application start'で実行されるアプリケーション内で実行できることは別として、アプリケーション内のURLにヒットするherokuデプロイフック(http://devcenter.heroku.com/articles/deploy-hooks#http_post_hook)を使用できます。キャッシュをクリアします

2
John Beynon

私もこの問題を抱えていましたが、ラッパーとして追加のスクリプトを使用せずにgitデプロイメントに固執したかったのです。

したがって、私のアプローチは、スラッグの生成中に、現在のプリコンパイルをマークするuuidを使用してファイルを書き込むことです。これは、assets:precompileのフックとして実行されます。

# /lib/tasks/store_asset_cacheversion.rake
# add uuidtools to Gemfile

require "uuidtools"

def storeCacheVersion
  cacheversion = UUIDTools::UUID.random_create
  File.open(".cacheversion", "w") { |file| file.write(cacheversion) }
end

Rake::Task["assets:precompile"].enhance do
  puts "Storing git hash in file for cache invalidation (assets:precompile)\n"
  storeCacheVersion
end

Rake::Task["assets:precompile:nondigest"].enhance do
  puts "Storing git hash in file for cache invalidation (assets:precompile:nondigest)\n"
  storeCacheVersion
end

もう1つは、このIDをキャッシュされたバージョンと照合する初期化子です。それらが異なる場合は、別のプリコンパイルが行われ、キャッシュが無効になります。

したがって、スラグの生成は1回だけ行われるため、アプリケーションがスピンアップまたはスピンダウンする頻度や、ワーカーが分散されるノードの数は関係ありません。

# /config/initializers/00_asset_cache_check.rb

currenthash = File.read ".cacheversion"
cachehash   = Rails.cache.read "cacheversion"

puts "Checking cache version: #{cachehash} against slug version: #{currenthash}\n"

if currenthash != cachehash
  puts "flushing cache\n"
  Rails.cache.clear
  Rails.cache.write "cacheversion", currenthash
else
  puts "cache ok\n"
end

Gitハッシュやその他の有用なIDを取得する方法がわからないため、ランダムIDを使用する必要がありました。おそらくENV[REQUEST_ID]ですが、これもランダムIDです。

Uuidの良いところは、herokuからも独立していることです。

0
bitcloud

私が使用したい解決策は次のとおりです。

まず、アプリごとに異なる設定をしたパラメーターを探すdeploy_hookアクションを実装します。通常、これは「ホーム」または「パブリック」コントローラーで実行します。これは、それほど多くのコードを必要としないためです。

### routes.rb ###

post 'deploy_hook' => 'home#deploy'

### home_controller.rb ###

def deploy_hook
  Rails.cache.clear if params[:secret] == "a3ad3d3"
end

そして、デプロイするたびにそのアクションに投稿するデプロイフックをセットアップするようにherokuに指示するだけです!

heroku addons:add deployhooks:http \
   --url=http://example.com/deploy_hook?secret=a3ad3d3

これで、デプロイするたびに、herokuがサイトにHTTPポストバックを実行して、デプロイが正常に機能したことを通知します。

私にとっては魅力のように機能します。もちろん、シークレットトークンは「高セキュリティ」ではなく、キャッシュがクリアされた場合にサイトをダウンさせるための適切な攻撃ベクトルがあった場合は、これを使用しないでください。ただし、正直なところ、サイトが攻撃にとって非常に重要である場合は、Herokuでホストしないでください。ただし、セキュリティを少し強化したい場合は、Heroku構成変数を使用して、ソースコードに「トークン」をまったく含めないようにすることができます。

人々がこれが役に立つと思うことを願っています。

0
hcatlin

私は追加しました config/initializers/expire_cache.rb

ActionController::Base.expire_page '/'

甘い作品!

0
Uko

Heroku gemは非推奨になっているため、Solomonsの非常にエレガントな答えの更新バージョンは、次のコードをlib/tasks/heroku_deploy.rakeに保存することです。

namespace :deploy do
    task :production do
        puts "deploying to production"
        system "git Push heroku"
        puts "clearing cache"
        system "heroku run rake cache:clear"
        puts "done"
    end
end

namespace :cache do
  desc "Clears Rails cache"
  task :clear => :environment do
    Rails.cache.clear
  end
end

次に、コマンドラインでgit Push heroku masterの代わりにrake deploy:productionと入力します。キャッシュをクリアするには、rake cache:clearを実行できます。

0
wnm