ElastiCacheは良いサービス!!特徴や使い方をおさらいしましょ!
こんにちは(U・ω・U)
ElastiCacheおじさんを目指して歩みを続ける深澤です。
立派なElastiCacheおじさんに成長することを決意したラスベガスでの出来事でした。
— 深澤俊 (@shun_quartet) December 4, 2019
皆さん、ElastiCache使ってますか?使ってますね。恐らくはAWSを触っている大多数の人は導入を検討される大変魅力的なサービスだと思います。ですが、実際にElastiCacheの導入に悩まれている方も多いと思います。そんな貴方にElastiCacheの魅力と使い方をお伝えしましょう。
どんな特徴があるの?
ElastiCacheはデータをノードのメモリに保存するので非常に高速でデータの出し入れが可能です。ですがメモリにデータを保存しているのでノードが落ちてしまう(再起動を含む)と中のデータが無くなってしまいます。なのでElastiCacheには無くなっても良いデータを保存するようにしましょう。
どんなデータを保存したら良いの?
セッション情報をElastiCacheに保存してサーバがスケールしても共通のセッション情報を参照できるようにしたり、データストアに保存したデータをElastiCacheに保存してアプリケーションのキャッシュとして利用したりしましょう。
どのように使うと良いの?
そうですね、キャッシュの読み込みのタイミングや書き込みのタイミングのコツがうまく掴めないと設計の中にどうElastiCacheを盛り込んだら良いかが非常に難しいと思います。
キャッシュを確認、なければデータストアへ
キャッシュは揮発性のあるデータです。消えてしまうと大変なデータの保存は避けて、キャッシュにデータが無いならデータストア(DBなど)を参照しにいく設計が良いでしょう。あくまでデータストアのクッション的な役割で使うと良いです。
結果整合性を前提で設計する
単一ノードで建てた場合は良いのですが、プライマリからレプリカにデータをシャードしている場合、読み込み処理はレプリカで行うので書き込んだデータはすぐには反映されません。これは不便に感じるかもしれませんが健全な設計です。書き込みも読み込みも同じノードで行えばコネクションの枯渇や処理によってはCPUの使用率が上がりノードの応答が遅延する可能性もあります。障害や再起動が起きた場合にはデータも無くなってしまいます。これらを考慮すると結果整合性は前提で設計した方が良いでしょう。
TTLをセットしましょう
ElastiCacheではデータを保存しすぎてノードのメモリが溢れてしまうといった事象がよく発生します。データを高速で出し入れできて非常に便利ですが保存し過ぎには注意です。必ずデータにはTTLをセットして一定時間が経過したらデータが揮発するようにしておきましょう。このとき以下のパターンに注意して下さい。
- データのライフサイクル
- TTLが切れるデータが並列で多く存在するとCPU使用率の上昇に繋がる事があります。
- 長すぎる
- TTLが長すぎるとTTLが切れる前にメモリが溢れるといった自体になる事があります。
エンジンはMemcachedとRedisどっちにしたら良いの?
こちらについては過去にブログを書いてみたので詳しくはこちらを参照してみてください。
最近ElastiCacheのアップデート(機能追加や改善)はRedisの方が多いです。いろんな機能を利用したい場合にはRedisを選択して、単一ノードの性能を上げたい場合にはMemcachedを利用すると良いでしょう。参考までに2019年度の更新一覧をまとめたブログを書きましたのでご参照ください。
どんな構成にしたら良いの?
先ほどの「ElastiCacheはMemcachedとRedisのどっちを選ぶ?」にも書かれていますが、Memcachedは単純にノードを追加したり減らしたりして負荷を分散する構成しかとれないのであまり悩むことはないかと思います。Redisの場合はRedisクラスターモードを有効化するか無効化するかで結構悩まれるかと思います。最近はクラスターモード無効化のアップデートが多く、リーダエンドポイントやほぼダウンタイムなしの垂直スケールがサポートされたりしてクラスターモードを無効化しても問題なく運用できるようになってきました。リーダエンドポイントや垂直スケールの性能については以前僕の方で検証してみたので良かったら参考にしてください。
クラスターモード無効化のデメリットとしては、プライマリノードが一台になるので書き込み処理においてはそこが単一障害点(SPOF)になります。また扱えるデータ量もクラスターモードを有効化した方がデータがノード毎に分割して保存(パーティション)されるので、より多くのデータを保存できるようになります。
ぶっちゃけDynamoDBじゃダメなの?
分かる。分かりますよー、その気持ち。確かにElastiCacheはノードやクラスターの管理をユーザ側でしなければなりませんが、DynamoDBはその辺りの管理をしなくて良いのが便利ですよね。しかし、DynamoDBは可用性担保のために書き込まれたデータを複数のAZに保存したり、接続にはSSLを用いるのでElastiCacheに比べるとやや書き込みが遅くなります。ElastiCacheは構成もユーザが選べるので通信元(クライアント)とノードを同一AZに寄せればより通信を早くするということも可能ですね。また例えばセッション情報のような頻繁に書き/読み込みされるようなデータの場合にはリクエストの度に課金されていくDynamoDBだとElastiCacheに比べて料金が割高になる可能性があります。
ちなみにDynamoDBにも別途キャッシュ機能を提供するサービス(DAX)が存在します。
これはDynamoDBに書き込まれた値が反映されて、結果整合性のある読み込み時にのみ参照されるDynamoDBの前段に存在するキャッシュサービスです。VPC内からの利用が必須です。
こちらを使用すればDynamoDBの読み込みコストを軽減できます。書き込み処理の場合には一旦DynamoDBに書き込まれてからキャッシュに反映される仕組みなので書き込んだ値はすぐにはキャッシュに反映されません。
なのでまとめますと、
- 高速な通信がしたい、保存するデータは書き込みと読み込みが頻繁に発生するためコストが心配
- ElastiCache
- データの永続化がしたい
- DynamoDB
という使い分けが良いかと思います。DAXを検討される際にはその特徴(VPC内からしか使えない、書き込んだ値はすぐには反映されない、結果整合性のある読み込みでしか参照されない)を良く理解しアプリケーション的に問題がないことを確認してください。
オンプレから使いたい
ElastiCacheはVPC内から使う設計になっているので残念ながらVPC外からの使用はオススメできません。かつてはNATインスタンスを建ててアクセスするみたいな手法もあったのですが現在ドキュメント上から記載は消えています(管理が煩雑になるのでこちらもオススメできません)。現在、公式ドキュメントに記載があるのはVPNを用いた方法のみです。
Redis
Memcached
ElastiCacheはVPC内から使うことを前提にしましょう。
最後に
以上です、ElastiCacheが非常に重要で使いやすいサービスであることが伝わったら幸いです。
以上、深澤(@shun_quartet)でした!