無論好壞,雲端中鍵/值儲存器的一個主要使用案例是會話快取。這些物件是短暫的、經常更新的、與使用者登入會話相關的大型資料區塊。非結構化資料和 TimeToLive 限制使它們不適合作為主要資料庫。
網站所有者通常會設定一個 memcached 執行個體,只用來處理會話。我們將專注於會話資料,但執行個體可以同時處理其他資料。
假設您有一個從單一 Droplet 發展而來的網站。您有一個每月 20 美元的執行個體,有 3.5G 的 RAM 專門用於 memcached(儘管我們建議您使用多個執行個體,以防一個執行個體發生故障!)。您最近注意到使用者無法持續登入,而且您的資料庫使用量正在增加。
對於許多會話實作,如果會話物件消失,使用者會登出,或者資料庫會遭受重創以重新產生它。因此,重要的是在會話有用的時候盡可能保留它們。
Extstore 需要在 RAM 中保留物件的鍵和元資料,同時將值指向儲存體。這不適合小型物件。會話資料可能會變得很龐大,所以讓我們先檢查一下。
$ echo "stats slabs" | nc localhost 11211 | grep -E "total_pages|chunk_size"
[... snip ...]
STAT 26:chunk_size 27120
STAT 26:total_pages 321
STAT 27:chunk_size 33904
STAT 27:total_pages 2936
STAT 28:chunk_size 42384
STAT 28:total_pages 157
[... snip ...]
透過快速檢查,我們可以看到大部分已分配的記憶體最終會進入使用 26k-42k 記憶體的物件,其中大部分為 32k。即使在極端情況下,memcached 中的鍵和元資料也不能超過 300 位元組,因此大部分空間都是項目值。非常適合 extstore(如果牽強附會)!
您可以而且應該查看或繪製來自 stats items
和 stats slabs
的計數器。在這種情況下,我們可以發現區塊類別 26、27 和 28 也有很高的驅逐計數。我們正在提早捨棄會話!
目前,我們透過 20 美元的 Droplet 擁有 3.5G 的 RAM 快取。截至撰寫本文時,10 美元的 Droplet 附帶 2G 的 RAM 和 50G 的 SSD 備份磁碟空間。讓我們嘗試以一半的成本將可用快取空間增加兩倍。
由於 extstore 仍屬新功能,可能必須自行建置 memcached 才能啟用它。在你讀到這篇文章時,這可能已不再需要,因此請檢查 memcached -h
以查看在手動建置任何內容之前是否支援 extstore。
在此範例中,我們使用來自 DigitalOcean 的 Ubuntu 18.04 64 位元 droplet。請根據你最習慣的方式封裝、建立快照或管理這些二進位檔案和組態。
首先,取得最新的 tarball。我們應該修正重新導向 ;)
d@blogbox:~$ wget https://memcached.dev.org.tw/latest
[... snip ...]
latest 100%[=========================>] 454.27K --.-KB/s in 0.005s
2018-08-14 04:46:27 (96.5 MB/s) - ‘latest’ saved [465169/465169]
d@blogbox:~$ tar -zxvf latest
d@blogbox:~$ ls
latest memcached-1.5.10
d@blogbox:~$ rm latest
接著,我們取得一些相依性並編譯守護程式。請注意,在基於 redhat 的發行版 (centos/等) 上,你可能必須安裝一些 Perl 模組才能執行測試。
d@blogbox:~$ cd memcached-1.5.10/
d@blogbox:~/memcached-1.5.10$ sudo apt-get install build-essential libevent-dev
Reading package lists... Done
Building dependency tree... 50%
Reading state information... Done
[... snip ...]
Do you want to continue? [Y/n] y
[... snip ...]
d@blogbox:~/memcached-1.5.10$ ./configure --enable-extstore
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
[... snip ...]
configure: creating ./config.status
config.status: creating Makefile
config.status: creating doc/Makefile
config.status: creating config.h
config.status: executing depfiles commands
d@blogbox:~/memcached-1.5.10$ make
[... snip ...]
Leaving directory '/home/d/memcached-1.5.10'
make[1]: Leaving directory '/home/d/memcached-1.5.10'
d@blogbox:~/memcached-1.5.10$
選擇性地執行測試。請注意在 1.5.10 中,在 ubuntu 18.04 上,t/lru-maintainer.t 可能會因競爭條件而失敗。這已經修補,並將在 1.5.11 中修正。
d@blogbox:~/memcached-1.5.10$ make test
[ might fail on t/lru-maintainer.t ]
現在,我們將二進位檔案安裝到 /usr/local。你可以在組態步驟中使用 --prefix
變更此路徑。
d@blogbox:~/memcached-1.5.10$ sudo make install
原始碼 tarball 附帶 systemd 服務指令碼和組態檔案。讓我們安裝它們。請參閱下方檔案的一些編輯內容。
d@blogbox:~/memcached-1.5.10$ sudo cp scripts/memcached.service /etc/systemd/system/
d@blogbox:~/memcached-1.5.10$ sudo mkdir /etc/sysconfig
d@blogbox:~/memcached-1.5.10$ sudo cp scripts/memcached.sysconfig /etc/sysconfig/memcached
d@blogbox:~/memcached-1.5.10$ sudo vi /etc/systemd/system/memcached.service
d@blogbox:~/memcached-1.5.10$ sudo vi /etc/sysconfig/memcached
編輯 /etc/systemd/system/memcached.service 中的「ExecStart」行,使其看起來像
ExecStart=/usr/local/bin/memcached -p ${PORT} -u ${USER} -m ${CACHESIZE} -c ${MAXCONN} $OPTIONS
我們所做的只是在路徑中新增「/local/」。
最後,使用看起來像這樣的 /etc/sysconfig/memcached
# These defaults will be used by every memcached instance, unless overridden
# by values in /etc/sysconfig/memcached.
USER="nobody"
MAXCONN="1024"
CACHESIZE="1500"
OPTIONS="-l 127.0.0.1 -o ext_path=/tmp/extstore:10G,ext_item_size=512"
# The PORT variable will only be used by memcached.service, not by
# memcached@xxxxx services, which will use the xxxxx
PORT="11211"
最後,啟用並啟動服務
d@blogbox:~/memcached-1.5.10$ sudo systemctl enable memcached
Created symlink /etc/systemd/system/multi-user.target.wants/memcached.service →
/etc/systemd/system/memcached.service.
d@blogbox:~/memcached-1.5.10$ sudo systemctl start memcached
d@blogbox:~/memcached-1.5.10$ ps aux | grep -i memcached
nobody 10069 0.0 0.3 1723160 7152 ? Ssl 05:32 0:00
/usr/local/bin/memcached -p 11211 -u nobody -m 1024 -c 1024 -l 127.0.0.1 -o
ext_path=/tmp/extstore:10G,ext_item_size=512
d 10100 0.0 0.0 14856 1048 pts/1 S+ 05:33 0:00 grep --color=auto -i memcached
d@blogbox:~/memcached-1.5.10$
這樣就完成了!你現在已使用 1.5G RAM 和 10G 磁碟備份儲存空間組態 memcached。我們也已指示它允許將大於 512 位元組的任何物件清除到磁碟。
你可以 (而且應該!) 為自己的使用案例進行實驗。也許你想要將快取擴充到更多節點以提高可靠性,也許你的工作階段較小 (因此需要更多 RAM) 等。沒有硬性規定。
不太可能。Memcached 不會立即將大型物件清除到磁碟:它們會盡可能長時間留在 RAM 中。實際上,最新物件也是「最熱門」的物件,會頻繁地被讀取和覆寫。即使磁碟空間是 RAM 的 10 倍,你的讀寫作業有 9/10 可能會停留在 RAM 中。
另外,當物件被覆寫、刪除或因 TTL 而過期時,它們不會造成任何磁碟 I/O。即使對於雲端執行個體可用的有限 I/O,這也應該能擴充得很好。
透過此演練,我們得以將理論網站的快取容量擴增 3 倍,且成本減半。雖然這無法涵蓋所有使用案例,但它能快速判斷,且實驗成本低廉。
更多詳細文件請參閱 wiki