Memcached 公式ドキュメント まとめ
Last updated
Last updated
memcached のWikiを一読してまとめてみました (2018/05/13 時点)
公式ページ: https://memcached.org/
Wiki: https://github.com/memcached/memcached/wiki
別途、Memcachedの機能のまとめ記事等は以下のURLを参照いただければと存じます。
URL: https://github.com/memcached/memcached/wiki/Overview
設計哲学
Simple Key/Value Store: データを事前にシリアライズする必要性
Logic Half in Client, Half in Server: どのサーバを選ぶかは、クライアントが決める
Servers are Disconnected From Each Other: サーバは互いに独立して同期をしない
O(1): 遅いマシン上でもクエリーは1ms以下
Forgetting is a Feature: LRU
Cache Invalidation: クライアントはサーバへ直接データを無効化。全ホストにブロードキャストといったことはしない。
URL: https://github.com/memcached/memcached/wiki/ReleaseNotes
URL: https://groups.google.com/forum/#!forum/memcached
URL: http://lists.danga.com/pipermail/memcached/
URL: https://github.com/memcached/memcached/wiki/Install
バグがあった場合は、まず最新版へアップグレード
Memcachedは libevent 依存なので、インストールしておく
インストール方法
URL: https://github.com/memcached/memcached/wiki/TutorialCachingStory
データベースが負荷が高くエラーが出ているのでmemcachedの導入。
Memcachedをアップグレードのためにシャットダウンをするときは、DBの負荷が大丈夫か気にかける
URL: https://github.com/memcached/memcached/wiki/Hardware
CPU Requirements
Memcachedは普通CPUをあまり使わない。
マルチスレッドで、デフォルトでは4ワーカースレッド
RAM Requirements
複数のホストのメモリセクションをすべて合わせて考える。
すべてのホストを同じ量のメモリが利用可能なものにすると、重みなど気にしなくても良くなる。
メモリを過剰に割り当てるとスワップが発生するので、チューニングが必要になる
RAMのスピードはそこまで高速にしても効果はなさそう
複数のNUMAノードにマナガって稼働させると、パフォーマンスが大幅に下がるので、numactl 等でNUMAノードにつき、1インスタンスを稼働させるようにする
ハードウェアレイアウト
Webサーバ上でMemcachedを稼働させる場合 : 残ったメモリに少し余裕を持たせて割り振る
データベース上にMemcachedを稼働させる場合 : あまり良くない。DBのメモリ上にインデックスやデータがある方がメリットが大きい
Memcached 専有 : 他のプログラムを考えなくてもよく、スケールもし易い
キャパシティプランニング : アプリケーション問題時に、サーバが何台ロストしても大丈夫か見積もっておくことが大事
ネットワーク
項目の大きさの平均サイズによるが、アプリケーションはできるだけ
多くのデプロイでは、それほど必要ないかも知れないが、大きい帯域幅や10gigabit ethernetが必要な状況であれば効果がある可能性がある。
URL: https://github.com/memcached/memcached/wiki/ConfiguringServer
Commandline Arguments
最新のドキュメントは、memcached -h や man memcached を参照
Init Scripts : scripts/ ディレクトリ以下
Multiple Instances
Networking : リスナー → TCP, UDP, UNIXソケット
Connection Limit
デフォルト 1024
コネクション不足は、stats コマンドの listen_disabled_num が0かそれに近いかを確認する
Threading
libevent を使用
ワーカースレッドによるモデルで各スレッドが並行した接続を扱う
デフォルトでは、4つのスレッドが割り当てられているが、激しく稼働させない限り、いじらないほうが良い。
Inspecting Running Configuration
URL: https://github.com/memcached/memcached/wiki/ConfiguringClient
Common Client Configurables
Hashing
全てのクライアントは、サーバーに渡って、ハッシュキーの手法を持っているが、クライアント間で互換性はない。
Perl の Cache::Memcached に対して PHP クライアントを使用しても、動作しない
Consistent Hashing
サーバの数を変更すると、通常40%以上のデータ移動が必要だが、10%未満の移動に抑えられる。
Configuring Servers Consistently
設定ファイルの同期には、Puppet/Chef/rsync/whateverを使うと良い
"Weighting"
より大きなサーバがある場合は、重みをつけられる
Failure, or Failover
サーバが落ちた時、リストの次のサーバに再割当てが試みられる。
Compression
圧縮していると、メモリ節約やレイテンシー減少が期待できる
多くのクライアントは、アイテムの一定サイズ以上の閾値での圧縮する機能がある
Managing Connection Objects
memcached へ接続する度に初期化していたら、接続がリークするかも
URL: https://github.com/memcached/memcached/wiki/Extstore
memcached 1.5.4 以上で、ビルド時に ./configure --enable-extstore が必要
複数インスタンスが有り、大きな値を持つ時に外部フラッシュストレージを使用
stats や stats slabs コマンドで、大きな chunk_size を持ったスラブクラスが、比較的高い total_pages を持っており、evictions が見られる時に有効
./configure --enable-extstore && make && make test && sudo make install
でビルド
チューニングは余裕があれば特にしない。stats
コマンドの結果を監視し、ディスクにどれだけ監視されているかを見る
Primary tradeoffs
LRUの末尾からアイテムは取り出されるので、再び取り出す時、フラッシュがヒットしにくい
書き込みがフラッシュより早いと、ストレージへのフラッシュより先に、LRUの末尾からevictされる
Performance expectations
多くの操作でフラッシュが必要ない
フラッシュされたアイテムのみ読み込み、書き込みはLRUの末尾から。既存のフラッシュされたアイテムを圧縮し、ストレージへタッチ
LRU の終わりに近づいているものはヒットしにくくなる。キャッシュミスを減らすことに役立つ
大きなアイテムのみフラッシュできる。アイテムサイズが小さいと、ネットワークの帯域の前にフラッシュデバイスが飽和する
監視すべき項目
evictions
stats items
コマンドで、高いスラブクラスで、とても低い age がないか。少ないアイテムで多くのメモリを使用している可能性
ディスクへの書き込みの多さ。レイテンシーのスパイク。ディスクのハング
ディスクへの書き込みの多さ。RAMを追加したり、圧縮設定を入れる
Page buckets
ストレージの page は、複数の buckets へ分割される
特殊ではない全てのアイテム
512k 以上の大きなアイテム
圧縮アイテム
TTLの短いアイテム
Tuning options
--help や stats settings でデフォルト設定確認
ext_page_size, デフォルト 64M
ext_wbuf_size, デフォルト 8M
ext_threads, デフォルト 1
ext_item_size, デフォルト 512バイト
ext_low_ttl
今後変更される可能性があり、バケットを多くするほうが効果的
ext_max_frag
ext_drop_unread
ext_compact_under
ext_drop_under
ext_recache_rate
Runtime tunables
extstore [command] [optional value].
command: item_size item_age low_ttl recache_rate compact_under drop_under max_frag drop_unread
Very high level detail
1つのファイルは、一定サイズ(デフォルト 64M)のいくつかの論理ページへ分割され、Writeバッファ(8M以上)がページへ後ほどフラッシュされるオブジェクトを保存するのに使われる。
IOスレッドは、非同期にWriteバッファへフラッシュされ、異アイテムを読み込み直す
アイテムは、キーと小さいヘッダー(フラッシュで生き残るデータを扱う)でハッシュテーブルに残される。
ストレージエンジンヒャ、バージョン数を返納することでページをリサイクルする
Technical Breakdown
Goals
大きな値がフラッシュできる。小さいものはRAM上のまま
1つのキーを受けるのに1つのread
非同期なドライブへのバッチ書き込み
主なハッシュテーブルは管理権限
新たなアイテムの書き込みは、フラッシュデバイスをブロックしない
ストレージからのデータをforget/evictは、ドライブを使ってはいけない
Assumptions
データのTTLが長い
小さいアイテムのオーバーヘッドが、保存よりメリットがある
小さいアイテムのオーバーヘッドが、ミスより良い
データの少数が頻繁にアクセスされる
Architecture
フラッシュの場合は、storage が LRU maintainer と似た働きをする。compaction も IO に作用する。
How an item flows to storage:
The lifetime of a storage page
1ページ辺り、デフォルト64MB。
書き込みはバッファIOを使用
メモリストアのアイテムヘッダーには、[PAGE ID, OFFSET IN PAGE, VERSION NUMBER]
URL: https://github.com/memcached/memcached/wiki/Clients
Memcached API clients : リストに載せたいクライントがあればPRを
URL: https://github.com/memcached/memcached/wiki/Commands
Standard Protocol
キー : 250バイトまで。スペースや、ASCIIモードの改行を含めず
32bitフラグ値
失効時間。30日まで。それ以上は、Unixタイムとして扱われる。
64bit CAS値
任意のデータ
コマンド
Storage Commands
set
add
replace
append
prepend
cas
Retrieval Commands
get
gets
delete
incr/decr
Statistics
stats
stats items
stats slabs
stats sizes
flush_all
References
https://github.com/memcached/memcached/wiki/Protocols
URL: https://github.com/memcached/memcached/wiki/CommonFeatures
特徴貼り付け!!!!
Less Common Features
Get-By-Group-Key
Multi-Get コマンドは、複数のサーバにまたがってリクエストは非効率
Noreply/Quiet
NoreplyがASCIIかそうでないかで実装されてるかによって、トラブルシューティングが難しくなりうる
Noreplyは、サーバへmutationsしたいが、レスポンスを待ちたくない時に使う
Multi-Set
Multi-Setは"quiet" モードの拡張で、多くのコマンドが、バイナリプロトコルでパックされる。
失敗時のとき等のみにサーバはレスポンスをする。
References
https://github.com/memcached/memcached/wiki/NewCommands
URL: https://github.com/memcached/memcached/wiki/Programming
Basic Data Caching
Wrapping an SQL Query
Wrapping Several Queries
Wrapping Objects
シリアライズの必要があるか。コンストラクタでキャッシュからデータを取ってくる時等
シリアライズは、効率的にシンプルに
Fragment Caching
Extended Functions
Proper Use of add
既存のキーがなければ追加することができる
Proper Use of incr or `decr
Expiration
0から30日までを指定可能
Key Usage
Avoid User Input
ASCIIプロトコルには、スペースや改行があるので注意。
バイナリプロトコルではこの必要はない。
Short Keys
64-bit UIDは良い。
base64 の利用
Informative Keys
これだと、tcpdumpやstraceしてもどこから来ているかわからないので
key = 'SQL' . md5sum("SELECT blah blah blah")
ユニークなクエリーIDをキーに含める
key = 'SQL' . query_id . ':' . m5sum("SELECT blah blah blah")
URL: https://github.com/memcached/memcached/wiki/ProgrammingFAQ
全キーをリスト化する方法はない。デバッグインタフェースはあるが、推奨されない
キャッシュのダンプを取るには、-vv や -vvv でスクリーンセッションを使用するか、 MaatKit を使用する
キー間を渡り歩くような操作には向いていないので、Tokyo Tyrant, MySQL等を使用する
デバッグインターフェイス stats cachedump で取得可能だが、部分的な取得で、かつ遅い
memcached をセッションには使用するのは推奨されない。ハードウェアやソフトウェアアップグレードでキャッシュがの一部が消え、ログアウトされることになるので。
MySQLのクエリーキャッシュで、テーブル単位でキャッシュしたりすのは、静的サイトでは有効
memcached コマンドは、内部的には、atomic
認証は、クライアントがサポートしていれば、SASL 認証が使えるかも。ただし、本当に必要な時以外に使うとレイテンシーの増加につながる
フェイルオーバー機能はないが、クライアントによっては、次のサーバへアクセスするという方法を取る。
再起動後にデータを残しておく方法はない。今後実装予定ではあるけど。
データが失効しても、再度参照されるまで、curr_items は減らない。
URL: https://github.com/memcached/memcached/wiki/ProgrammingTricks
ネームスペース
機能はないが、キーのプレフィックスで簡単にシミュレーションできる
Unixタイムを利用
Invalidation
Zero byte values
こういう実装はダメ。結果で0やfalseや空のデータが返ってくるので。
空のキーは役に立つ
Reducing key size
メモリの節約にキーのサイズは小さくしておく。
250文字まで。今後65kまで拡張予定
説明的なキー名は無駄
Avoiding stampeding herd
hotなデータのキャッシュミスを避ける
Ghetto lock : add コマンドで減らす
Outside mutex : サードパーティの中央化されたmutexがある。MySQL の SELECT GET_LOCK() ... RELEASE_LOCK()
Scaling expiration : 失効時間を指定しても、実際には、もう少し長い時間を設定されており、ソフトタイムアウトとハードタイムアウトがある。ロックに失敗して、古い方のデータを使うことがある。
Scaling expiration : Gearman は良くある、早くてスケーラブルなジョブサービス
Ghetto replication : クライアントによっては、レプリケーションをサポートしているかも。
"Touching" keys with add : 1週間以内に失効させたいキーがある時、add コマンドで、LRU の先頭に値を持ってくることができる。
References
http://www.maatkit.org/
http://dormando.livejournal.com/495593.html
https://github.com/memcached/memcached/wiki/SASLHowto
http://lists.danga.com/pipermail/memcached/2007-July/004578.html
http://lists.danga.com/pipermail/memcached/2007-July/004581.html
http://gearman.org/
URL: https://github.com/memcached/memcached/wiki/UserInternals
How Memory Gets Allocated For Items
-m オプションで、アイテムデータのストレージのために予約するメモリ割り当て量を指定し、主なストレージは、1MB のページへ分割される。各ページは、必要に応じて、slab classes に割り当てられ、特定の塊のサイズへ分割される。
What Other Memory Is Used
各コネクションのバッファにもメモリが使われる。
URL: https://github.com/memcached/memcached/wiki/ServerMaint
Important Stats
stats コマンド
curr_connections : -c オプション
listen_disabled_num
accepting_conns
limit_maxbytes : -m オプション
cmd_flush : flush_all コマンド実行時にカウントされる。
stats sizes コマンド : stats sizes enable
Slab imbalance
グローバルの evictions stat
stats items コマンド内の evicted, evicted_nonzero
stats slabs コマンドから total_pages stat
evictions が多いスラブが多いページを持っていたら、OOMになりうる
evictions が多いスラブがページでラインアップされなかったら、再起動
Stats for Application Health
OS Health (avoid swap!)
URL: https://github.com/memcached/memcached/wiki/ClusterMaint
Upgrades : プロダクション環境では、1台だけアップグレードしてみて問題がなければ、残りへロールアウトしていくと良い。
URL: https://github.com/memcached/memcached/wiki/Performance
Max Clients
接続された各クライアントはTCPメモリを使うので、RAMから割り当てられる限りでしか接続できない。
新規クライアント接続は、1つしかスレッドを使うことができないので、非常に早く接続を使いまわすとスレッドをオーバーするかも。永続接続か、UDPが代替案。
高い接続切れは、OSのTCPのチューニングが必要かも
Maximum number of nodes in a cluster
From the Client Perspective
TCPソケットを多く確立しすぎるとRAMの無駄使い
永続接続を使わないと、TCPのスリーウェイハンドシェイクのレイテンシーやパケットが余分に発生
The Multiget Hole
特定ユーザーのプロファイルに対する全てのキーが、同一サーバ上にあると、呼び出すsyscallの数が少なくなる
A Well Designed Binary Protocol Client
バイナリプロトコルを使えば、異なるクライアントインスタンスからのリクエストを同じTCPソケットにパックできる。
Remember Moore's Law
Economy of Scale : クラスターが大きくなってくると問題も発生するようになりがち
URL: https://github.com/memcached/memcached/wiki/Timeouts
Troubleshooting Timeouts
stats コマンドで listen_disabled_num を確認
2.通常の怪しいところを確認 : スワップ。CPU(nice,renice)。64bit
mc_conn_tester.pl を実行(www.memcached.org/files/mc_conn_tester.pl )
パケットがドロップしている可能性
ファイアウォールやスロット不足、ネットワークカード等
TIME_WAIT バケットやローカルポートの使い切り
mc_conn_tester.pl で接続タイムアウトが確認できる(conn: is 0)
netstat -n | grep -c TIME_WAIT
も確認
URL: https://github.com/memcached/memcached/wiki/DevelopmentRepos
New contributors
コードを読み、テストを実行、mc-crusher を稼働、commit を読み、typo fixes をsubmitするのが良いスタート
Branches
master ブランチが中央レポジトリ
next ブランチがテストやレビューされたものがcommitされるブランチ。PR時はここからfork
Development work
リリーステスト : http://build.memcached.org:8010/
パフォーマンスリグレッションテスト: https://www.packet.net/
パフォーマンステスト: https://github.com/dormando/mc-crusher
URL: https://github.com/memcached/memcached/wiki/Protocols
主に2つのプロトコル
ASCII プロトコル
バイナリプロトコル
サブプロトコルや提案
SASL 認証
レンジ操作
Protocol
URL: https://github.com/memcached/memcached/blob/master/doc/protocol.txt
まとめをざっと外観したい場合、これをとりあえず見とく。★5
BinaryProtocolRevamped
URL: https://github.com/memcached/memcached/wiki/BinaryProtocolRevamped
memcached 1.3から導入
パケットのフォーマット
リクエストヘッダー
レスポンスヘッダー
References
memcached Binary Protocol in a Nutshell : https://www.slideshare.net/tmaesaka/memcached-binary-protocol-in-a-nutshell-presentation/
SASLAuthProtocol
URL: https://github.com/memcached/memcached/wiki/SASLAuthProtocol
References
SASLHowto: https://github.com/memcached/memcached/wiki/SASLHowto
Simple Authentication and Security Layer: https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer
RangeOps
URL: https://github.com/memcached/memcached/wiki/RangeOps