以下は「Memcached の総合分析」の第 3 部です。
公開日: 2008/7/16
著者: 前坂 徹
原文リンク: http://gihyo.jp/dev/feature/01/memcached/0003
この連載記事へのリンクはこちら:
memcachedはキャッシュ、したがって、データはサーバーに永続的に保存されません。これは、memcached をシステムに導入するための前提条件です。 この記事では、memcached のデータ削除メカニズムと、memcached の最新の開発方向 (バイナリ プロトコルと外部エンジンのサポート) について紹介します。
前回紹介したように、memcachedは割り当てられたメモリを解放しません。レコードがタイムアウトすると、クライアントはレコードを表示できなくなり (非表示、透明)、そのストレージ スペースは再利用できるようになります。
memcached は、レコードの有効期限が切れているかどうかを内部的に監視しません。代わりに、レコードを取得するときにレコードのタイムスタンプをチェックして、レコードの有効期限が切れているかどうかを確認します。 この手法は遅延有効期限と呼ばれます。したがって、memcached は有効期限の監視時に CPU 時間を消費しません。
memcached はタイムアウトしたレコードのスペースを優先的に使用しますが、それでも新しいレコードを追加するときにスペースが不足します。スペースを割り当てるための、最も最近使用されていない (LRU) メカニズムと呼ばれるファイル。 名前が示すように、これは「最も最近使用されていない」レコードを削除するためのメカニズムです。 したがって、memcached のメモリ領域が不足している場合 (スラブ クラスから新しい領域を取得できない場合)、最近使用されていないレコードから検索し、その領域を新しいレコードに割り当てます。 キャッシュの実用的な観点から見ると、このモデルは理想的です。
ただし、場合によっては、LRU メカニズムが問題を引き起こす可能性があります。 LRU は、以下に示すように、memcached の起動時に「-M」パラメータを使用して無効にすることができます:
$ memcached -M -m 1024
起動時に、最大メモリ サイズを指定するために小文字の「-m」オプションが使用されることに注意してください。特定の値が指定されていない場合は、デフォルト値の 64MB が使用されます。
「-M」パラメータを指定して起動した後、メモリが使い果たされた場合、memcached はエラーを返します。 とはいえ、memcached は結局のところメモリではなくキャッシュなので、LRU を使用することをお勧めします。
memcached のロードマップには 2 つの大きな目標があります。 1 つはバイナリ プロトコルの計画と実装、もう 1 つは外部エンジンのローディング機能です。
バイナリプロトコルを使用する理由は、テキストプロトコルの解析や処理が不要となり、元々高速だったmemcachedの性能が向上し、テキストプロトコルの脆弱性が軽減されるためです。この機能はほとんど実装されており、この機能はすでに開発コード ベースに含まれています。 memcached のダウンロード ページにはコード ライブラリへのリンクがあります。
プロトコルのパケットは24バイトのフレームで、その後にキーと非構造化データ(Unstructural Data)が続きます。 。 実際のフォーマットは次のとおりです (プロトコルのドキュメントから引用):
Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0/ HEADER / / / / / / / +---------------+---------------+---------------+---------------+ 24/ COMMAND-SPECIFIC EXTRAS (as needed) / +/ (note length in th extras length header field) / +---------------+---------------+---------------+---------------+ m/ Key (as needed) / +/ (note length in key length header field) / +---------------+---------------+---------------+---------------+ n/ Value (as needed) / +/ (note length is total body length header field, minus / +/ sum of the extras and key length body fields) / +---------------+---------------+---------------+---------------+ Total 24 bytes
上に示したように、パケットのフォーマットは非常に単純です。なお、16バイトのヘッダ(HEADER)はリクエストヘッダとレスポンスヘッダの2種類に分かれます。 ヘッダーには、パッケージの有効性を示すマジックバイト、コマンドの種類、キーの長さ、値の長さなどの情報が含まれています。形式は次のとおりです。 memcached ツリーのバイナリ プロトコルのコードについては、docs フォルダー内のprotocol_binary.txt ドキュメントを参照してください。
HEADERフォーマットを見た感想は、キーの上限が多すぎる!現在の memcached 仕様では、キーの最大長は 250 バイトですが、バイナリ プロトコルのキー サイズは 2 バイトで表されます。したがって、理論上は、最大長 65536 バイト (2 16 ) を使用できます。 250 バイトを超えるキーはあまり一般的ではありませんが、バイナリ プロトコルのリリースにより、巨大なキーの使用が可能になります。
バイナリプロトコルは次のバージョン1.3シリーズからサポートされます。
私は昨年、memcached ストレージ レイヤーを実験的にプラガブルに変換しました。
MySQL の Brian Aker はこの変換を見て、コードを memcached メーリング リストに送信しました。 memcached の開発者も非常に興味を持ち、ロードマップに入れました。現在、私と memcached の開発者 Trond Norbye によって開発 (仕様設計、実装、テスト) されています。 海外との共同開発は時差が大きな問題ですが、同じビジョンのもと、ようやくスケーラブルなアーキテクチャのプロトタイプを発表することができました。 コードベースには、memcached のダウンロード ページからアクセスできます。
世の中にはmemcachedの派生版が数多く存在しますが、その理由は、多少のパフォーマンスを犠牲にしてでもデータを永続的に保存したり、データの冗長性を実現したりするためです。 memcached を開発する前は、mixi の研究開発部門で memcached を再発明することも検討していました。
外部エンジンの読み込みメカニズムは、memcachedのネットワーク機能やイベント処理などの複雑な処理をカプセル化できます。 そのため、強制的な手段や再設計によるmemcachedエンジンやストレージエンジンとの連携の現状の難しさは解消され、様々なエンジンを試しやすくなります。
このプロジェクトで最も重要視しているのはAPI設計です。機能が多すぎると、エンジン開発者にとって問題が発生します。機能が複雑すぎると、エンジンを実装するための敷居が高くなりすぎます。したがって、インターフェイス関数の初期バージョンには 13 しかありません。 具体的な内容は紙面の都合上省略します:
詳細な仕様に興味のある読者は、リーダー内のエンジンプロジェクトとengine.hのコードをチェックアウトできます。
外部ストレージをサポートする memcached の難しさは、ネットワークおよびイベント処理関連のコード (コア サーバー) がメモリ ストレージ コードと密接に関連していることです。この現象は密結合とも呼ばれます。 外部エンジンを柔軟にサポートするには、インメモリ ストレージ コードをコア サーバーから分離する必要があります。 そこで、設計したAPIを基にmemcachedを以下のように再構築しました
リファクタリング後、バージョン1.2.5やバイナリプロトコルサポートバージョン等との性能比較を行い、性能に影響を与えないことを確認しました。 。
外部エンジンの読み込みをどのようにサポートするかを考えると、memcachedに同時実行制御を実行させるのが最も簡単ですが、エンジンにとっては同時実行制御がパフォーマンスの本質であるため、マルチスレッドを完全にサポートする方法を採用しました。エンジンの設計。
今後の改善により、memcached の適用範囲がさらに広がる予定です。
この記事では、memcached のタイムアウト原理、内部でデータを削除する方法などを紹介しました。これに加えて、バイナリ プロトコルや外部エンジンのサポートなど、memcached の最新の開発方向についても紹介しました。これらの機能はバージョン 1.3 までサポートされないため、しばらくお待ちください。
これがこのシリーズの最後の記事です。私の記事を読んでくださった皆様、ありがとうございました!
次回は永野がmemcachedのアプリケーション知識とアプリケーション互換性について紹介します。