サナギわさわさ.json

サナギさんとキルミーベイベーとプログラミングが好きです

Amazon ElastiCacheのchunk_sizeとEvictionではまった件

今更ですが今シーズンはヤクルトが優勝したので嬉しいです。記念に人の画像を全部畠山っぽくしてくれるフィルタを作りたいところです。

Unused MemoryがいっぱいなのにEvictions発生

本題です。この前Amazon ElastiCache(Memcached)にバッチでデータをロードしていたのですが、Unused Memoryがまた10GB近く残っているのにEvictionsが発生し始めました。

f:id:kakakazuma:20151215101956p:plain f:id:kakakazuma:20151215102046p:plain

そもそもMemcachedについての知識が無かったので色々調べてみたところ、良さげなサイトが見つかりました。

Cloud, Big Data and Mobile: Part 5: Understanding Amazon ElastiCache Internals: Memory Allocation and Eviction

ElastiCacheのメモリ挙動

詳しくは上に挙げたサイトを読んでください。簡単にまとめると、以下のようになります。

  • ElastiCacheのメモリは1MBのページングされたメモリの集合である
  • 1MBのページングされたメモリの中にはchunkが格納され、chunkのサイズは同一ページの中では全て同じになる
  • 格納可能なchunkのサイズのリストは、chunkの最小値に対して係数(growth factor)をかけていき1MBになったらストップ、という形式で用意される
  • アイテムをElastiCacheに格納する際に使われるchunkは、用意されたchunkのサイズのリストの中で格納するアイテムのサイズに最も近いchunkである
  • 格納されるchunkのサイズと、実際のアイテムのサイズの差はメモリの無駄使いとなる

MemCached界ではたぶん常識ですね、すみませんでした。

ElastiCacheの設定値

上で挙げたメモリ挙動を踏まえると重要な設定値となるのが

  • chunkの最小値
  • chunkのリストを作るときに掛ける係数(growth factor)

なわけですが、ElastiCacheではそれぞれ

  • chunk_size
  • chunk_size_growth_factor

という名前になっています。

参考: https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/UserGuide/ParameterGroups.Memcached.html

というわけで確認してみたところ、 chunk_sizeが1024バイトになっている!!! ※初期値は48バイトです

f:id:kakakazuma:20151215102306p:plain

今回投入していたデータはせいぜい100バイトぐらいなので、投入データ1件につき900バイトぐらいの無駄が発生していた事になります。恐ろしい...

解決編

というわけでchunk_sizeの設定を初期値の48バイトに修正し再度データを投入してみたところ、Evictionsは発生しなくなりました。

f:id:kakakazuma:20151215102443p:plainf:id:kakakazuma:20151215102452p:plain

さすがにここまで極端な例は無いかと思いますが、投入するアイテムのサイズが分かりきっているときはchunk_sizechunk_size_growth_factorの設定を変更すればより効率的にメモリが活用できるかもしれません。