django で Memcached の cache 設定を実施しました。
コンテンツの更新を行った後は、cache の削除、再生成を行う必要があります。

コンテンツの更新トリガで cache の削除、更新を行うのは難しいと思ったため、スケジュール実行で cahce の削除と、再生成を行うようにしました。
実施したことと、作成したスクリプトについて記載します。


cache の削除タスク

django shell 、django-extentions の clear_cache コマンドで削除可能なので、作成は不要です。

clear_cache コマンド

django-extentions clear_cache コマンドは以下のように実行します。

python2.7 manage.py clear_cache
django-extensions/clear_cache.py at master · django-extensions/django-extensions確認したところ、引数なしで実行する場合は、DEFAULT_CACHE_ALIAS指定されている cache の削除を行っています。
cache の alias を指定して削除する場合は、以下のように実行します。
python2.7 manage.py clear_cache --cache alias_name

django shell で削除する

Djangoのキャッシュをクリアする |記載がありますが、django shell で削除可能です。

$ python2.7 manage.py shell
>> from django.core.cache import cache
>> cache.clear()
この場合も、DEFAULT_CACHE_ALIAS指定されている cache が削除されます。
削除する cache alias を切り替えたい場合は、djang-extentions clear_cache使った方がいいかと思います。


cache の生成タスク

cache の削除後の初回ページ表示には、時間がかかります。
ユーザ がアクセスする前に、cache を作成するようにしたいので、自サイトのサイトマップ XML に記載された URL にアクセスするタスクと、と TOP ぺージからリンクされた URL にアクセスするタスク を作成します。

以下の Gist を参考に、2つスクリプトを作ってみました。
A couple of simple options to parse sitemap.xml to warm the cache or for other actions such as generating memory_profiler checks.

sitemap_cache_warmer.sh

sitemap に記載されている url にアクセスするスクリプトです。
'含む URL へのアクセスが上手くいかなかったので、エンコードされた ' '置換した後に、1行ずつ読み込むようにしました。
あとはもとの Gist とほぼ同じです。

#!/bin/bash
DOMAIN='www.monotalk.xyz'

# wget and curl
# sitemap base
wget -q https://$DOMAIN/sitemap.xml --no-cache -O - | egrep -o "https://$DOMAIN[^<]+" | sed "s/&#39;/'/g" | while read line;
do
  echo "-----------"
  echo "Cache Warmer access START url>>>" "$line"
  time curl -A 'Cache Warmer' -s -L "$line" > /dev/null 2>&1
  echo "Cache Warmer access END"
done

domain_root_cache_warmer.sh

ドメイン TOP ぺージからの一部リンクを抜き出して、抜き出した url にアクセスするスクリプトです。

#!/bin/bash
DOMAIN='www.monotalk.xyz'

# toppageから、category page、archivepage のcache を作成
wget -q https://$DOMAIN --no-cache -O - | egrep -o "/blog/category/[^\"]+|/blog/archive/[^\"]+" | sed "s/&#39;/'/g" | while read line;
do
  url=https://"$DOMAIN$line"
  echo "----------"
  echo "Cache Warmer access START url>>>" $url
  time curl -A 'Cache Warmer' -s -L "$url" > /dev/null 2>&1
  echo "Cache Warmer access END"
done


crontab の設定

clear_cache 5分後に、cache を再生成するスクリプトを実施するようにしました。
clear_cache 自体は一瞬で終わるので、間隔はもっと短くてもよいかと思います。

10 0-23/6 * * * $PYTHON_PATH $DJANGO_PROJECT_ROOT/manage.py clear_cache &>> $LOG_DIR/clear_cache.log # django-cronjobs for blog
15 0-23/6 * * * /bin/sh $SCRIPT_HOME/domain_root_cache_warmer.sh &>> $LOG_DIR/domain_root_cache_warmer.log && /bin/sh $SCRIPT_HOME/sitemap_cache_warmer.sh &>> $LOG_DIR/sitemap_cache_warmer.log

補足

  • 各変数について
    $PYTHON_PATH python のパス。
    $DJANGO_PROJECT_ROOT は、django の プロジェクトルートディレクトリ。
    $LOG_DIRログの出力先ディレクトリ。
    $SCRIPT_HOME スクリプトの配置先ディレクトリになります。
    環境に合わせて読み替えてください。

  • ログのリダイレクト方法について
    作成時は、&>> ではなくて、 >>リダイレクトしていて、エラーメールが飛んできていました。
    スクリプト内で、time コマンドを使用していますが、time コマンドの出力は、標準エラーに出力されるようです。
    以下、記事が参考になりました。
    timeコマンドの結果って、標準エラー出力ですよね? - Objrepos Blog

以上です。

コメント