[ElastiCache] memcachedのflush_allの挙動について

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

佐々木です。最近はもっぱら英語の勉強をしています。中学英語から復習中なのですが、時々長女(中学校三年生)に間違いを指摘されます。お父さん形無し。

本記事はmemcachedを使っていて気づいたことの小ネタです。

flush_allの挙動

ElastiCacheをmemcachedエンジンで構築し、telnetで接続します。

$ telnet memcached.foobar.cfg.apne1.cache.amazonaws.com 11211

statsを確認します。構築したばかりの段階だと、(当然ですが)データはゼロです。

stats
...snip...
STAT curr_items 0
...snip...
END

データを3つsetしてみました。

set 1 0 0 6
sasaki
STORED

set 2 0 0 4
kaji
STORED

set 3 0 0 8
ishikawa
STORED

この状態でstatsを確認すると、データが3つ登録されたことが分かります。

stats
...snip...
STAT curr_items 3
...snip...
END

ここで、全てのデータを無効(Invalidate)にするflush_allを実行します。

flush_all
OK

この状態でstatsを確認すると...あれ、データ数は3つのままです。

stats
...snip...
STAT curr_items 3
...snip...
END

しかし、getしてもデータは取れません。

get 1
END

getした後にstatsを確認すると...データ数が減ってますね。2になっています。

stats
...snip...
STAT curr_items 2
...snip...
END

理由

memcachedのWebサイトNewProgrammingFAQページに、その理由が記載されていました。以下引用。

[Why Isn't curr_items Decreasing When Items Expire?]

Expiration in memcached is lazy. In general, an item cannot be known to be expired until something looks at it.

Think of it this way: You can add billions of items to memcached that all expire at the exact same second, but no additional work is performed during that second by memcached itself. Only as you attempt to retrieve (or update) those items will memcached ever notice that they shouldn't be there. At this point, curr_items will be decremented by each item it has seen expired.

We may also notice expired items while searching for memory for new items, though this isn't likely to create an observable difference in curr_items because we'll be replacing it with a new item anyway.

つまり、

  • (1)memcachedはデータの有効期限を監視してしない。
  • (2)データを取得/更新する時にだけ有効期限を確認し、有効期限切れであればcurr_itemsを減らす。
  • (3)flush_allのInvalidateは有効期限切れにするだけ。
  • (4)なので、flush_allしてもcurr_itemsは変わらない。getして初めてcurr_itemsが減った。

ということですね。

さいごに

memcachedを使い込んでいると当たり前の仕様なのでしょうが、初めて知ったのでメモとしてブログ記事にしてみました。