1. 程式人生 > >【Web 叢集實戰】21_Memcached 服務應用

【Web 叢集實戰】21_Memcached 服務應用

【Web 叢集實戰】21_Memcached 服務應用

標籤(空格分隔): Web叢集實戰


文章目錄

1. Memcached 介紹

1.1 Memcached 是什麼?

  • Memcached 是一個開源的、支援高效能 、高併發的分散式記憶體快取系統。 “Mem” 即記憶體;“cache” 即快取;“d" 是 daemon,代表是伺服器端守護程序模式服務。Memcached 服務分為伺服器端和客戶端兩部分。

1.2 Memcached 的作用

  • 使用 Memcached 的主要目的是,通過在自身記憶體中快取關係型資料庫的查詢結果,減少資料庫被訪問的次數,以提高動態 Web 應用的速度,提高網站架構的併發能力和可擴充套件性。
  • Memcached 服務的執行原理是通過在事先規劃好的系統記憶體空間中臨時快取資料庫中的各類資料,以達到減少前端業務對資料庫的直接高併發訪問,從而提升大規模網站叢集中動態服務的併發訪問能力。

1.3 Memcached 常見用途工作流程

  • Memcached 是一種記憶體快取軟體,在工作中經常用來快取資料庫的查詢資料,資料被快取在事先預分配的 Memcached 管理的記憶體中,可以通過 API 或命令的方式存取記憶體中快取的這些資料,Memcached 服務記憶體中快取的資料就像一張巨大的 hash 表,每一條資料都是以 key-value 對的形式存在。

1.4 網站讀取 Memcached 資料時工作流程

  • 使用 Memcached 快取查詢資料來減少資料庫壓力的具體工作流程如下:
    • Web 程式首先檢查客戶端請求的資料是否在 Memcached 快取中存在,如果存在,直接把請求的資料返回給客戶端,此時不再請求後端資料庫。
    • 如果請求的資料在 Memcached 快取中不存在,則程式會去請求你資料庫服務,把從資料庫中取到的資料返回給客戶端,同時把新到的資料快取一份到 Memcached 快取中。

1.5 網站更新 Memcached 資料時的工作原理

  • 當程式更新或刪除資料時,會首先處理後端資料庫中的資料。
  • 在處理後端資料庫中資料的同時,也會通知 Memcached,告訴它對應的舊資料失效,從而保證 Memcached 中快取的資料始終和資料庫中的一致,這個資料一致性非常重要,也是大型網站分散式快取叢集的關注問題。
  • 如果是在高併發讀寫場合,除了要程式通知 Memcached 過期的快取失效外,還可能要通過相關機制,例如在資料庫上部署相關程式(如在資料庫中設定觸發器使用 UDFs),實現當資料庫有更新時就把資料更新到 Memcached 服務中,這樣一來,客戶端在訪問新資料時,因預先把更新過的資料庫資料複製到 Memcached 中快取起來了,所以可以減少第一次查詢資料庫帶來的訪問壓力,提升 Memcached 中快取的命中率。還可把持久化儲存 Redis 做成 MySQL 資料庫的從庫,實現真正的主從複製。

1.6 Memcached 的特點

  • 協議簡單。採用的是基於文字行的協議,能通過 telnet/nc 等命令直接操作 Memcached 服務存取資料。

  • 支援 epoll/kqueue 非同步 I/O 模型,使用 libevent 作為時間處理通知機制。

    • 簡單的說,libevent 是一套利用 C 開發的程式庫,它將 BSD 系統的 kqueue、Linux 系統的 epoll 等事件處理功能封裝成一個介面,確保即使伺服器端的連線數增加也能發揮很好的效能。
  • 採用 key/value 鍵值資料型別。

  • 全記憶體快取,效率高。

    • Memcached 管理記憶體的方式非常高效,即全部的資料都存放於 Memcached 服務事先分配好的記憶體中,無持久化儲存的設計,和系統的實體記憶體一樣,當重啟系統或 Memcached 服務時,Memcached 記憶體中的資料就會丟失。如果希望重啟後,資料依然能保留,那麼就可以採用 Redis 這樣的永續性記憶體快取系統。
    • 當記憶體中快取的資料容量達到服務啟動時設定的記憶體值時,就會自動使用 LRU 演算法刪除過期的快取資料。也可以在存放資料時對儲存的資料設定過期時間,這樣過期後資料就自動被清除,Memcached 服務本身不會監控資料過期,而是在訪問的時候檢視 key 的時間戳判斷是否過期。
  • 可支援分散式叢集

    • Memcached 沒有像 MySQL 那樣的主從複製方式,分散式 Memcached 叢集的不同伺服器之間是互不通訊的,每一個節點都獨立存取資料,並且資料內容也不一樣。通過對 web 應用端的程式設計或者通過支援 hash 演算法的負載均衡軟體,可以讓 Memcached 支援大規模海量分散式快取叢集應用。

