Auto ScalingではなくてAuto Cachingという考え方

今年の3月くらいからずっと悶々としていて、なかなか手が出せなかったアイデアがやっと実現できました。

(試行錯誤して書いてみたら、結果たった数行という。。。)

Auto ScalingではなくてAuto Cachingという考え方

AWSではAuto Scalingという、サーバの負荷の変化などによってEC2インスタンスをスケールする便利な機能があります。

が、大抵はクラウド環境でないと容易には実現できません。

例えば、クラウドではなく

  • サーバリソースは増やせない。
  • 普段はキャッシュはしてほしくないコンテンツ。
  • ただ、アクセスが多くなるとかで何かしら負荷が高くなった時には「仕方なく」キャッシュを使っても良い。落ちるよりはマシ。
  • 負荷が戻ったらキャッシュを使わないようにして欲しい。

という状況もあるかもしれません(そしてあります)。

「状況によってWebサーバがいい感じにキャッシュコントロールしてくれないかな」と考えていました。

Auto ScalingならぬAuto Cachingみたいな。

その時のメモがこちら

  • ngx_mruby( + http-dos-detector + mruby-changefinder)とかを駆使して、高負荷を検知したらキャッシュを利用するように変更するとか?
  • mod_mrubyとmod_cacheでもいけるのか?
  • というか、もともとそういう設定できないの?できるんでしょ?

(改めて検索してみたら、はるか以前に同じようなことを実現されていた方が。しかもkazuhoさんという。。)

Fukuoka.rb活動

いろいろ考えてはいたものの、別のOSS活動をしていました。

で、やっと先日のFukuoka.rbで重い腰を上げて試してみました。

なんとかmod_mrubyのインストールまでできたので、そのあとはずっとmod_cacheとmod_mrubyのドキュメントやエントリーを読んで、試行錯誤していました。

Auto Caching

こちらが成果です。

# -*- coding: utf-8 -*-
# LoadModule cache_module modules/mod_cache.so
# LoadModule cache_disk_module modules/mod_cache_disk.so
# LoadModule mruby_module modules/mod_mruby.so
#
# CacheRoot /var/www/cache
# CacheEnable disk /cache-control
# CacheIgnoreCacheControl Off
# CacheIgnoreNoLastMod On
# CacheIgnoreHeaders Set-Cookie
# CacheDefaultExpire 300
# CacheMaxExpire 600
#
# <Location /cache-control>
#   mrubyQuickHandlerFirst /path/to/autocache.rb
# </Location>

r = Apache::Request.new()

r.headers_in['Cache-Control'] = 'no-cache'

wc = Apache::Scoreboard.new()

if wc.loadavg.first > 1
  # cache
  r.headers_in['Cache-Control'] = 'public'
end

Apache.return(Apache::DECLINED)

mod_cache、mod_disk_cacheを併用して使います。

サーバのLoad Averageが1以上になったときにだけ、mod_cacheを利用してコンテンツをキャッシュします。そして、Load Averageが1以下に落ち着いたらキャッシュが解除されます。

若干強引ですが Cache-Control ヘッダをいじってmod_cacheを反応させることで実現しています。

今更ながら mod_mruby / ngx_mruby すごい

たった数行でこんなことができるとは。。。

if wc.loadavg.first > 1 の部分を頑張れば、より柔軟にキャッシュコントロールできそうです。

ギョームではLAMP環境を構築することが多いです。

mod_mrubyというプログラマにやさしいモジュールは、今後インフラを考えるときに選択肢を増やす強力な武器になりそうです。

やさしいツール

AWSもInfrastructure as codeもmod_mruby / ngx_mrubyもプログラマにやさしいです。

やさしさ重要だなーと思う日々です。

今後

Auto Cachingの実戦投入をしてみたい。