© 2016, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Takashi Narita
Solutions Architect
Amazon Web Se...
Amazon ElastiCache
• Managed in-memory service
• Memcached or Redis
• Cluster of nodes
• Read replicas
• Monitoring + aler...
ELB Web/App
External APIs
Modern Web / Mobile App
ELB Web/App
Modern Web / Mobile App
ブラウザ
キャッシュ
データストア及びAPIレスポ
ンス、Appでの処理結果の
キャッシュ
ストレージエンジンの
キャッシュ
及びクエリキャッシュ
NginxなどWebサー...
それぞれの代表的なキャッシュデータ
• ブラウザキャッシュ
• Webサーバレスポンス(HTML、js、CSS、画像などの静的ファイル)のキャッシュ
• Webサーバキャッシュ
• アプリケーションからのレスポンスデータ
• SSLセッション
...
それぞれの代表的なキャッシュパターン
• それぞれキャッシュする内容は違うが目的は高速なレスポンスを実現す
る事と負荷を軽減させる
• キャッシュ出来る内容は要件によって異なる。即時反映させなければい
けない物はブラウザ〜Webサーバまでの場所...
今回触れるのは
ELB App
External APIs
データストア及びAPIレスポ
ンス、Appでの処理結果の
キャッシュ
ElastiCacheでキャッシュする目的
• データストアからの結果をキャッシュする事でデータストアへのアクセスを減らす
• 外部APIの結果をキャッシュする事で外部APIへのアクセスを減らす
• これらのデータを用いて計算した結果をキャッシ...
Memcached vs Redis: Cage Match
• Multithreaded
• No persistence
• Flat string cache
• Low maintenance
• Easy to scale hori...
Caching Strategies and Tactics
Setting up caching
The questions
• キャッシュ可能なのか?
• どのくらいのキャッシュ空間が必要か?
• キャッシュ障害が起きた場合の影響範囲は?
• キャッシュ戦略を成功させる為に何が必要か?
Data set properties
キャッシュ可能なデータの特性
• 読み取り専用でべき等な物
• 繰り返しアクセスされ、生存期間が長いもの
すぐに変更されてしまうものはキャッシュに向かない。
許容出来る範囲で多少古い物や一貫性の無いデータ...
Data Properties: item sizes
大きな塊としてキャッシュすべきか、細かく分けた方が良いのか
• 例として10個のデータを元にするHTMLデータ自体をキャッシュすると仮
定する
• この時最終的なデータを1つの塊としてキャ...
The Thundering Herd
キャッシュミスはデータストアへのアクセススパイクを引き起こ
す。
• 重要な事は計画と分析
一般的な原因と緩和策
• コールドキャッシュ– キャッシュに階層型キャッシュの仕組みを取り入
れる、キャッシュウ...
Data Properties: related items
アプリケーションは全く同じデータか、もしくはいくつかのデータ
を1つのグループとしてキャッシュストレージにアクセスします。
この時TTLを全ての項目で同じ値か、特定の間隔の倍数に設
...
Data liveness
どのようにキャッシュアイテムのTTLを最小限に抑えるか
• 生存期間は短ければ短いほどネガティブキャッシュにヒット
する可能性やパージする処理を記述するコストが減る
どのようにキャッシュアイテムのTTLを伸ばすか。
...
Data Consistency
ノードの追加などによるクラスタリサイズを実施するとコンシス
テントハッシングの再計算が行われ、各ノードで持っている
キャッシュ情報へのアクセスパターンが変更される。
緩和策:
• TTLの最小化:古いデータが生...
App Caching Patterns
Web Cache with Memcached
# Gemfile
gem 'dalli-elasticache’
# config/environments/production.rb
endpoint = “mycluster.abc12...
ElastiCache twemproxy config
mycache-dev:
listen: 0.0.0.0:11311
hash: fnv1a_64
distribution: ketama
timeout: 100
preconnec...
Be Lazy
# Python
def get_user(user_id):
record = cache.get(user_id)
if record is None:
# Run a DB query
record = db.query(...
Write On Through
# Python
def save_user(user_id, values):
record = db.query("update users ... where id = ?", user_id, valu...
Combo Move!
def save_user(user_id, values):
record = db.query("update users ... where id = ?", user_id, values)
cache.set(...
Storing JSON – Memcached vs Redis
# Memcached: Serialize string
str_json = Encode({“name”: “Nate Wiger”, “gender”: “M”})
S...
ElastiCache with
Not if I
destroy
it first!
It’s
mine!
Need uniqueness + ordering
Easy with Redis Sorted Sets
ZADD "leaderboard" 1201 "Goll...
Ex: Throttling requests to an API
Leverages Redis Counters
ELB
Externally
Facing
API
Reference: http://redis.io/commands/I...
• Redis counters – increment likes/dislikes
• Redis hashes – list of everyone’s ratings
• Process with algorithm like Slop...
Chat and Messaging
• PUBLISH and SUBSCRIBE Redis commands
• Use Cases:
• Chat rooms
• Server Intercommunication
Redis – Read/Write Connections
# Ruby example
redis_write = Redis.new(
'mygame-dev.z2vq55.ng.0001.usw2.cache.amazonaws.com...
Tune It Up!
Alarms
Monitoring with CloudWatch
• CPU
• Evictions
• Memory
• Swap Usage
• Network In/Out
• https://docs.aws.amazon.com/j...
Key ElastiCache CloudWatch Metrics
• CPUUtilization
• Memcached – up to 90% ok
• Redis – divide by cores (ex: 90% / 4 = 22...
Scaling Up Redis
1. Amazon S3へスナップショットを書き出す
http://bit.ly/redis-snapshot
2. Snapshotからクラスタを作成 http://bit.ly/redis-
seeding...
まとめ
1. 何をキャッシュすべきか
2. どうキャッシュすべきか
3. キャッシュしたあとどうすべきか
4. これらを気をつける事でより効果的にElastiCacheを
利用頂けます!
Thank you!
Upcoming SlideShare
Loading in …5
×

ElastiCacheを利用する上でキャッシュをどのように有効に使うべきか

81 views

Published on

2016/03/29「アプリケーション高速化のためのキャッシュ活用」の講演資料です。

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
81
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

ElastiCacheを利用する上でキャッシュをどのように有効に使うべきか

  1. 1. © 2016, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Takashi Narita Solutions Architect Amazon Web Services Japan K.K. March 29, 2016 ElastiCacheを利用する上で キャッシュをどのように 有効に使うべきか
  2. 2. Amazon ElastiCache • Managed in-memory service • Memcached or Redis • Cluster of nodes • Read replicas • Monitoring + alerts
  3. 3. ELB Web/App External APIs Modern Web / Mobile App
  4. 4. ELB Web/App Modern Web / Mobile App ブラウザ キャッシュ データストア及びAPIレスポ ンス、Appでの処理結果の キャッシュ ストレージエンジンの キャッシュ 及びクエリキャッシュ NginxなどWebサーバでの Webリクエストへのレスポン スキャッシュ
  5. 5. それぞれの代表的なキャッシュデータ • ブラウザキャッシュ • Webサーバレスポンス(HTML、js、CSS、画像などの静的ファイル)のキャッシュ • Webサーバキャッシュ • アプリケーションからのレスポンスデータ • SSLセッション • 静的ファイルデータ • キャッシュストレージ • データストアやAPIの結果 • それらを処理した結果 • セッションデータ • データストアキャッシュ • ストレージエンジンが処理で利用するキャッシュ • クエリの結果
  6. 6. それぞれの代表的なキャッシュパターン • それぞれキャッシュする内容は違うが目的は高速なレスポンスを実現す る事と負荷を軽減させる • キャッシュ出来る内容は要件によって異なる。即時反映させなければい けない物はブラウザ〜Webサーバまでの場所でキャッシュは難しい • 大人数が共通して利用出来るjs、CSS、画像ファイルはCloud Frontを利 用した方が良い • キャッシュはあくまでもキャッシュなので、キャッシュが参照出来なくなっ ても実際のデータは必ず改めて参照出来るようにする事
  7. 7. 今回触れるのは ELB App External APIs データストア及びAPIレスポ ンス、Appでの処理結果の キャッシュ
  8. 8. ElastiCacheでキャッシュする目的 • データストアからの結果をキャッシュする事でデータストアへのアクセスを減らす • 外部APIの結果をキャッシュする事で外部APIへのアクセスを減らす • これらのデータを用いて計算した結果をキャッシュする事で同じ処理を減らす • アプリケーション内部でこれらのキャッシュを保持する機構を分離する • アプリケーション単体で保持出来ない容量のキャッシュを保持する • アプリケーション単体のダウンに影響されないようにする • アプリケーションが生成したキャッシュをアプリケーションクラスタ全体で利用可能 にする
  9. 9. Memcached vs Redis: Cage Match • Multithreaded • No persistence • Flat string cache • Low maintenance • Easy to scale horizontally • Single-threaded • Persistence • Advanced data types - http://redis.io/topics/data-types • Atomic operations • Pub/sub messaging • Read replicas / failover
  10. 10. Caching Strategies and Tactics
  11. 11. Setting up caching The questions • キャッシュ可能なのか? • どのくらいのキャッシュ空間が必要か? • キャッシュ障害が起きた場合の影響範囲は? • キャッシュ戦略を成功させる為に何が必要か?
  12. 12. Data set properties キャッシュ可能なデータの特性 • 読み取り専用でべき等な物 • 繰り返しアクセスされ、生存期間が長いもの すぐに変更されてしまうものはキャッシュに向かない。 許容出来る範囲で多少古い物や一貫性の無いデータを返して も良い物がキャッシュに向いている
  13. 13. Data Properties: item sizes 大きな塊としてキャッシュすべきか、細かく分けた方が良いのか • 例として10個のデータを元にするHTMLデータ自体をキャッシュすると仮 定する • この時最終的なデータを1つの塊としてキャッシュするとヒットする時は1 回のリクエストで良いが、少しでも変更があれば毎回updateをする必要 が出る。 • また、他のHTMLと共通化出来るもの(フッター情報など)をそれぞれ重 複してキャッシュする事になる • 個別に分けると可能な限り無駄は減るがキャッシュストレージへのアクセ スは増加する。 • これはどちらの負荷がよりコントロールしやすいかで最終的に判断、調 整する必要がある。
  14. 14. The Thundering Herd キャッシュミスはデータストアへのアクセススパイクを引き起こ す。 • 重要な事は計画と分析 一般的な原因と緩和策 • コールドキャッシュ– キャッシュに階層型キャッシュの仕組みを取り入 れる、キャッシュウォーミングのシーケンスを導入します。 • 同じタイミングでのTTL切れ– ランダムジッタをTTLに設定します。 • Undersized cache – ヒットレート、データセットの解析 • アクセスパターンの変更– 分析, 計画, テスト • より高いヒットレートへの対応 – 冗長性 , スケーリングの向上
  15. 15. Data Properties: related items アプリケーションは全く同じデータか、もしくはいくつかのデータ を1つのグループとしてキャッシュストレージにアクセスします。 この時TTLを全ての項目で同じ値か、特定の間隔の倍数に設 定すると最悪の場合、全て同一のタイミングでキャッシュミスが 発生する可能性があります。 これを避ける為にTTLをセットする場合はランダムな値で調整 する事でTTL切れによるキャッシュミスを平滑化します。
  16. 16. Data liveness どのようにキャッシュアイテムのTTLを最小限に抑えるか • 生存期間は短ければ短いほどネガティブキャッシュにヒット する可能性やパージする処理を記述するコストが減る どのようにキャッシュアイテムのTTLを伸ばすか。 • 生存期間が長いほどキャッシュヒットする事によるデータスト アへのアクセスなどは減少出来る
  17. 17. Data Consistency ノードの追加などによるクラスタリサイズを実施するとコンシス テントハッシングの再計算が行われ、各ノードで持っている キャッシュ情報へのアクセスパターンが変更される。 緩和策: • TTLの最小化:古いデータが生存する可能性を減少させる。 • 確認されたアップデート手法 • 固定されたコンシステントハッシングパターンを取る
  18. 18. App Caching Patterns
  19. 19. Web Cache with Memcached # Gemfile gem 'dalli-elasticache’ # config/environments/production.rb endpoint = “mycluster.abc123.cfg.use1.cache.amazonaws.com:11211” elasticache = Dalli::ElastiCache.new(endpoint) config.cache_store = :dalli_store, elasticache.servers, expires_in: 1.day, compress: true # if you change ElastiCache cluster nodes elasticache.refresh.client Ruby on Rails Example
  20. 20. ElastiCache twemproxy config mycache-dev: listen: 0.0.0.0:11311 hash: fnv1a_64 distribution: ketama timeout: 100 preconnect: true auto_eject_hosts: true server_retry_timeout: 2000 server_failure_limit: 3 servers: - mycache-dev.0001.use1.cache.amazonaws.com:11211:1 - mycache-dev.0002.use1.cache.amazonaws.com:11211:1 - mycache-dev.0003.use1.cache.amazonaws.com:11211:1 - mycache-dev.0004.use1.cache.amazonaws.com:11211:1
  21. 21. Be Lazy # Python def get_user(user_id): record = cache.get(user_id) if record is None: # Run a DB query record = db.query("select * from users where id = ?", user_id) cache.set(user_id, record) return record # App code user = get_user(17)
  22. 22. Write On Through # Python def save_user(user_id, values): record = db.query("update users ... where id = ?", user_id, values) cache.set(user_id, record) return record # App code user = save_user(17, {"name": "Nate Dogg"})
  23. 23. Combo Move! def save_user(user_id, values): record = db.query("update users ... where id = ?", user_id, values) cache.set(user_id, record, 300) # TTL return record def get_user(user_id): record = cache.get(user_id) if record is None: record = db.query("select * from users where id = ?", user_id) cache.set(user_id, record, 300) # TTL return record # App code save_user(17, {"name": "Nate Diddy"}) user = get_user(17)
  24. 24. Storing JSON – Memcached vs Redis # Memcached: Serialize string str_json = Encode({“name”: “Nate Wiger”, “gender”: “M”}) SET user:nateware str_json GET user:nateware json = Decode(str_json) # Redis: Use a hash! HMSET user:nateware name “Nate Wiger” gender M HGET user:nateware name >> Nate Wiger HMGET user:nateware name gender >> Nate Wiger >> M
  25. 25. ElastiCache with
  26. 26. Not if I destroy it first! It’s mine! Need uniqueness + ordering Easy with Redis Sorted Sets ZADD "leaderboard" 1201 "Gollum” ZADD "leaderboard" 963 "Sauron" ZADD "leaderboard" 1092 "Bilbo" ZADD "leaderboard" 1383 "Frodo” ZREVRANGE "leaderboard" 0 -1 1) "Frodo" 2) "Gollum" 3) "Bilbo" 4) "Sauron” ZREVRANK "leaderboard" "Sauron" (integer) 3 Real-time Leaderboard!
  27. 27. Ex: Throttling requests to an API Leverages Redis Counters ELB Externally Facing API Reference: http://redis.io/commands/INCR FUNCTION LIMIT_API_CALL(APIaccesskey) limit = HGET(APIaccesskey, “limit”) time = CURRENT_UNIX_TIME() keyname = APIaccesskey + ":” + time count = GET(keyname) IF current != NULL && count > limit THEN ERROR ”API request limit exceeded" ELSE MULTI INCR(keyname) EXPIRE(keyname,10) EXEC PERFORM_API_CALL() END Rate Limiting
  28. 28. • Redis counters – increment likes/dislikes • Redis hashes – list of everyone’s ratings • Process with algorithm like Slope One or Jaccardian similarity • Ruby example - https://github.com/davidcelis/recommendable Recommendation Engines INCR item:38927:likes HSET item:38927:ratings "Susan" 1 INCR item:38927:dislikes HSET item:38927:ratings "Tommy" -1
  29. 29. Chat and Messaging • PUBLISH and SUBSCRIBE Redis commands • Use Cases: • Chat rooms • Server Intercommunication
  30. 30. Redis – Read/Write Connections # Ruby example redis_write = Redis.new( 'mygame-dev.z2vq55.ng.0001.usw2.cache.amazonaws.com') redis_read = Redis::Distributed.new([ 'mygame-dev-002.z2vq55.ng.0001.usw2.cache.amazonaws.com', 'mygame-dev-003.z2vq55.ng.0001.usw2.cache.amazonaws.com' ]) redis_write.zset("leaderboard", "nateware", 1976) top_10 = redis_read.zrevrange("leaderboard", 0, 10)
  31. 31. Tune It Up!
  32. 32. Alarms Monitoring with CloudWatch • CPU • Evictions • Memory • Swap Usage • Network In/Out • https://docs.aws.amazon.com/ja_jp/AmazonEl astiCache/latest/UserGuide/CacheMetrics.Whi chShouldIMonitor.html
  33. 33. Key ElastiCache CloudWatch Metrics • CPUUtilization • Memcached – up to 90% ok • Redis – divide by cores (ex: 90% / 4 = 22.5%) • SwapUsage low • Evictions low • CacheMisses / CacheHits Ratio low • CurrConnections stable • Whitepaper: http://bit.ly/elasticache-whitepaper
  34. 34. Scaling Up Redis 1. Amazon S3へスナップショットを書き出す http://bit.ly/redis-snapshot 2. Snapshotからクラスタを作成 http://bit.ly/redis- seeding 3. クラスタ作成完了 4. 必要な分のデータコピーを実行する 5. ※クラスタ自体のスケールアップ、エンジンアップグ レードには対応
  35. 35. まとめ 1. 何をキャッシュすべきか 2. どうキャッシュすべきか 3. キャッシュしたあとどうすべきか 4. これらを気をつける事でより効果的にElastiCacheを 利用頂けます!
  36. 36. Thank you!

×