1. 八百万のOSS
  2. #13 memcachedはシンプルなま..
#13 memcachedはシンプルなまま —— Netflix EVCacheの「賢いクライアント」設計
2026-07-29 44:28

#13 memcachedはシンプルなまま —— Netflix EVCacheの「賢いクライアント」設計

memcachedはシンプルで高速です。一方で、複数の場所にデータを複製したり、障害が起きたときの読み書きを切り替えたりするところまでは面倒を見ません。では、大規模なサービスでは、たくさんのmemcached serverをどう扱えばよいのでしょうか。今回はNetflixが公開しているOSS「EVCache」を読みながら考えます。


EVCacheはmemcached serverそのものを複雑にするのではなく、アプリケーション側のsmart clientが状況を判断します。writeは複数のAvailability ZoneにあるServerGroupへ送り、readは近くのServerGroupを優先。近くのcacheに問題があれば、別のzoneへ切り替えます。すべてのwriteが終わるまで必ず待つのではなく、一部の失敗や古い値を許容するのも、消えても作り直せるcacheならではの割り切りです。


serverを増減したとき、保存先の変化をどう小さくするのか。アクセスが一つのkeyに集中したらどうするのか。空のcache clusterをいきなりread対象にすると何が起きるのか。こうしたcacheの一般的な問題から出発し、consistent hashing、client-side in-memory cache、先にwriteだけを流して温めるwrite-only ServerGroupといったEVCacheの実装につなげていきます。


EVCacheのコードを手がかりに、Netflixが大規模なcacheをどう支えているのかを読み解きます。cacheをserverだけでなく、client、deploy、障害時の切り替え、監視まで含めて考える視点を学ぶ回です。


- Netflix EVCache: https://github.com/Netflix/EVCache

- memcached: https://memcached.org/

- pecl memcached: https://pecl.php.net/package/memcached

- 達人が教えるWebパフォーマンスチューニング(ISUCON本): https://gihyo.jp/book/2022/978-4-297-12846-3


─────────────

YouTube: https://youtu.be/8_zwaJgqN5Y

Web: https://yaoyorozu-oss.henteko07.com/

X: https://x.com/yaoyorozu_oss

感想

まだ感想はありません。最初の1件を書きましょう!

サマリー

このエピソードでは、Netflixが開発したOSSであるEVCacheについて、その設計思想と機能が詳細に解説されています。EVCacheは、単なるMemcachedクライアントではなく、大規模サービスにおけるキャッシュの課題を解決するために、アプリケーション側に高度なロジックを組み込んだ「スマートクライアント」です。 EVCacheの主な特徴として、複数のアベイラビリティゾーン(AZ)への書き込み、近くのキャッシュを優先する読み込み、障害時の自動切り替え、一部の書き込み失敗や古い値の許容などが挙げられます。これにより、オリジンサーバーへの負荷軽減、障害耐性の向上、パフォーマンスの最適化を実現しています。また、ホットキー問題への対策としてクライアントサイドのインメモリキャッシュを導入し、Memcachedとの二層構造を構築しています。 さらに、コンシステントハッシングによるサーバーへの効率的なデータ分散、デプロイや障害時の挙動、監視機能まで考慮された設計は、Netflixのインフラ運用ノウハウが詰まったものと言えます。EVCacheは、その複雑さゆえに導入のハードルは高いものの、大規模サービスにおけるキャッシュ運用の参考となる多くの知見を提供しています。

