0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

memcachedの概要と動作確認

Posted at

はじめに

インターン先でMemcashedに触れる機会があったので、どんなものか調べてみました。
Memcashedについて様々な素晴らしい記事があり、それらを参考に体型立ててまとめたものなので引用が多くなっております。

memcachedとは

とてもわかりやすい記事があったので、そちらを引用させていただきます。

memcachedは高性能な分散メモリキャッシュサーバ。データベースへの問い合わせ結果を一時的にキャッシュすることで,データベースへのアクセス回数を減らし,動的なウェブアプリケーションの高速化やスケーラビリティの向上のために利用されている。
引用元:
memcachedを知り尽くす ~第1回 memcachedの基本~

導入方法

参考:macでmemcachedを導入する手順 - Qiita

###インストール

console
# brewでmemcachedをインストール
$ brew install memcached

###デーモンの自動起動設定
シンボリックリンクを作成し、launchctlで定期実行させるように設定します。

console
# シンボリックリンクの作成
$ ln -sfv /usr/local/opt/memcached/*.plist ~/Library/LaunchAgents

# 定期的にスクリプトを実行する設定
$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.memcached.plist

動作確認

###0. 前提知識
memcachedがどのような仕組みで値を格納しているのかのイメージを持っていないと、これからのコマンド操作などが理解しづらいと思いました。
とてもいい記事を見つけたので、引用させていただきます。

memcachedはSlabAllocatorという構造でデータを格納している。SlabAllocatorは、メモリを最初からある程度の量確保しておき、その確保したメモリを一定サイズの塊に分割してフラグメンテーションが起こらないようにした構造。memcachedはchunkという小さなメモリ領域に値を保存する。このchunkは決まったサイズので、chunkのサイズは複数ある。同一サイズのchunkをまとめたものがSlabと呼ばれる。memcachedはまずメモリをPageという単位で分割する。このPageはデフォルトで1MB。そのPageのなかにそれぞれのSlabが入り、Slabの中にはSlab固有のchunksizeのchunkたちが入っているという構造になっている。
引用元:キー一覧を見るためにmemcached入門

つまり、chunkというさまざまな大きさがある最小単位の入れ物があって、そのchunkを大きさごとにまとめたものがSlabっていうことみたいだ。格納する値の大きさによって使うchunkが変わってくるみたいです。

###1. プロセスが起動しているか確認

参考:macでmemcachedを導入する手順 - Qiita

console
# デーモンの自動起動設定をしたため、ずっと動いているはず。以下のような出力されればOK
$ ps aux | grep memcached
username      93162   0.0  0.0  4962944    668   ??  S    水06PM   0:01.21 /usr/local/opt/memcached/bin/memcached -l localhost
username       5111   0.0  0.0  4427068    828 s000  S+   10:36AM   0:00.00 grep memcached

###2. memcachedが実際に使えるか確認

参考:RailsからMemcachedを使いつつその実体を垣間見てみる - 株式会社ランチェスター

rails consoleでmemcacheにアクセスするためのインスタンスを作る

rails console
[1] pry(main)> a = ActiveSupport::Cache::MemCacheStore.new('localhost:11211', expires_in: 60, namespace: 'NS_ABC', compress: true)
=> #<ActiveSupport::Cache::MemCacheStore:0x007f9e886df938
 @data=#<Dalli::Client:0x007f9e886df690 @options={}, @ring=nil, @servers=["localhost:11211"]>,
 @options={:expires_in=>60, :namespace=>"NS_ABC", :compress=>true}>

引数で渡しているもの

  • localhost:11211 > ポート番号の指定
  • expires_in: 60 > 時間の指定
  • namespace: 'NS_ABC' > タグと認識している
  • compress: true > compressにtrueを指定した時は、データ容量が特定の閾値(compress_thresholdで指定も可能)を超えた際に圧縮するという設定のよう

データをキャッシュさせたり取り出したりする

rails console
# キャッシュ
[3] pry(main)> a.write('key', 'val')
=> 5044031582654955520
 
# 取り出し
[4] pry(main)> a.read('key')
=> "val"

telnetでmemcachedに接続し、実際に値が格納されているか確認する

ターミナル
# telnetでmemcachedに接続する
$ telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.

まずはstats itemsでSlabの一覧を確認する。

ターミナル
stats items
STAT items:1:number 4
STAT items:1:number_hot 0
STAT items:1:number_warm 1
STAT items:1:number_cold 3
・
・
・
END

先程格納した値がどのSlabに格納されているかはstats cachedump [Slabの番号] [取得する要素数]で1つ1つ中身を確認していく。

ターミナル
#1つ1つのSlabを確認する stats cachedump [Slabの番号] [取得する要素数]
stats cachedump 1 100
stats cachedump 2 100
stats cachedump 3 100
・
・
・
stats cachedump 4 100
ITEM NS_ABC:key [102 b; 1638165259 s]
END

Slab番号4のところに、先程格納したものが[namespace]:[key]というファーマットで格納されていることがわかります。
get <キー>で値を確認してみましょう。

ターミナル
get NS_ABC:key
VALUE NS_ABC:key 1 102
o: ActiveSupport::Cache::Entr:
                              @valueIval:ET:@created_atf1638164899.004805:@expires_in6e1
END

よくわからない値が出ましたが、これは格納した値がシリアライズされたものです。

したがって、ActiveSupport::Cache::Entryにデータを詰め込んでシリアライズをすると、同じようなものが作れます。rails consoleの方で値(val)をシリアライズしてみましょう。シリアライズはMarshalというクラスを使うのがスタンダードらしいです。

rails console
[32] pry(main)> b = ActiveSupport::Cache::Entry.new('val', expires_in: 60)
=> #<ActiveSupport::Cache::Entry:0x007f8ee9c7e758 @created_at=1638165624.288047, @expires_in=60.0, @value="val">

# Marshalというクラスを使ってシリアライズする
[33] pry(main)> puts Marshal.dump(b)                                                                                                 o: ActiveSupport::Cache::Entr:
                             @valueIval:ET:@created_atf1638165624.288047:@expires_in6e1
=> nil

memcached側で出力されたものと同じになるため、key/valでしっかり値が格納されていることがわかります。

memcached側で値を格納し、rails consoleで確認するような逆方向もできる

ターミナル
# 値を入れる set <キー> <フラグ> <有効期間> <サイズ>
set NS_ABC:hoge 0 60 8
hogehoge
STORED


# 値をmemcached側で確認してみる get <キー>
get NS_ABC:hoge
VALUE NS_ABC:hoge 0 8
hogehoge
END

しっかりと格納されていることがわかりました。
どうやら、インスタンスとnamespaceが対応づけられているみたいです。

また、実際に動いているアプリケーションのコンソールでも確認ができる

Railsアプリを起動しているターミナル
Cache read: "namespace"
Cache fetch_hit: "namespace"

casheが利用される時は、上記にあるように、fetch_hitと出力されます。
cacheはconfig/environments/development.rbmemcachedが設定されています。

最後に

今回はローカル上での簡単な動作確認を行いました。速度改善などに役立ってくる機能なので、今後は実際の開発現場での活用法などをまとめていけたらと思います。至らない点が多くあると思うので、ご指摘などございましたらご教授いただけると幸いです。
最後まで読んでいただき、ありがとうございました。

参考にさせていただいた資料一覧

第1回 memcachedの基本:memcachedを知り尽くす
第2回 memcachedのメモリストレージを理解する
macでmemcachedを導入する手順 - Qiita
キー一覧を見るためにmemcached入門 - tumblr
RailsからMemcachedを使いつつその実体を垣間見てみる - 株式会社ランチェスター

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?