Memcached使ってみたかった。なんかキャッシュしなきゃならんので
ブラウザ <---> Heroku <---(cache)---> Twitter
なものを作った。

できたもの http://twiticon.herokuapp.com/

twitterのユーザーアイコンをHTMLに簡単に貼れるやつ。ソースコードはここ

こういうHTMLでアイコンがでる。
<img src="http://twiticon.herokuapp.com/shokai">


小さいのや大きいのも貼れる。

テキストや http://twiticon.herokuapp.com/shokai.txt
JSONでも取得できる http://twiticon.herokuapp.com/shokai.json


使い方は http://twiticon.herokuapp.com に詳しく書いてある。


Twitterのアイコン

ここにAPIがある
GET users/profile_image/:screen_name | Twitter Developers
ユーザーが新しいアイコンをアップロードする毎にURLが変わる。
例えば今の俺のアイコンは https://si0.twimg.com/profile_images/2328443341/tmp_normal.png になってる。


Memcached

ふつうのSQL DBみたいにHDDにデータは保存しないけど、メモリ上で高速に動作する。
あとExpireする期限を決めれる。今回は保存したアイコンURLは12時間で消滅するようにした。
12時間1秒経過すると、再度Twitter APIを使ってURLを取りに行く。


Herokuでmemcached使う

Memcache | Heroku Dev Centerにドキュメントがある。
Herokuのmemcachedはユーザー名とパスワードによる認証があって、SASLというプロトコルを使っているので対応しているgemじゃないと使えない。
dalliというpure rubyのgemが推奨されている。

いつも使ってるCで書かれてるmemcached gemはSASLサポートしてるって記述があるんだけど、使い方がドキュメントに書いてないし面倒臭くなってdalliに落ち着いた。


Herokuにmemcached addon追加した。無料だけどクレジットカード番号登録しないと使わせてもらえない。
% heroku create --stack cedar
% heroku addons:add memcache:5mb


パスワードとかは
% heroku config
で見れる。
MEMCACHE_PASSWORD, MEMCACHE_SERVERS, MEMCACHE_USERNAMEがそれ。
これがHerokuで動かしてるアプリの環境変数に入るので、ENV[‘MEMCACHE_SERVERS’]とかで取り出す。


dalliでMemcached使う

認証なし
require 'rubygems'
require 'dalli'
cache = Dalli::Client.new 'localhost:11211'

Heroku用
cache = Dalli::Client.new ENV['MEMCACHE_SERVERS'], {:username => ENV['MEMCACHE_USERNAME'], :password => ENV['MEMCACHE_PASSWORD']}


で、あとはcacheにset/getすればよい。
# cache 1 hour
cache.set('icon_shokai', 'https://si0.twimg.com/profile_images/2328443341/tmp_normal.png', 3600)

# get icon
puts cache.get('icon_shokai')


ちなみにHerokuのmemcachedは自分のローカル環境からも接続できる。
addons:add memcachedしたらすぐに起動するので、手元で開発してるプログラムで
cache = Dalli::Client.new 'xxxxx.ec2.northscale.net', {:username => '123456heroku.com', :password => 'asdf122345hujiko'}
とか書いても動かせる。太平洋横断してるから遅いけど。


ローカル開発環境にMemcachedをインストール

homebrewやapt-getでインストールできる。
% brew install memcached
% memcached -vv -p 11211
これでlocalhost:11211で起動する。


SinatraでMemcachedを使う

ふつうに上に書いたのを組み合わせてredirectするだけなのでgithub見ればわかると思う。
https://github.com/shokai/twiticon


controllerでは
redirect icon user, size
とだけ書いて、iconって関数は適当にキャッシュもしてくれるように書かれている


あと開発時はローカルのlocalhost:11211のmemcachedを見て欲しいので、環境変数が無かったらconfig.ymlから同じ値を探すようにしたらはかどった。


感想

memcache無料の5MBぐらいだと、tmp_cache gem使ったほうが設定もいらないし楽なのでは・・・