NetflixとEVCacheの紹介
Netflixって、使ってるデータがそもそも巨大だし、 かなりのトラフィックをさばいている世界的企業っていうようなイメージがあってですね。
技術的にもいろんなことを内部でしてそうだなって勝手に思ってるんですけど、 このNetflixでOSS的な話題ってあったりしますかね?
それが結構いい質問で。以前ここでもMemcachedの話したじゃないですか。 実はNetflixってMemcachedを使ってることで有名なんですよね。
だからMemcached使ってあの大量のトラフィックをさばいているっていう感じで、 ただNetflix規模だとMemcached使えば早いみたいな、そういう単純な話でもなくて、
すっごい工夫してるんですよ。 その工夫が我々見れるかっていうと、実はGitHubでEVcacheっていう、そのNetflixEVcacheですね。
っていうライブラリーがあって、これがNetflixが使っているMemcachedクライアントになるんですよ。 これ我々でもGitHubにあるんで読むことができます。
なのでEVcache実はすごいやってること多くて、ちょっと話し切れるかわかんないんですけど、 ちょっとできる限り何やってるか話していきたいかなと思ってます。
はい、お願いします。 じゃあ今日はEVcacheの話をしていけたらなと思うんですけど、
そもそも今話聞いてて思ったのが、Memcachedのクライアントなんですかね。
Memcachedをそもそも使ってて、その上でEVcacheっていうのをクライアント側で使ってるっていう形なんですかね。
そうですね。NetflixはJava使ってるみたいで、 EVcacheはJavaで書かれているMemcachedクライアントになるんですけど、
ただEVcacheの中でMemcachedクライアントライブラリーをさらに呼び出していて、
EVcacheは単純なMemcachedクライアントライブラリーっていう感じでは実はなくて、
そのすごいNetflixでMemcachedを使うならこうするぞみたいなのが詰まってるライブラリーって感じなんですよね。
ただのラッパーじゃないってことですよね。
そうですね。ラッパーというにはちょっとやってることがかなり多いかなと思います。
EVCacheが解決するMemcachedの課題
具体的にどういうこと、一番特徴的にやってることって言ったら何になるんですかね。
本当にいろいろあるんで一個一個言わないといけないんですけど、
本当に今回スマートクライアントって呼べばいいのかなと思っていて、
本当に単なるMemcachedクライアントじゃなくて、すごい頭のいいMemcachedクライアントだと思って、
今回ちょっと話を聞いてもらえればなと思ってるんですけど、
まず普通にMemcached使うとしたらみんなどうやって使うかっていうのをちょっと思い出していくと、
まず例えばアプリケーションがキャッシュを見て、キャッシュなかったらデータベースとかライブのAPI叩いたりとかして、
それをTTL付きでMemcachedに保存して、で次回以降はキャッシュヒットするよねみたいな使い方するじゃないですか。
普通に使うとしたらそうですよね。
それでいいじゃんって思いがちなんですけど、やっぱりNetflixぐらいの大規模になってくるとこれだと足りないんですよね。
他にもあるということなんですね。
他にもっていうか、まず今言った単純な仕組みだと、まずキャッシュミスした時にオリジンに負荷が入っちゃうんですよね。
例えばそのキャッシュミスが一気に大量に発生しちゃったら一気にオリジンに負荷がかかっちゃうんですよね。
これってサンダリングハードプロブレムとか名前がついてるんですけど、そういう問題が結構容易に発生してしまったりとか、
あとMemcachedってNetflix規模だとMemcachedってノードとしてたくさん起動してるんですけど、
このノードが障害になってしまうとそのMemcachedがないので大量にミスをしてしまう。
そうなるといろいろ起こってしまったりとかもするし、
あとそのMemcachedのノードでこの後もちょっと話すんですけど、
例えば特定のキーだったらこのサーバーに行くみたいな設定を例えばするじゃないですか、
そういう設定した時に特定のキーがすごい参照されるキーっていうのがあって、
そうなるとその特定のMemcachedノードに集中してしまう。
そうするとそのMemcachedだけすごい負荷が上がっちゃってなんか障害になるとか、そういうのも起こりうる。
あとこれってあの分散システムとかで一般によく起こるんですけど、
キャッシュがたまに遅いサーバーがあったりとかすると、
その99%タイルとか取るとなんかそんなに遅くなさそうに見えるんだけど、
実はすっごい遅いことがたまにあるみたいなことが起こりうるんですよね。
やっぱりサーバーすっごいたくさんあると運が悪いとめちゃくちゃ遅いとかってあるんですよ。
そういうのをやっぱりその分散システムとかサーバーが大量にあるシステムだと、
こういうことって考えないといけないんですよね。
すごくまるにすっごい遅いっていうケース。
そういうのがNetflix規模だといろいろ考えないといけないっていうのがあります。
とにかくNetflix規模のトラフィックがあると、そういう細かいところも致命的になる。
そうですね。ちょっとでもキャッシュがミスしちゃったら一気に負荷が上がっちゃって死んじゃうとかそういうことがあり得るんですね。
しかもキャッシュミスしたらオリジンに負荷いくのは当然だろうと思いがちなんですけど、
それさえも障害になり得るということなんですね。
それが致命傷になり得るっていうところですよね。やっぱり同時にリクエストが大量に来てるっていうのもあるので。
確かに。先にちょっとホットキャッシュっていうか、キャッシュを温めとかないといけないということも考慮しないといけないっていうような規模なんですね。
実はちょっとその辺も後で話すんですけど、いろいろ考えることがあります。
PHP版MemcachedClient (PECL Memcached) の効率化
なるほど。じゃあちょっとどこから見ていけるのか。
ここでちょっと触れとくと、ゲヒョウさんからイスコンボンって呼ばれてる本があって、実は自分それ著者の一人でイスコンボンのキャッシュ書を書いたの自分なんですよ。
そのキャッシュの書にその基本的なことでキャッシュで気をつけないといけないこととかいろいろ書いてあるんですけど、
実は今回のEVキャッシュはそのイスコンボンに書いてあるような内容が実際に実装されていたりするので、
基礎的なことを知りたい場合はちょっと手前ミソになってしまうんですけど、
イスコンボンのキャッシュ書を見てもらいつつ、実際にそれを受けてネットフリックスだとどうなってんのってところまで興味のある人に届けられるような内容にしたいなと思っております。ちょっと宣伝でした。
いいですね。ありがとうございます。イスコンボンって調べたら何か出てきますかね。
皆さんちょっと調べて読んでみてください。
で、どこから見ていきましょうかね。
なんかその前に、EVキャッシュの前に他の、例えばPHPでMemcachedClientを作ってあるんですけど、そのpeclでMemcachedというライブラリーがあるんですけど、
これが実はちょっと面白いことをやっていて、ちょっと関係するのでEVキャッシュとも。
ちょっとここも話したいなと思っていて、
まずそのPHPってアーキテクチャとして、一回リクエスト来たら、レスポンス返したらそのプロセスは死んじゃうんですよね基本的に。
PHPって毎回プロセス起動しては捨ててるみたいな感じになるんですよ。
なのでこれってすごく効率が悪くて、例えばそのリクエストが来たタイミングでMemcachedに通信しました。
で、レスポンス返した後にMemcachedとのコネクションが切れちゃいます。
っていう風にPHPだとなっちゃうんですね普通にやると。
コネクションを毎回繋ぎ直さないといけないんですよね。
やっぱりそのTCPのコネクション作るのって時間ちょっとかかるじゃないですか。
なのでMemcachedでせっかく早いのにTCPのコネクション作るのにコストがかかっちゃうんですね。
そこでオーバーヘッドがかかってしまうと。
かかってしまうんですよ。
そこでPHPのMemcached、FeclMemcachedは、
FeclってC言語で一部書けるので、
そのPHPのアーキテクチャを飛び越えてそのC言語側でパーシステントコネクションを作っちゃう。
実はMemcachedのコネクションをC言語の領域で作っちゃう。
それである程度そのコネクションを保持しておいて、
PHP側はTCPのコネクションをいちいち作らなくてもMemcachedのコネクションが使えるようにっていう風になってるんですね。
実はFeclMemcachedって。
コネクションプール的なものが別で存在していて、そこに対してリクエストする形になってですね。
そういう作りになっています。
FeclMemcachedはそのPHPのアーキテクチャを飛び越えるためにこういう作りになってるんですけど、
これはFeclMemcachedってそのPHPでMemcachedを効率よく使うクライアントになるんですよね。
EVCacheはなんかもっともっといろんなことをやっていて、
EVCacheのスマートクライアントとしての設計思想
ざっくり言うとそのマルチAZ、アベラビリティゾーンがたくさんあるんですよね。
Torixで当然。
そのマルチAZにも大量してるし、Memcachedのノードが大量にあるっていうケースもあるし、
あとなんかエラーが起こった時のフォールバックとかもEVCache自前でやってるし、
あとEVCache自体にも監視でモニタリングで使えるようなものも返してたりとか、
本当にいろんなことをやっています。
なるほど、クライアント側でできることは全てやるみたいなことをやっているとEVCacheでは。
じゃあなんでEVCacheそんなスマートクライアントやってんのっていうのもあって、
プロクシーサーバーみたいなのを用意すればいいじゃんって多分思うと思うんですよね、多くの人は。
で、これさっきのPHPの話にもつながるんですけど、
実際PHPでそういう考えでやることももちろんできるんですけど、
じゃあなんでMemcachedみたいなことをやるかっていうと、
例えばそのローカルにMemcachedのプロクシーサーバーみたいなのを建てるとするじゃないですか。
で、そのローカルで建っているそのプロセスに対してPHPがすごい量コネクションを作るんですよね。
やっぱりこれってローカルとはいえコネクション作るコストもあるし、
何よりこのプロクシーサーバーが障害になったりとかすると全部落ちちゃうんですよ。
そうなんでやっぱりそういうレイヤー1個挟んじゃうと、
その対障害率っていう観点だとやっぱり増えちゃうんですよね、その障害になる要素っていうのが。
壊れる部品がちょっと多くなってしまうってことですよね。
そうです。それにやっぱりそのTCPのコネクションも、
1回そのプロクシーサーバーにTCPコネクションを張って、
その後プロクシーサーバーがもう1回TCPで通信、Memcachedに通信するって形になっちゃうので、
やっぱりTCP的にも無駄が多いんですね。
なのでそのAVキャッシュの肝なんですけど、プロクシーサーバーじゃなくて、
そのアプリケーションサーバーに組み込む、ライブラリとして組み込んで、
そのMemcachedのコネクションもそのアプリケーション内でちゃんと扱うし、
本当にそういうスマートな処理をたくさんやることで、
パフォーマンスも上げるし、対障害率っていう観点でも上げるし、
あとシステム全体のシステム全体のシステムをシンプルにするようなことをやるために、
わざとEVキャッシュでアプリケーション側にちょっと複雑なロジックを組み込むっていう形になってます。
なるほど、あえて分離した設計をするんじゃなくて、
アプリケーション側で全てコントロール可能なようにしてるということなんですね。
なるほど、ちょっと考え方が若干違うってことなんですね。
そうですね、プロクシーでそっちに丸投げするってやり方もあるんですけど、
それだと逆に複雑になっちゃうし、あと対障害率って観点でも不利。
だからあえてアプリケーション側で難しいことをたくさんやるっていう構成になってます。
かなり思想が現れてますね、こうするんだっていう。
思想っていうか、多分実際こうしないと辛いんだと思うんですよ、シンプルに。
そのプロクシーサーバーみたいなのを用意しちゃうと、そのプロクシー側が高負荷になっちゃうし、
インフラの管理コストが跳ね上がっちゃうんだと思うんですよ。
この構成だと多分すごい安定させやすいと思います、実際。
アプリケーションサーバーが頑張ればいいという。
アプリケーションが頑張ってるだけだから、インフラはシンプルになる。
なるほど。
本当にEVキャッシュはたくさんの機能があるので、ちょっと一個一個話していきたいですね。
まずは。
EVCacheの書き込み・読み込み戦略
まずは、アベラリティゾーンごとにメミキャッシュが立ってるんですけど、
それがメミキャッシュ1台とかじゃなくてたくさん立ってます。
それがアベラリティゾーンごとにあると。
例えばアプリケーションはそのEVキャッシュ経由で、
例えばゲットする、セットから反したほうがいいか。
まずセットするじゃない、セットするっていうのを呼び出した場合、
複数のアベラリティゾーンに一気に書き込むんですよ。
なるほど。
一つのアベラリティゾーンでもなければ一つのメミキャッシュサーバーでもないってことですね。
複数に書き込むんですね。
複数に書き込むんですけど、その書き込むメミキャッシュDも後で話すんですけど、
コンシステントハッシュングっていうのがあって、一部のサーバーに偏らせてるんですけど、
けどそれをアベラリティゾーン複数あるので、結局何台も何台も一気にセットする。
この時に、例えばアベラリティゾーンが3つあった場合、
さっきもちょっと話したんですけど、すごいサーバーたくさんあると、
運が悪いとめちゃくちゃ遅いサーバーに当たったりするんですよ。
なのでそれを避けるために、3台中2台に対して書き込みが成功したら、
もうもう1台に書き込み成功したかどうかは確認しない。
なるほど、完全性を持たないんです。
EVキャッシュは全体的にそういう筆頭で、これただキャッシュしてるだけだから、
多少データが欠けてても特に致命的な問題ないよねっていう考え方で全体的に作られてます。
確かに頭いい、その考え方。
なのでそのアベラリティゾーン3つのうち2つ書き込めたら、
あとはもう1個の方は書き込めたかどうか確認せずに、
処理としては成功とみます。
リードについては、基本的には自分と同じアベラリティゾーンに対してリードをしつつ、
ただリードが失敗した時に、データベースに対してオリジンに対してアクセスいっちゃうと、
オリジンが高負荷になる可能性もあるので、
他のアベラリティゾーンも確認していく。
いくつか確認して、でもそれもタイムアウトちょっと早めにしておいて、
もし失敗してもすぐ諦める。
で最終的にいくつか見てもなかったら初めてオリジンにアクセスする。
やることによってそのオリジンへの負荷っていうのできる限り抑えていたりします。
できる限りデータがあるところから取ってくるんだけども、
それも早くレスポンス返すために一定のところでは諦める。
そうですね。これやっぱりMemcachedがすごい早いっていうのと、
あとその分散システムとしてその1台だけすごい遅い可能性があるとか、
そういうのを全部考慮した上でこういう構成になってるんですよ。
で、あと重要なのがそのMemcached自体にはそのレプリケーションの機能って基本的にないので、
レプリケーションできないんですよ、Memcachedは。
Memcachedのサーバーの機能としてデータをコピーしておくっていうことはできないんですよね。
なのでMemcachedで頑張るんじゃなくてクライアントサイドで複数に書き込みしちゃうっていう。
そうですね。一番最初そのセットのところでクライアントが勝手にアベラビティゾーン複数と複数のサーバーに対して書き込みする。
しかも2つOKだったら3つ目は成功、可否は問わないみたいないうのをクライアント側でやってるっていうのがやっぱり聞く限りちょっと不思議だなと思っちゃいますね。
これをクライアント側でやるんだっていうのがありますよね。
確かに分散システムとか分散データベースとかだとこういう似たようなことってやってるケースあるんですけど、
それをクライアント側でやっちゃうっていうのがEVキャッシュなんですよ。
なんかすごいなと思いますね単純に。
本当に分散システムの基本的なことをもう自分たちでやっちゃうっていうのがEVキャッシュです。
若干気になったのがこのアベラビティゾーンとかサーバーのMemcachedが立ってるサーバーとかが増えた時にクライアント側はどう検知するのかなっていうのは若干気になるところではあるんですが、
ちょっとそこまではって感じですかね。
そこはね、コンシステントハッシングの話になるので。
そっちの話になるんですね。
そこもちょっと後で話しましょうか。
ありがとうございます。
キャッシュの特性とデータ選択の重要性
例えばその、やっぱりここってさっきから話してる通りそのキャッシュってもうすぐ消えるよねっていう大前提があるんですよ。
消えたら再生できるよねっていう割り切りが全体的にあるんですよね。
やっぱりその、なんでそのそもそもキャッシュしていいデータとキャッシュしちゃいけないデータってあるじゃないですか。
アプリケーションの特性として。
なのでそもそもそのキャッシュしていいデータじゃないデータをやっぱりEVキャッシュ使って書き込むと多分いろいろおかしなことになるんですよね。
なのでやっぱりここはその使う側がちゃんとそういうことを考えて使っているっていう大前提はありますね、やっぱり。
アプリケーション側でこのEVキャッシュを使う際にセットを、セットをどのデータに対して。
どのデータに対してキャッシュを使うのかっていうことを間違えるともう全部おかしくなるので、アプリケーション作ってる側はそこを間違えないっていう大前提でEVキャッシュは作られてますね。
なるほど、じゃあエンジニア側の力量が。
そうですね、力量が壊れている感じがします。
ネットフリックスの内部ではそこをちゃんとレビューとかしてるんでしょうね。
だと思います。
これはMEMキャッシュに載せるデータであるかどうかとか。
なるほど。
例えばそのライト失敗しましたっていう時にやっぱりその一つのサーバーグループに対して失敗しただけだったら無視するだけなんですけど、
そこが失敗したAvailabilityゾーンのアプリケーションサーバーがまず自分のAvailabilityゾーンのMEMキャッシュで見に行くんで、
その時に書き込み失敗してるから古い値を返してしまうかもしれないしミスするかもしれない。
EVキャッシュは別にだからそういう時に完全に隠さないというか、
その時にまた他のAvailabilityゾーンを見に行ったりするんだけど、それで失敗してもある程度はいいよねっていう。
EVキャッシュの設計ってキャッシュだからある程度その辺を割り切るっていう感じに全体的になっています。
それが前提としてデータの特性上あるからこういう設計になってるよっていうようなところですね。
そうですね。で、さっきもちょっと話したその特定のサーバーに負荷が偏る。
ホットキー対策と二層キャッシュ構造
例えばホットキーめちゃくちゃ参照が来るキーみたいなのあるじゃないですか。
そういう時に特定のサーバーに負荷が偏ってしまうっていうのもあるので、実はこれインメモリーのキャッシュっていうのもあります。
で、リードするときにいきなりMemcacheに行くんじゃなくて、インメモリーのキャッシュを見に行って、なかったらMemcacheにアクセス行くようになります。
なるほど。アプリケーションサーバー側のメモリーにも一旦保持してる。
一旦保持してる。これなんでかっていうとそのホットキー、めちゃくちゃ参照が来るキーにMemcacheに対してリクエスト行きまくっちゃうとMemcacheがまた負荷になっちゃうので、
そういうのはインメモリーで返してほしいんですよ、ホットキーは。そうすればMemcacheにほとんどリクエスト行かなくなるので、ホットキーがあったとしても大丈夫。
回送になってるんですよね。アプリケーション側のインメモリーのキャッシュと、そこから先のMemcacheのキャッシュというような形で、
すごいざっくり分けると2層ぐらいになってるってことなんですね。
そうですね、結構これってよく使われているもので、例えばCDNのキャッシュとかも結構2層でやるとうまくいったりするんですよね。
なんで2層になってるかっていうと、やっぱりCDNのキャッシュもホットキーっていうのが絶対あるんで、特定のURLだけめちゃくちゃアクセス来るとかあるじゃないですか、CDNとか特に。
たしかに。
なので、エッジでそういうホットキーみたいなのはもうエッジで全部返しちゃうっていう構成になってるんです。
なってることが多くて、やっぱりそのキャッシュを2段で持つっていうのはそのホットキー対策としてすごく有効なんですよ。
それをEVキャッシュの中で実装してる。
なるほど。EVキャッシュはそこのホットキー対策までちゃんとケアして、インメモリーの機能も足して、独自で足してる。
独自で足してます。
逆にメムキャッシュDのクライアント、標準のクライアントではない機能ってことですね。
インメモリーは勝手には作んないですね。
EVキャッシュの機能としてインメモリーを使う。それによってそのアプリケーションとメムキャッシュDクラスターで2段でキャッシュをするっていう構成になります。
頭いい。
そうですね。
コンシステントハッシングの実装と課題
そして。
さっき言ったコンシステントハッシングの話をちょっとすると、各サーバーグループ、アベラビティゾーンごとのグループにメムキャッシュDのノードがたくさんあるんですよ。
このキーはこのノードに置くみたいなのを決める必要があるんで、これがコンシステントハッシングって呼ばれてる仕組みになります。
難しそうなんですけど単純に聞くと。
なんかそんなに難しくなくて、例えば何でもいいんですけどキーをハッシュ関数通してあげて、例えばサーバーが10台、クラスター10台あるんだったらそれを10で割った余りが、
例えば0だったらこのサーバー、1だったらこのサーバーみたいなそういう単純なロジックでもいいんですよね。
確かに。機械的に割り振ってるってことですね。
そうですね。それによってメムキャッシュDの効率を高めるっていう感じになります。
分散させる。
分散させてわざと偏らせることによってメムキャッシュDのメモリーを節約してたくさんのデータをキャッシュできるようにするっていうやつで、
実はさっきちょっと紹介したそのpeckleのメムキャッシュD、PHPのやつですね。
もう実はコンシステントハッシング使えるんですよ。
だからPHPのpeckleメムキャッシュDって結構すごくて、
プロクシーサーバーみたいに通さなくてもそのコンシステントハッシングもできるし、
あとコネクションの映像化もできるので、
実はPHPでハイパフォーマンスなシステム作りたいってなったら、
けっこうpeckleメムキャッシュDはすごく強い味方になってくれます。
もしかしてEVキャッシュはpeckleメムキャッシュDをちょっとリスペクトしているみたいな。
たぶんないんじゃないかなと思っていて、
なんでかっていうと、
単純にコンシステントハッシングはけっこう有名な、
いろんなシステムで使われている仕組みだし、
あとJavaのメムキャッシュDクリエイントはコネクションプーリングとか当たり前にやるので、
そんなに珍しい機能じゃないんですよ、Javaだと。
そういった形でキャッシュを分散させていい感じに。
やってるんですけど、
ただやっぱりさっきもちょっと話した、
サーバーが例えば障害になってしまうと、
やっぱりさっき言ったような、
例えば10台だったら10のワタ余りってやってた場合、
やっぱ9台になってしまうと、
けっこう変わっちゃうじゃないですか、
そうするとキャッシュのミスが一気に発生するようになってしまうんですね。
なんでこれはもうけっこうどうしようもないです。
なのでここはもうサーバー台数を増やすしかないかな基本的には。
なのですごいサーバー台数が多いから、
コンセンスレッドハッシングのサーバー台数ずれても、
ちょっとはミスするけど、
すごい致命的なことにはならないよねっていう感じですね。
1台死んだとしても他に100台いるから大丈夫だよなっていう。
そうですね、それでちょっとキャッシュミスするけど、
それは致命的な問題はないでしょうっていう。
それこそやっぱり2段、
インメモリーキャッシュもあって、
キャッシュが2段になっているからっていうのもあると思います。
なるほど。
もう本当にメモキャッシュDのサーバーをどれだけ増やせるかっていう勝負なんですね、ここは。
1台死んだ、2台死んだとしても被害が最小に収まる形のサーバー台数を
常に確保しておかないといけないということなんですね、ここは。
サーバー台数ある程度ないとコンセンスレッドハッシング使ってても、
やっぱりサーバー台数増減したときにちょっと影響が出ちゃうっていうのはどうしてもあります。
だから1台、2台じゃあ意味ないんだぞってことですよね。
そうですね、数台だけだとクラスターにはならないですね。
本当にどのぐらい経っているのかわかんないですけどね、
Netflixのプロダクション関係で、
数千台いるってことはどうなんですかね。
何台いるかわからないですけど、
コンセンスレッドハッシング使いたいんだったら、
数十台は最低でも必要かなと思いますね。
なるほど。
そういったのをコンシステントハッシングっていうのを
EVキャッシュでは、もちろんクライアント側でサポートしてる。
サポートクライアント側でサポートしてるんで、
だからクライアント側が全員同じ計算式でコンセンスレッドハッシングしてるんですよ。
そうじゃないときっとしないじゃないですか。
アルゴリズムを統一しないといけないですよね。
ここは結構割り切りというか、
ここのEVキャッシュのコンセンスレッドハッシングのロジックはいじれないんですよね。
全アプリケーション同じ行動でプロイしないといけないから。
しかも同時にですよね。
ここ切り替えること現実的にないんだと思うんですけど、
なのでこの辺はEVキャッシュだからこそできるというか、
全員ロジックが一緒だからできるっていうところもあります。
ちなみにさっき途中で言ってたサーバーを増やしたときに、
クライアント側がどう判断するのかみたいなところはどうなんですかね。
コンシステントハッシングの範疇なんですかね。
サーバー台数増えたら、
もちろんそのコンシステントハッシングの割り振りが変わることはありますよ。
そこはやっぱりインメモリキャッシュも使いつつ、
キャッシュがミスになったやつだけがミキャシュに行くので、
そこはなんとかなるでしょうっていうところですね。
そこはやっぱり割り切りが大事なんですよね。
EVキャッシュの仕組みとして。
やっぱりキャッシュしてるだけなんで。
そういった形でも大量なサーバーをどれだけ使い倒すか、
障害をなくすかっていうところに重きを置いているというところ。
EVCacheにおける監視機能
次のところで言うと、
やっぱりこの手のやつって監視、モニタリングも結構大事じゃないですか。
確かにそうです。サーバーが死んだら一大事っていうことなんで。
そうですね。
メキャシュリー単体だったら、
メキャシュリーの機能としてサーバースタッツの機能があって、
どれくらいヒットしてるの、どれくらいミスしてるのとか、
あとエビクションズ。
前のメキャシュリー化の時も話したんですけど、
メモリーが足りない時に古いデータを追い出さないといけないんですよね。
それがエビクションズっていうのを見ると、
どれくらいキーが消されたのかっていうのが見れるんですけど、
そういったデータっていうのをやっぱりメキャシュリーモニタリングするんだったら監視しないといけないんですよね。
EVキャッシュを使うとやっぱりクライアント側でも結構いろんな処理をしているので、
クライアント側でも結構いろんな情報、
例えばどのゾーンのメキャシュリーリードしてるのかとか、
あとアクティブなコネクション数どれくらいなのとか、
タイムアウトどれくらい発生してんの、エラーどれくらい発生してんのとか、
あとコネクションプールリングの状態どうなってんのとか、
本当にEVキャッシュの中でモニタリングしたい要素ってたくさんあるんですよ。
なのでそういうのもちゃんとEVキャッシュの機能として監視できるようになっている。
クライアント側で監視機能が存在してる。
あと管理用のオブジェクトっていうのがJavaのオブジェクトがあって、
それを使って監視ができるようになっている。
なので本当にそのモニタリングも考慮して作られてるんですよね。
具体的にはスタッツみたいな関数呼び出すとダンプされるみたいな感じなんですかね。
その辺は自分もあんまり詳しく知らないんですけど、
Javaにそもそもそういうスタッツ用の機能があるらしくて、
それに乗っかった仕組みらしいです。
なるほど、デバッグの機能というかそういう監視の機能があるんですね。
JavaのJVM自体に標準であるらしくて、それに乗っかってるみたいですね。
それで監視ができるよっていうJVMの監視機能に乗っかることでできるって形なんですね。
そうですね。
エビクションズと運用上の注意点
便利そう。
なので本当に詰まってるんですよね。
EVキャッシュのソースコードの中に本当に大規模な環境でウェブサービスで
キャッシュをどううまく使えばいいのかっていうのが詰まってるのがEVキャッシュなんですよ。
今ちょっと聞いてて気になったのが、
こんだけ巨大になって巨大なシステムで、
かつメモキャッシュで扱ってるようなデータがキャッシュミスしてしまうと
ちょっと致命的になるっていう状況において、
メモキャッシュDサーバーのメモリが枯渇しているからデータが追い出されたっていう状況?
エビクションズですかね。
結構致命的なのかなと思っちゃったんですけど、そこはそうでもないんですかね。
そこも割り切りなんですかね。
自分のイスコンボンでも書いたんですけど、
基本的にエビクションズが発生していたら何かおかしい。
やっぱりメミキャッシュDのメモリが足りないとか、
あとクラスターの台数が足りないとか、
基本的に致命的なことが起こっているので、
メミキャッシュDとかそういうKBSのキャッシュを運用する場合は
必ずエビクションズを監視してくださいっていうのは、
イスコンボでも実は書いてあります。
じゃあそこを監視してもアラートが鳴るような状況ってことですよね。
そうですね。アラート鳴らした方がいい。
エビクションズが常に発生しているようだったら何かおかしいですね。
っていうのをクライアント側、EVキャッシュ側もカバーしてたりするんですかね。
それはカバーしてないですね。
カバーしてないですね。
それはもうやっぱりそれはまた別なんですよね。
EVキャッシュとは。
そのメミキャッシュDクラスターの監視で文脈になるので、
EVキャッシュは監視してないですね。
なるほど。そこは割り切ってるんですね。
EVキャッシュは結構割り切りがあります。
なるほど。
ちゃんと責任分解点で、
メミキャッシュの方のサーバーの監視の方はそこでちゃんとやっておいてはないっていうところですね。
あとエビクションズは少しだけだったらすぐ致命的なことにはならないので、
エビクションズが発生してたらちゃんとクラスターの台数足せば大体なんとかなると思います。
この構成であれば。
あれですよね。その一時的なエラーというかちょっとやばいよというようなアラートで、
それが日常的というかずっと続いてるとやばいよっていうようなエラー。
そうですね。少し発生するぐらいだったら一旦いいかっていう感じであります。
なるほど。サーバーをちゃんと増やしてねとかそういうことが発生するってことですね。
そうですね。
障害発生時のEVCacheの挙動と回復力
っていう中でそういうちゃんと監視していく中でも障害が発生した時のこととかもちゃんと考えられたりするんですかね。
どこで障害になるかっていうのもあって、やっぱメミキャッシュリークライアント側が例えば障害になった場合は、
さっきも言った通りリードする時にまずは自分が所属しているサーバーアベラビリティゾーンのメミキャッシュリー見に行くんですけど、
その後に他のアベラビリティゾーンも見に行くんですよ。
なのでその特定のメミキャッシュリーのアベラビリティゾーンが障害になっているだけだったら、
自分EVキャッシュだけで回復というかなんとかなるって構成になります。
あとここもやっぱりメミキャッシュリーであるメリットがあって、
メミキャッシュリーってそのレプリケーションしてないんで、なんか前代いきなり壊れるってことがあんまりないんですよ。
なるほど。コピーをしてないか故に大障害性がある。
通信してないからそもそもメミキャッシュリー同士は。
確かに。
だからデータセンター自体が障害になったりとかしたら別なんだけど、
メミキャッシュリーは本当にシンプルで、あとレプリケーションとかもしてないから、
いきなり前代同時に壊れるっていうことは滅多にない。
確かにメモキャッシュリーサーバー自体は疎結合になってるからですよね。
そうですね。
もしなんかおかしなメミキャッシュリーがあったら、それをちゃんと隔離できれば、
そのコンセンセントハッシングの仕組みを使ってすぐに復旧できるはず。
ちゃんと隔離できればですけど。
素晴らしくないですかこれ。素晴らしい設計だなと思うんですけど今。
本当にとにかくNetflixを安定的に動かしたい。
早く安定的に動かしたいって考えられた結果がこれなんですよ。
綺麗ですね。
EVCacheの設計思想とインフラシンプル化
綺麗っていうか、スマートクライアントでクライアント側がすごい一生懸命考えることによって、
全体のインフラはシンプルで、すごいパフォーマンスが出せる仕組みになっている。
クライアント側のEVキャッシュに全てを詰めてる感じですね。
EVキャッシュがすごい難しいことやってる代わりに、全体がシンプルになっていい感じに返せる。
いや素晴らしいです。ここまで聞いてて。
やっぱり最初の話、プロクシーサーバーで賢いプロクシーサーバーがいて、全部やればいいんじゃないかとか、
メミキャッシュDにレプリケーションの機能とか、そういう上手い機能つけて頑張ってやってもらったらいいんじゃないかって、
最初ちょっと話あったと思うんだけど、やっぱりそうじゃないんですよね。
それだとやっぱりそこが障害になる可能性がある。
メミキャッシュD自体が障害になったりとか、プロクシーサーバーが障害になったりとかっていうのが全然あり得る。
なのでEVキャッシュで全部やると障害になりにくいんですよ。
いやすごいですね。
ここまで聞いてて、すごいこのEVキャッシュとメミキャッシュDを使ったサーバー群のこの構成って、
Netflixが使ってる構成ってすごい素晴らしいシステム構成じゃないですか、設計じゃないですか。
それ自体がネオメミキャッシュDみたいな形になるんじゃないのかなって若干思ったんですが、
それをあえてメミキャッシュDはメミキャッシュDとして存在させておいて、
EVキャッシュはあくまでもクライアント側のライブラリーとして存在するみたいないうところを守ってるっていうところが何かあったりするんですかね。
デプロイとキャッシュの課題
やっぱりシンプルでかつ信頼性があるシステムにしたいってなると、
メミキャッシュDは十分早いし、ちゃんと信頼性が高いシステムなんですよね。
だからそれぞれ信頼性が高いシステムでちゃんと構成したいんだと思うんですよ。
新しく作るわけではない。
そうですね。
でもこれもユメミのような仕組みかっていうと、やっぱりいろいろ問題はあって、
さっきも言ったEVキャッシュってeメモリキャッシュじゃないですか。
そうなると再起動した時にキャッシュ飛んじゃうんですよ。
アプリケーションサーバーが立ち上がり直したら消えちゃいますね。
そうですね。なのでデプロイした時に消えちゃうんですよね、キャッシュが。
なのでここってデプロイもちゃんと考えないといけなくて、
デプロイも前代一気にデプロイしちゃうと、一気にキャッシュミスイベントが大量に発生しちゃうので、
デプロイもちょっとずつやるっていうのも考えないといけないし、
あとデプロイタイミングもアベラリティゾーンごとにずらしていくとかやんないといけないし、
あと例えばデータセンターのアベラリティゾーン自体が障害になって、
一回下げたとするじゃないですか。
で、じゃあまた障害治ったんで戻しますってなった時にも、
メミキャッシュD側が温まってなかったら障害になる。
その投入したらまた障害になる可能性があるんですよ。
そこだけの負荷が高まりますね。
なのでさっき言ったライトを複数のクラスターにやるっていうのもここで生きてきて、
なんでそのライトを複数のアベラリティゾーンに対してやるかっていうと、
やっぱりそのちゃんと他のアベラリティゾーンのメミキャッシュDも温めておくっていう効果があるんだよね、これって。
なのでやっぱりそこも本当によく考えられてるんですよね。
そのアベラリティゾーンが障害になって一回下げたとか、
あとそういうのもちゃんと考えられてるし、
ただデプロイに関してはEVキャッシュ側じゃなくて、
デプロイの仕組み側でちゃんとそのEVキャッシュを使ってるってことを控除した上で、
デプロイの仕組みを作るっていう感じで何とかするっていう感じですかね。
なんか全てが絡んでますね、インフラ全て。
アプリケーションのデプロイもそうだし、インフラの構成もそうだし。
全部そのEVキャッシュを使う前提で考えないといけないし、
インフラと密結合、密結合っていうのかな。
まあわかんないけど。
そのインフラ全体を考えた上で作られてるのがこのEVキャッシュっていうライブラリなんですよ。
考えないといけないことがすごくいっぱいあるけど、
堅牢にする、ないしはそのレスポンスをできる限り早くするためにはこうしないといけないの運用が詰まってますね。
運用のノウハウが詰まってるんですよ、このEVキャッシュには。
EVCacheの全体像と導入の難しさ
なのでこれEVキャッシュ本当にすごい面白いし、
やっぱ大規模サービスのキャッシュはこうするんだっていうのが詰まってる。
なんかEVキャッシュっていう単体だけで見るとただのキャッシュしてる何かかなみたいなことを思ってしまうけども、
そうじゃなくてNetflixの社内で行われているどうやってデプロイサーバーを運用していくのかとか、
デプロイしてどうやってリリースしていくのかみたいなところまでもう範囲の中に入ってきてしまってるってことですもんね。
そうですね、なんで結構そのEVキャッシュ見るとそのNetflixのインフラの浸水というか、
ちょっと浸水まで見れてるかわかんないけど、なんかその一部だけでもなんかNetflixの内部を感じることができるので、
結構EVキャッシュ面白いと思ってます。
めちゃくちゃ面白いですね、これここだけでも。他にももちろんいっぱいあるんで。
そうですね、正直多分ごく一部しか自分も解説できてないと思うんですけど、
でもごく一部だけでもこんだけいろいろなものが詰まっている。
いやすごいな、EVキャッシュだけでも。きっとあれですよね、Netflixが出してるOSSなんて他にもいっぱいあったりしますよね。
あると思うし、そんな詳しくないんですけどあると思うし、そもそもMemcached自体が結構Netflixの支援で最近機能追加したりとかもするので、
結構そういうの積極的なんですよね。Netflix社内で使われている仕組みをOSSにしたりとかっていうのは結構割と積極的な印象がありますね。
すごい、ちゃんと本件にも貢献しつつ、全体EVキャッシュとしてもどんどん進化していってるっていうところなんですね。
すごいな、Netflix本当に巨大ですごいトラフィックをさばいてるからこそできるような知見とかがいっぱいありそうですね。
そうですね、そこの一部だけでも感じ取れるので、結構そういうの知りたかったらEVキャッシュはおすすめです。
ちなみにこのEVキャッシュ、Javaのサーバーを運用してたとして、使うかどうかでいったらどうなんですかね。
ちょっと巨大すぎたりするんじゃないのかなと思うんですけど。
そうですね、今言ったやつ結構設定できるんですよね、そのE-Memoryキャッシュどれぐらいすんのとか。
なんかいろいろ設定がたくさんあるので、実際に運用しようとするとだいぶどういう設定があるのかとか全部確認してからじゃないと使えないので、
相当ハードルは高いと思います。
ですよね、サクッと使ってみようっていうようなものではなさそうですよね。
やっぱりどういう設定があって、うちだったらどういう設定がいいのかまでちゃんと考えないと無理ですね。
でもすごいカスタマイズできるし、めちゃくちゃスケーラブルなんだけど、使うのはエンジニアの力量が必要だよというような。
そうですね、気軽に使えるライブラリーではないと思います。
でも内部を見てみるとかなりエンジニアリング的には面白いよという。
面白いし、やっぱり部分的には自分たちで実装とかもできるところあると思うので、そういうエッセンスだけ使うとかっていうのも結構お勧めというか、
普通にやらないといけないことあると思います、大規模サービスやってたら。
やらないとスケールできないところがある。
あるので、やっぱりそういうところ参考になるんじゃないかなと思ってます。
面白いな。他にEVキャッシュのところで言い足りないというか、言っておくべきところあったりしますかね。
あるかな。割と話したかなと思います。
こんなところですかね。かなりEVキャッシュ、一番最初聞いていた話というか想像していたところと比べて、
いろんなことやってるし、ネットフリックスの内部が本当にすごいんだろうなという、
エンジニアリングの力の塊が全て入ってそうだなというところがすごいライブラリだなと思うのと、
同時に絶対自分だったらこのEVキャッシュ使いこなせないだろうなという自信が湧いてきたんですけど。
すごいなと思います。他に使ってる会社いるんですかね。
いや、いるのかな。ネットフリックスのブログとかでも紹介されたりするので、
存在を知ってる人は結構いると思うんだけど、実際投入してますわ。果たしているのかっていうのはちょっと疑問だったりします。
Amazonだったりとか他の巨大なところだったらもしかしたら使ってるかもしれないけど、
そのぐらいになると自社独自のライブラリ使ってるかもしれないですね。
結局、EVキャッシュが必要な会社は自前でこういうの作ってるんじゃないかなという気はしますよね。
そのレベル感になってくるとですよね。
そうですね。
でも、こんな形で公開してくれてること自体にはかなり技術的な面白さもあるし、勉強ポイントもあるので。
そうですね。やっぱり公開してくれてすごい感謝してますね。
結構いい時間になったので、今回はここまでにしたいかなと思います。
番組紹介と今後の展望
では、Yahoo!Yolo!とのOSSではですね、毎回一つのOSSを取り上げつつ、
それについて、片付いた変態コテ、技術的なところも深掘りしながら話をしていく番組になってます。
今後もその名の通り、Yahoo!Yolo!とのOSSを取り上げていきたいなと思ってますので、
ぜひお聞きのプラットフォームでフォローと高評価のほうをお願いします。
またですね、このOSSについて取り上げてほしいなどありましたら、
コメントとかで教えていただけると非常に嬉しいです。
公式サイトのほうに匿名でお便りを送れるようなフォームがありますので、そちらからもよろしくお願いします。
つぶやく際には、Xとかでつぶやく際にはですね、
ハッシュタグYahoo!Yolo!とのOSSつけていただけると補足しやすいのでよろしくお願いします。
それでは今回もありがとうございました。
ありがとうございました。
44:28

コメント

スクロール