1.7 Memcached 記憶體管理機制

  • Mc 早期記憶體管理機制為 malloc(動態記憶體分配)。
  • malloc(動態記憶體分配)產生記憶體碎片,導致作業系統效能急劇下降。
  • Slab 記憶體分配機制可以解決記憶體碎片問題。
  • Memcached 服務的記憶體預先分割成特定長度的記憶體塊,稱為 chunk,用於快取資料的記憶體空間或記憶體塊,相當於磁碟的 block,只不過一個磁碟的每一個 block 都是相等的,而 chunk 只有在同一個 Slab Class 內才是相等的。
  • Slab Class 指特定大小(MB)的包含多個 chunk 的集合或組,一個 Memcached 包含多個 Slab Class,每個 Slab Class 包含多個相同大小的 chunk。

1.8 Memcached 的檢測過期與刪除機制

  • 不主動檢測 item 物件是否過期,而是在 get 時才會檢查 item 物件是否過期以及是否應該刪除。
  • 當刪除 item 物件時,一般不釋放記憶體空間,而是做刪除標記,將指標放入slot 回收插槽,下次分配的時候直接使用。
  • 當記憶體空間滿的時候,將會根據 LRU 演算法把最近最少使用的 item 物件刪除。
  • 資料存入可以設定過期時間,但是資料過期後不會被立即刪除,而是在 get 時檢查 item 物件是否過期以及是否應該刪除。
  • 如果不希望系統使用 LRU 演算法清除資料,可以使用 -M 引數。

2. Memcached 服務安裝

2.1 安裝 libevent 及連線 Memcached 工具 nc

  • 系統安裝環境如下:
