こんにちは。s.kです。少し前に自身の知識と事前調査不足から直面した問題に対しての備忘録です。
目次
事象
・システムでmemcachedエンジンを選択したElastiCacheを使用しており、保存されているキー一覧の取得コマンドの実行結果と実登録件数が合わない。
テストの一環でElastiCacheに正しくデータがキャッシュされているかを確認したところ、上記事象に遭遇した。
手順
①:ターミナルからノード単位にncコマンドで接続を行い、"stats items"コマンドで出力されるデータを取得し、number行を抽出、加工しリスト化を行う。 ②:①で作成したリストを用いて、forコマンドで"stats cachedump"をリスト行数分処理する。 ③:②で行ったループ処理結果をファイルへ出力する。
以下が実際に実行したコマンドである。
for item in $(echo "stats items" | nc "ノードID" 11211 | grep 'number ' | tr ':' ' ' | awk '{print $3"_"$5}');do echo "stats cachedump $(echo $item | awk -F '_' '{print $1, $2}')"| nc "ノードID" 11211 ;done > result_keylist.txt
自身が登録を実行した回数と、ElastiCahceのモニタリングより全件正しく登録されていることは確認済みでした。しかし、登録件数とコマンド結果の取得件数が何度実行しても合いませんでした。
この時点で以下二点が原因なのではと考えました。(結果的には違いましたが…) ・視認性の悪いワンライナーコマンドなので何かを間違えている。 ・stats cachedumpコマンドのレスポンス上限(2MiB)に引っかかっている。
まず手順①で作成したリストをファイルに出力し、"stats cachedump [slabs_clsid] [limit]"コマンドのlimitと出力件数が一致しているかを確かめました。その結果、limitと出力件数が一致していない箇所が多々発見されました。しかし、結果を見る限りレスポンス上限に引っかかっている結果とは考えられませんでした。
原因
今回からmemcachedのバージョンを新しくした事を思い出し、リリースノートを見に行きました。
ReleaseNotes1423 #new-features (https://github.com/memcached/memcached/wiki/ReleaseNotes1423#new-features) バージョン1.4.23からLRUアルゴリズムが変更され、スラブ内に"HOT"、"WARM"、"COLD"の3つの領域が作成されることとなった。
今回の場合、"stats cachedump [slabs_clsid] [limit]"で取ってくるのはHOT領域のキャッシュのみだったようで、WARM、COLD領域にあった場合取得されないといった具合でした。
"stats items"コマンド結果でも"HOT"、"WARM"、"COLD"の3つの領域が表示されるようになっています。
stats items STAT items:5:number 6 STAT items:5:number_hot 1 STAT items:5:number_warm 0 STAT items:5:number_cold 5
しかしv1.5.16でnc接続後、"stats items"コマンドの結果が以下の状態時に"stats cachedump"コマンドを行ったところ
stats items STAT items:1:number 2 STAT items:1:number_hot 0 STAT items:1:number_warm 0 STAT items:1:number_cold 2 STAT items:1:age_hot 0 STAT items:1:age_warm 0 STAT items:1:age 19144 STAT items:1:evicted 0 STAT items:1:evicted_nonzero 0 STAT items:1:evicted_time 0 STAT items:1:outofmemory 0 STAT items:1:tailrepairs 0 STAT items:1:reclaimed 0 STAT items:1:expired_unfetched 0 STAT items:1:evicted_unfetched 0 STAT items:1:evicted_active 0 STAT items:1:crawler_reclaimed 0 STAT items:1:crawler_items_checked 37 STAT items:1:lrutail_reflocked 0 STAT items:1:moves_to_cold 33 STAT items:1:moves_to_warm 31 STAT items:1:moves_within_lru 1 STAT items:1:direct_reclaims 0 STAT items:1:hits_to_hot 0 STAT items:1:hits_to_warm 1 STAT items:1:hits_to_cold 32 STAT items:1:hits_to_temp 0 stats cachedump 1 2 ITEM key2 [2 b; 0 s] ITEM key1 [2 b; 0 s]
と、表示されたのでデータが存在する一番上の領域のみを表示するのかもしれません。 ソースコードまで読んだのですが、理解が出来ず…曖昧となってすみません。詳しい処理が分かり次第追記いたします。
対処方法 保存件数を取得するのであれば上記コマンドでもよいが、キー一覧を取得する場合以下のコマンドが推奨されている。
lru_crawler metadump [all/slabs_clsid]
"lru_crawler metadump [all/slabs_clsid]"を使用することによって全て、もしくは指定したSlab内のすべてのキーを取得することができる。
以上となります。