[[email protected] ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[[email protected] ~]# uname -m
x86_64
[[email protected] ~]# uname -r
3.10.0-693.el7.x86_64
  • 安裝 libevent
[[email protected] ~]# yum install -y libevent libevent-devel nc
[[email protected] ~]# rpm -qa libevent libevent-devel nc
libevent-devel-2.0.21-4.el7.x86_64
libevent-2.0.21-4.el7.x86_64

2.2 安裝 Memcached

[[email protected] ~]# yum install -y memcached
[[email protected] ~]# rpm -qa memcached
memcached-1.4.15-10.el7_3.1.x86_64

3. Memcached 服務的基本管理

3.1 啟動 Memcached

  • 啟動命令如下:
[[email protected] ~]# which memcached
/bin/memcached
[[email protected] ~]# memcached -m -16m -p 11211 -d -u root -c 8192
  • 檢查啟動結果
[[email protected] ~]# lsof -i :11211
COMMAND   PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
memcached 945 memcached   26u  IPv4  18588      0t0  TCP *:memcache (LISTEN)
memcached 945 memcached   27u  IPv6  18589      0t0  TCP *:memcache (LISTEN)
memcached 945 memcached   28u  IPv4  18592      0t0  UDP *:memcache
memcached 945 memcached   29u  IPv6  18593      0t0  UDP *:memcache
[[email protected] ~]# ps -ef|grep memcached|grep -v grep
memcach+    945      1  0 20:34 ?        00:00:00 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024
  • 將上述啟動命令放入 /etc/rc.local
[[email protected] ~]# vim /etc/rc.local
[[email protected] ~]# tail -2 /etc/rc.local
#start up memcached by ylt at 20181012
memcached -m -16m -p 11211 -d -u root -c 8192

3.2 向 Memcached 中寫入資料並檢查

通過 printf

  • 通過 printf 配合 nc 向 Memcached 中寫入資料:
[[email protected] ~]# printf "set key1 0 0 3\r\nylt\r\n"|nc 127.0.0.1 11211
STORED
  • 通過 printf 配合 nc 向 Memcached 中讀取資料:
[[email protected] ~]# printf "get key1\r\n"|nc 127.0.0.1 11211
VALUE key1 0 3
ylt
END
  • 通過 printf 配合 nc 向 Memcached 中刪除資料:
[[email protected] ~]# printf "delete key1\r\n"|nc 127.0.0.1 11211
DELETED

通過 Telnet

  • 安裝 telnet 工具
[[email protected] ~]# yum install telnet -y
[[email protected] ~]# rpm -qa telnet
telnet-0.17-64.el7.x86_64
  • 通過 telnet 向 Memcached 中寫入資料
[[email protected] ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set user01 0 0 4
ylt1
STORED
get user01
VALUE user01 0 4
ylt1
END
delete user01
DELETED
quit
Connection closed by foreign host.

3.3 關閉 Memcached

  • 單例項關閉 Memcached 的方法如下:
[[email protected] ~]# ps -ef|grep memcache|grep -v grep
memcach+    945      1  0 20:34 ?        00:00:00 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024
[[email protected] ~]# killall memcached 或 pkill memcached
  • 若啟動了多個例項 Memcached,使用 killall 或 pkill 方式就會同時關閉這些例項。因此最好在啟動時增加 -P 引數指定固定的 pid 檔案,這樣便於管理不同的例項。
[[email protected] ~]# memcached -m -16m -p 11211 -d -u root -c 8192 -P /var/run/11211.pid
[[email protected] ~]# memcached -m -16m -p 11212 -d -u root -c 8192 -P /var/run/11212.pid
[[email protected] ~]# ps -ef|grep memcache|grep -v grep
root       1781      1  0 20:58 ?        00:00:00 memcached -m -16m -p 11211 -d -u root -c 8192 -P /var/run/11211.pid
root       1788      1  0 20:58 ?        00:00:00 memcached -m -16m -p 11212 -d -u root -c 8192 -P /var/run/11212.pid
  • 此時,即可通過 kill 命令關閉 Memcached
[[email protected] ~]# kill `cat /var/run/11211.pid`
[[email protected] ~]# lsof -i:11211
[[email protected] ~]# lsof -i:11212
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
memcached 1788 root   26u  IPv4  23322      0t0  TCP *:11212 (LISTEN)
memcached 1788 root   27u  IPv6  23323      0t0  TCP *:11212 (LISTEN)
memcached 1788 root   28u  IPv4  23326      0t0  UDP *:11212
memcached 1788 root   29u  IPv6  23327      0t0  UDP *:11212
  • 關閉 Memcached 的方法小結
ps -ef|grep memcache|grep -v grep|awk '{print $2}'|xargs kill
kill `cat /var/run/11211.pid`
killall memcached
pkill memcached

4. 安裝 Memcached 客戶端

4.1 Memcached 快取 PHP 擴充套件外掛安裝

[[email protected] tools]# git clone https://github.com/websupport-sk/pecl-memcache memcache
[[email protected] tools]# cd memcache/
[[email protected] memcache]# /application/php/bin/phpize
Configuring for:
PHP Api Version:         20160303
Zend Module Api No:      20160303
Zend Extension Api No:   320160303
[[email protected] memcache]# ./configure --enable-memcache --with-php-config=/application/php/bin/php-config
[[email protected] memcache]# make
[[email protected] memcache]# make install
Installing shared extensions:     /application/php-7.1.22/lib/php/extensions/no-debug-non-zts-20160303/
[[email protected] tools]# ll /application/php/lib/php/extensions/no-debug-non-zts-20160303/
-rwxr-xr-x 1 root root  508496 Oct 12 22:54 memcache.so

4.2 配置 Memcached 客戶端,使其生效

  • 修改 PHP 的配置檔案 php.ini,加入 Memcached 客戶端的配置
[[email protected] tools]# cd /application/php/lib
[[email protected] lib]# vim php.ini
[[email protected] lib]# tail -2 php.ini
extension_dir = "/application/php/lib/php/extensions/no-debug-non-zts-20160303/"
extension=memcache.so

4.3 重啟 php fpm 服務使 PHP 的配置修改生效

  • 檢查 php-fpm 語法
[[email protected] ~]# /application/php/sbin/php-fpm -t
[12-Oct-2018 21:00:48] NOTICE: configuration file /application/php-7.1.22/etc/php-fpm.conf test is successful
  • 重啟 fpm
[[email protected] ~]# pkill php-fpm
[[email protected] ~]# ps -ef|grep php-fpm|grep -v grep
[[email protected] ~]# /application/php/sbin/php-fpm
[[email protected] ~]# ps -ef|grep php-fpm|grep -v grep
root       1815      1  0 21:00 ?        00:00:00 php-fpm: master process (/application/php-7.1.22/etc/php-fpm.conf)
nginx      1816   1815  0 21:00 ?        00:00:00 php-fpm: pool www
nginx      1817   1815  0 21:00 ?        00:00:00 php-fpm: pool www
  • 開啟瀏覽器訪問 phpinfo 頁面,出現下圖則表示 Memcached 客戶端安裝成功

Memcache

4.4 編寫測試 Memcached 服務的 PHP 指令碼

[[email protected] blog]# cat -n op_mem.php
     1  <?php
     2          $memcache = new Memcache;
     3          $memcache->connect('192.168.2.135', 11211) or die ("Could not connect Mc server");
     4          $memcache->set('key', 'ylt book');
     5          $get= $memcache->get('key');
     6          echo $get;
     7  ?>
  • 測試
[[email protected] blog]# /application/php/bin/php op_mem.php
ylt book

5 Memcached 應用管理

5.1 通過命令管理 Memcached

通過指令碼模擬使用者插入及刪除資料來監控 Memcached 服務是否正常

  • 指令碼內容如下:
[[email protected] ~]# cat -n mon_mc.sh
     1  #!bin/sh
     2  export MemcachedIp=$1
     3  export MemcachedPort=$2
     4  export NcCmd="nc $MemcachedIp $MemcachedPort"
     5  export MD5=3fe396c01f03425cb5e2da8186eb090d
     6  USAGE(){
     7          echo "$0 MemcachedIp MemcachePort"
     8          exit 3
     9  }
    10  [ $# -ne 2 ] && USAGE
    11  printf "set $MD5 0 0 6\r\noldboy\r\n"|$NcCmd >/dev/null 2>&1
    12  if [ $? -eq 0 ];then
    13          if [ `printf "get $MD5\r\n"|$NcCmd|grep oldboy|wc -l` -eq 1 ];then
    14                  echo "Memcached status is ok"
    15                  printf "delete $MD5\r\n"|$NcCmd >/dev/null 2>&1
    16                  exit 0
    17          else
    18                  echo "Memcached status is error1"
    19                  exit 2
    20          fi
    21  else
    22                  echo "Could not connect Mc server"
    23                  exit 2
    24  fi
  • Memcached 服務正常的情況下,測試檢驗指令碼
[[email protected] ~]# sh mon_mc.sh 127.0.0.1 11211
Memcached status is ok
  • 然後關閉 Memcached 服務,測試檢驗指令碼
[[email protected] ~]# pkill memcached
[[email protected] ~]# lsof -i:11211
[[email protected] ~]# sh mon_mc.sh 127.0.0.1 11211
Could not connect Mc server
  • 最後開啟 Memcached 服務,測試檢驗指令碼
[[email protected] ~]# memcached -m -16m -p 11211 -d -u root -c 8192 -P /var/run/11211.pid
[[email protected] ~]# sh mon_mc.sh 127.0.0.1 11211
Memcached status is ok

通過 nc 命令檢視 Memcached 服務的執行狀態資訊

[[email protected] ~]# printf "stats\r\n"|nc 127.0.0.1 11211
STAT pid 11025
STAT uptime 110
STAT time 1539360955
STAT version 1.4.15
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.004133
STAT rusage_system 0.008266
STAT curr_connections 10
STAT total_connections 15
STAT connection_structures 11
STAT reserved_fds 20
STAT cmd_get 1
STAT cmd_set 1
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 1
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 1
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 146
STAT bytes_written 81
STAT limit_maxbytes 18446744073692774400
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT bytes 0
STAT curr_items 0
STAT total_items 1
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 0
END