MemCache 是一個自由、源碼開放、高性能、分佈式的分佈式內存對象緩存系統,用於動態 Web 應用以減輕數據庫的負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數, 從而提升了網站訪問的速度。 MemCaChe 是一個存儲鍵值對的 HashMap,在內存中對任意 的數據(好比字符串、對象等)所使用的 key-value 存儲,數據能夠來自數據庫調用、API 調用,或者頁面渲染的結果。MemCache 設計理念就是小而強大,它簡單的設計促進了快速 部署、易於開發並解決面對大規模的數據緩存的許多難題,而所開放的 API 使得 MemCache 能用於 Java、C/C++/C#、Perl、Python、PHP、Ruby 等大部分流行的程序語言。javascript
另外,說一下爲何會有 Memcache 和 memcached 兩種名稱?php
其實 Memcache 是這個項目 的名稱,而 memcached 是它服務器端的主程序文件名css
MemCache 的官方網站爲 http://memcached.org/html
MemCache 訪問模型java
爲了加深對 memcache 的理解,以 memcache 爲表明的分佈式緩存,訪問模型以下:mysql
特別澄清一個問題,MemCache 雖然被稱爲」分佈式緩存」,可是 MemCache 自己徹底不具有 分佈式的功能,nginx
MemCache 集羣之間不會相互通訊(與之造成對比的,好比 JBoss Cache,某 臺服務器有緩存數據更新時,會通知集羣中其餘機器更新緩存或清除緩存數據),所謂的」 分佈式」,徹底依賴於客戶端程序的實現,c++
就像上面這張圖的流程同樣。 同時基於這張圖,理一下 MemCache 一次寫緩存的流程:web
一、應用程序輸入須要寫緩存的數據算法
二、API 將 Key 輸入路由算法模塊,路由算法根據 Key 和 MemCache 集羣服務器列表獲得一 臺服務器編號
三、由服務器編號獲得 MemCache 及其的 ip 地址和端口號
四、API 調用通訊模塊和指定編號的服務器通訊,將數據寫入該服務器,完成一次分佈式緩 存的寫操做 讀緩存和寫緩存同樣,只要使用相同的路由算法和服務器列表,只要應用程序查詢的是相同 的 Key,MemCache 客戶端老是訪問相同的客戶端去讀取數據,只要服務器中還緩存着該數 據,就能保證緩存命中。
這種 MemCache 集羣的方式也是從分區容錯性的方面考慮的,假如 Node2 宕機了,那麼 Node2 上面存儲的數據都不可用了,此時因爲集羣中 Node0 和 Node1 還存在,下一次請求 Node2 中存儲的 Key 值的時候,確定是沒有命中的,這時先從數據庫中拿到要緩存的數據, 而後路由算法模塊根據 Key 值在 Node0 和 Node1 中選取一個節點,把對應的數據放進去, 這樣下一次就又能夠走緩存了,這種集羣的作法很好,可是缺點是成本比較大。
一致性 Hash 算法 從上面的圖中,能夠看出一個很重要的問題,就是對服務器集羣的管理,路由算法相當重要, 就和負載均衡算法同樣,路由算法決定着究竟該訪問集羣中的哪臺服務器,先看一個簡單的 路由算法。
一、餘數 Hash 簡單的路由算法可使用餘數 Hash:用服務器數目和緩存數據 KEY 的 hash 值相除,餘數爲服 務器列表下標編號,假如某個 str 對應的 HashCode 是 5二、服務器的數目是 3,取餘數獲得 1, str 對應節點 Node1,因此路由算法把 str 路由到 Node1 服務器上。因爲 HashCode 隨機性比 較強,因此使用餘數 Hash 路由算法就能夠保證緩存數據在整個 MemCache 服務器集羣中有 比較均衡的分佈。 若是不考慮服務器集羣的伸縮性,那麼餘數 Hash 算法幾乎能夠知足絕大多數的緩存路由需 求,可是當分佈式緩存集羣須要擴容的時候,就難辦了。 就假設 MemCache 服務器集羣由 3 臺變爲 4 臺吧,更改服務器列表,仍然使用餘數 Hash, 52 對 4 的餘數是 0,對應 Node0,可是 str 原來是存在 Node1 上的,這就致使了緩存沒有命 中。再舉個例子,原來有 HashCode 爲 0~19 的 20 個數據,那麼: 那麼不妨舉個例子,原來有 HashCode 爲 0~19 的 20 個數據,那麼:
如今擴容到 4 臺,加粗標紅的表示命中:
若是擴容到 20+的臺數,只有前三個 HashCode 對應的 Key 是命中的,也就是 15%。固然現 實狀況確定比這個複雜得多,不過足以說明,使用餘數 Hash 的路由算法,在擴容的時候會 形成大量的數據沒法正確命中(其實不只僅是沒法命中,那些大量的沒法命中的數據還在原 緩存中在被移除前佔據着內存)。在網站業務中,大部分的業務數據度操做請求上事實上是 經過緩存獲取的,只有少許讀操做會訪問數據庫,所以數據庫的負載能力是以有緩存爲前提 而設計的。當大部分被緩存了的數據由於服務器擴容而不能正確讀取時,這些數據訪問的壓 力就落在了數據庫的身上,這將大大超過數據庫的負載能力,嚴重的可能會致使數據庫宕機。
這個問題有解決方案,解決步驟爲:
(1)在網站訪問量低谷,一般是深夜,技術團隊加班,擴容、重啓服務器
(2)經過模擬請求的方式逐漸預熱緩存,使緩存服務器中的數據從新分佈
二、一致性 Hash 算法
一致性 Hash 算法經過一個叫作一致性 Hash 環的數據結構實現 Key 到緩存服務器的 Hash 映 射。簡單地說,一致性哈希將整個哈希值空間組織成一個虛擬的圓環(這個環被稱爲一致性 Hash 環),如假設某空間哈希函數 H 的值空間是 0~2^32 -1(即哈希值是一個 32 位無符號整 形),整個哈希空間以下:
下一步將各個服務器使用 H 進行一個哈希計算,具體可使用服務器的 IP 地址或者主機名 做爲關鍵字,這樣每臺機器能肯定其在上面的哈希環上的位置了,而且是按照順時針排列, 這裏咱們假設三臺節點 memcache 經計算後位置以下
接下來使用相同算法計算出數據的哈希值 h,並由此肯定數據在此哈希環上的位置 假如咱們有數據 A、B、C、D、4 個對象,通過哈希計算後位置以下:
根據一致性哈希算法,數據 A 就被綁定到了 server01 上,D 被綁定到了 server02 上,B、C 在 server03 上,是按照順時針找最近服務節點方法 這樣獲得的哈希環調度方法,有很高的容錯性和可擴展性: 假設 server03 宕機
能夠看到此時 C、B 會受到影響,將 B、C 節點被重定位到 Server01。通常的,在一致性哈希 算法中,若是一臺服務器不可用,則受影響的數據僅僅是此服務器到其環空間中前一臺服務 器(即順着逆時針方向行走遇到的第一臺服務器)之間數據,其它不會受到影響。 考慮另一種狀況,若是咱們在系統中增長一臺服務器 Memcached Server 04:
此時 A、D、C 不受影響,只有 B 須要重定位到新的 Server04。通常的,在一致性哈希算法 中,若是增長一臺服務器,則受影響的數據僅僅是新服務器到其環空間中前一臺服務器(即 順着逆時針方向行走遇到的第一臺服務器)之間數據,其它不會受到影響。 綜上所述,一致性哈希算法對於節點的增減都只需重定位環空間中的一小部分數據,具備較 好的容錯性和可擴展性。
一致性哈希的缺點:
在服務節點太少時,容易由於節點分部不均勻而形成數據傾斜問題。我 們能夠採用增長虛擬節點的方式解決。 更重要的是,集羣中緩存服務器節點越多,增長/減小節點帶來的影響越小,很好理解。換 句話說,隨着集羣規模的增大,繼續命中原有緩存數據的機率會愈來愈大,雖然仍然有小部 分數據緩存在服務器中不能被讀到,可是這個比例足夠小,即便訪問數據庫,也不會對數據 庫形成致命的負載壓力。
MemCache 實現原理
首先要說明一點,MemCache 的數據存放在內存中
一、訪問數據的速度比傳統的關係型數據庫要快,由於 Oracle、MySQL 這些傳統的關係型數 據庫爲了保持數據的持久性,數據存放在硬盤中,IO 操做速度慢
二、MemCache 的數據存放在內存中同時意味着只要 MemCache 重啓了,數據就會消失
三、既然 MemCache 的數據存放在內存中,那麼勢必受到機器位數的限制,32 位機器最多隻 能使用 2GB 的內存空間,64 位機器能夠認爲沒有上限 而後咱們來看一下 MemCache 的原理,MemCache 最重要的是內存如何分配的,MemCache 採用的內存分配方式是固定空間分配,以下圖所示:
2、centos7.2+(nginx+php)+memcache+mysql
環境描述:
OS:
[root@www ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
nginx 和 php:
nginx-1.10.2.tar.gz
php-5.6.27.tar.gz
ip 地址:192.168.239.133/24
memcache:
memcached-1.4.33.tar.gz
ip 地址:192.168.239.143/24
mysql:
mysql-5.7.13.tar.gz
ip地址:192.168.239.129/24
一、安裝 nginx(在 192.168.239.133 主機操做)
解壓 zlib
[root@www ~]# tar zxf zlib-1.2.8.tar.gz
說明:不須要編譯,只須要解壓就行。
解壓 pcre
[root@www ~]# tar zxf pcre-8.39.tar.gz
說明:不須要編譯,只須要解壓就行。
[root@www ~]# yum -y install gcc gcc-c++ make libtool openssl openssl-devel
下載 nginx 的源碼包:http://nginx.org/download
解壓源碼包:
[root@www ~]# tar zxf nginx-1.10.2.tar.gz
[root@www ~]# cd nginx-1.10.2/
[root@www ~]# groupadd www #添加 www 組
[root@www ~]# useradd -g www www -s /sbin/nologin #建立 nginx 運行帳戶 www 並加入到 www 組,不容許 www 用戶直接登陸系統
[root@www nginx-1.10.2]# ./configure --prefix=/usr/local/nginx
--with-http_dav_module --with-http_stub_status_module
--with-http_addition_module --with-http_sub_module
--with-http_flv_module --with-http_mp4_module
--with-pcre=/root/pcre-8.39 --with-zlib=/root/zlib-1.2.8 (這兩個包注意看路徑在哪,默認/root)
--with-http_ssl_module--with-http_gzip_static_module --user=www
--group=www
[root@www nginx-1.10.2]# make&& make install
注: --with-pcre:用來設置 pcre 的源碼目錄。
--with-zlib:用來設置 zlib 的源碼目錄。
由於編譯 nginx 須要用到這兩個庫的源碼。
[root@www nginx-1.10.2]# ln -s /usr/local/nginx/sbin/* /usr/local/sbin/
[root@www nginx-1.10.2]# nginx -t
啓動 nginx [root@www nginx-1.10.2]# nginx
[root@www nginx-1.10.2]# netstat -anpt | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 9834/nginx: master
[root@www nginx-1.10.2]# firewall-cmd --permanent --add-port=80/tcp
success
[root@www nginx-1.10.2]# firewall-cmd --reload
二、安裝 php
安裝 libmcrypt
[root@www ~]# tar zxf libmcrypt-2.5.7.tar.gz
[root@www ~]# cd libmcrypt-2.5.7/
[root@www libmcrypt-2.5.7]# ./configure --prefix=/usr/local/libmcrypt && make && make install
[root@www ~]# yum -y install libxml2-devel libcurl-devel openssl-devel bzip2-devel
[root@www ~]# tar zxf php-5.6.27.tar.gz
[root@www ~]# cd php-5.6.27/
[root@www php-5.6.27]#./configure --prefix=/usr/local/php5.6 --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --with-openssl --enable-fpm --enable-sockets --enable-sysvshm --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --with-mhash --with-mcrypt=/usr/local/libmcrypt --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2 --enable-maintainer-zts
[root@www php-5.6.27]# make && make install
[root@www php-5.6.27]# cp php.ini-production /etc/php.ini
建立 php-fpm 服務啓動腳本:
[root@www php-5.6.27]# cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
[root@www php-5.6.27]# chmod +x /etc/init.d/php-fpm
[root@www php-5.6.27]# chkconfig --add php-fpm
[root@www php-5.6.27]# chkconfig php-fpm on
提供 php-fpm 配置文件並編輯:
cp /usr/local/php5.6/etc/php-fpm.conf.default /usr/local/php5.6/etc/php-fpm.conf
[root@www php-5.6.27]# vi /usr/local/php5.6/etc/php-fpm.conf
修改內容以下:
pid = run/php-fpm.pid
listen =127.0.0.1:9000
pm.max_children = 300
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers =50
啓動 php-fpm 服務:
[root@phpserver ~]# service php-fpm start
Starting php-fpm done
[root@www php-5.6.27]# netstat -anpt | grep php-fpm
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 10937/php-fpm: mast
三、安裝 mysql 在239.129 (以前有安裝配置,省略,本身裝)
四、安裝 memcached 服務端(在 192.168.239.143 主機操做)
memcached 是基於 libevent 的事件處理。libevent 是個程序庫,它將 Linux 的 epoll、BSD 類 操做系統的 kqueue 等事件處理功能封裝成統一的接口。即便對服務器的鏈接數增長,也能 發揮 I/O 的性能。 memcached 使用這個 libevent 庫,所以能在 Linux、BSD、Solaris 等操做 系統上發揮其高性能。
首先先安裝 memcached 依賴庫 libevent
[root@memcache ~]# tar zxf libevent-2.0.22-stable.tar.gz
[root@memcache ~]# cd libevent-2.0.22-stable/
[root@memcache libevent-2.0.22-stable]# ./configure
[root@memcache libevent-2.0.22-stable]# make && make install
安裝 memcached
[root@memcache ~]# tar zxf memcached-1.4.33.tar.gz
[root@memcache ~]# cd memcached-1.4.33/
[root@memcache memcached-1.4.33]# ./configure --prefix=/usr/local/memcached --with-libevent=/usr/local
[root@memcache memcached-1.4.33]# make && make install
檢測是否成功安裝
[root@memcache ~]# ls /usr/local/memcached/bin/memcached
經過以上操做就很簡單的把 memcached 服務端編譯好了。這時候就能夠打開服務端進行工做 了。
配置環境變量:
進入用戶宿主目錄,編輯.bash_profile,爲系統環境變量 LD_LIBRARY_PATH 增長新的目錄, 須要增長的內容以下:
[root@memcache ~]# vi ~/.bash_profile
MEMCACHED_HOME=/usr/local/memcached
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MEMCACHED_HOME/lib
[root@memcache ~]# /usr/local/memcached/bin/memcached -d -m 2048 -l 192.168.31.250 -p 11211 -u root -c 10240 -P /usr/local/memcached /memcached.pid
[root@memcache ~]# netstat -anpt |grep memcached
tcp 0 0 192.168.31.250:11211 0.0.0.0:* LISTEN 12840/memcached
設置防火牆:
[root@memcache ~]# firewall-cmd --permanent --add-port=11211/tcp
success
[root@memcache ~]# firewall-cmd --reload
success
刷新用戶環境變量: (可不用)
[root@memcache ~]# source ~/.bash_profile
五、配置 nginx.conf 文件(在 nginx 主機操做)
配置內容以下:
user www www;
worker_processes 2;
worker_cpu_affinity 01 10;
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
worker_rlimit_nofile 10240;
pid logs/nginx.pid;
events {
use epoll;
worker_connections 4096;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'"$upstream_cache_status"';
access_log logs/access.log main;
server_tokens off;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#Compression Settings
gzip on;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_proxied any;
gzip_min_length 1k;
gzip_buffers 16 8k;
gzip_types text/plain text/css text/javascript application/json application/javascript
application/x-javascript application/xml;
gzip_vary on;
#end gzip
#http_proxy Settings
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 75;
proxy_send_timeout 75;
proxy_read_timeout 75;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_buffering on;
proxy_temp_path /usr/local/nginx1.14/proxy_temp;
proxy_cache_path /usr/local/nginx1.14/proxy_cache levels=1:2 keys_zone=my-cache:100m
max_size=1000m inactive=600m max_size=2g;
#load balance Settings
upstream backend {
sticky;
server 192.168.254.130:80 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.254.131:80 weight=1 max_fails=2 fail_timeout=10s;
}
#virtual host Settings
server {
listen 80;
server_name localhost;
charset utf-8;
location ~/purge(/.*) {
allow 127.0.0.1;
allow 192.168.254.0/24;
deny all;
proxy_cache_purge my-cache $host$1$is_args$args;
}
location / {
index index.php index.html index.htm;
proxy_pass http://backend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
location ~ .*\.(gif|jpg|png|html|htm|css|js|ico|swf|pdf)(.*) {
proxy_pass http://backend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_cache my-cache;
add_header Nginx-Cache $upstream_cache_status;
proxy_cache_valid 200 304 301 302 8h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1d;
proxy_cache_key $host$uri$is_args$args;
expires 30d;
}
location /nginx_status {
stub_status on;
access_log off;
allow 192.168.254.0/24;
deny all;
}
}
}
重啓 nginx 服務
生成一個 php 測試頁
[root@www memcache-3.0.8]# cat /usr/local/nginx1.10/html/test.php
<?php
phpinfo();
?>
使用瀏覽器訪問 test.php 測試頁
六、memcache 客戶端(在 php 服務器操做):
memcache 分爲服務端和客戶端。
服務端用來存放緩存,客戶端用來操做緩存。
安裝 memcache 擴展庫
[root@www ~]# tar zxf memcache-3.0.8.tgz
[root@www ~]# cd memcache-3.0.8/
[root@www memcache-3.0.8]# /usr/local/php5.6/bin/phpize
[root@www memcache-3.0.8]#./configure --enable-memcache --with-php-config=/usr/local/php5.6/bin/php-config
[root@www memcache-3.0.8]# make && make install
安裝完後會有相似這樣的提示:
Installing shared extensions:
/usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/
把這個記住,而後修改 php.ini
添加一行
extension=/usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/memcache.so
重啓 php-fpm 服務
[root@www memcache-3.0.8]# service php-fpm restart
Gracefully shutting down php-fpm .done
Starting php-fpm done
測試:
檢查 php 擴展是否正確安裝
一、[root@www html]# /usr/local/php5.6/bin/php -m
二、建立 phpinfo()頁面,查詢 session 項下面的 Registered save handlers 值中是否有 memcache 項
瀏覽器訪問 test1.php
(進入nginx主配 把他註釋)
測試代碼:
[root@www ~]# cat /usr/local/nginx/html/test2.php
<?php
$memcache = new Memcache;
$memcache->connect('192.168.31.250', 11211) or die ("Could not connect");
$version = $memcache->getVersion();
echo "Server's version: ".$version."</br/>";
$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;
$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 10 seconds)<br/>";
$get_result = $memcache->get('key');
echo "Data from the cache:<br/>";
var_dump($get_result);
?>
瀏覽器訪問test2.php
使用 memcache 實現 session 共享
配置 php.ini 中的 Session 爲 memcache 方式。 (第一個修改,下增長)
session.save_handler = memcache
session.save_path = "tcp://192.168.31.250:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
測試 memcache 可用性
在 web 服務器上新建/usr/local/nginx/html/memcache.php 文件。內容如
<?php
session_start();
if (!isset($_SESSION['session_time']))
{
$_SESSION['session_time'] = time();
}
echo "session_time:".$_SESSION['session_time']."";
echo "now_time:".time()."<br/>";
echo "session_id:".session_id()."
"; ?>
如圖所述:
訪問網址 http://192.168.239.133./memcache.php 能夠查看 session_time 是否都是爲 memcache 中的 Session,同時能夠在不一樣的服務器上修改不一樣的標識查看是否爲不一樣的服務器上的。
能夠直接用 sessionid 去 memcached 裏查詢一下:
yum install telnet (默認要裝)
[root@www html]# telnet 192.168.239.143 11211
七、測試 memcache 緩存數據庫數據
在 Mysql 服務器上建立測試表
mysql> create database testdb1;
Query OK, 1 row affected (0.00 sec)
mysql> use testdb1;
Database changed
mysql> create table test1(id int not null auto_increment,name varchar(20) default null,primary key (id)) engine=innodb auto_increment=1 default charset=utf8;
Query OK, 0 rows affected (0.03 sec)
mysql> insert into test1(name) values ('tom1'),('tom2'),('tom3'),('tom4'),('tom5');
Query OK, 5 rows affected (0.01 sec)
測試
下面就是測試的工做了,這裏有個 php 腳本,用於測試 memcache 是否緩存數據成功 須要爲這個腳本添加一個只讀的數據庫用戶,
命令格式
mysql> grant select on testdb1.* to user@'%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
在 web 服務器上建立測試腳本內容以下:
[root@www html]# cat /usr/local/nginx/html/test_db.php
若是出現 mysql 表示 memcached 中沒有內容,須要 memcached 從數據庫中取得 再刷新頁面,若是有 memcache 標誌表示此次的數據是從 memcached 中取得的。 memcached 有個緩存時間默認是 1 分鐘,過了一分鐘後,memcached 須要從新從數據庫中 取得數據
實驗:
一、安裝libevent軟件(四臺)
[root@localhost ~]# tar -zxvf libevent-2.0.22-stable.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/libevent-2.0.22-stabl
[root@localhost libevent-2.0.21-stable]# ./configure --prefix=/usr/
[root@localhost libevent-2.0.21-stable]# make && make install
二、安裝memcached軟件(Memcached服務器 2臺)
[root@localhost ~]# tar -zxvf memcached-1.4.31.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/memcached-1.4.31/
[root@localhost memcached-1.4.31]# ./configure --enable-memcache --with-libevent=/usr/
[root@localhost memcached-1.4.31]# make && make install
主緩存:
[root@localhost ~]# memcached -d -m 1024 -u root -l 192.168.1.201 -p 11211
備緩存:
[root@localhost ~]# memcached -d -m 1024 -u root -l 192.168.1.202 -p 11211
三、安裝magent 軟件(Magent 服務器 2臺)
[root@localhost ~]# mkdir /usr/magent
[root@localhost ~]# tar -zxvf magent-0.6.tar.gz -C /usr/magent/
[root@localhost ~]# cd /usr/magent/
[root@localhost magent]# vim ketama.h
添加(頭部添加):
#ifndef SSIZE_MAX
#define SSIZE_MAX 32767
#endif
[root@localhost magent]# ln -s /usr/lib64/libm.so /usr/lib64/libm.a
[root@localhost magent]# ln -s /usr/lib64/libevent-2.0.so.5 /usr/lib64/libevent.a
[root@localhost magent]# /sbin/ldconfig
[root@localhost magent]# make
[root@localhost magent]# cp magent /usr/bin/
主緩存和備緩存同樣的啓動命令(-l 是漂移IP 尚未搭建Keepalived服務 暫時不要啓動Magent服務)
四、安裝keepalived 軟件(Magent 服務器 2臺)
[root@localhost ~]# yum -y install kernel-devel openssl-devel popt-devel
[root@localhost ~]# tar -zxvf keepalived-1.3.9.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/ keepalived-1.3.9/
[root@localhost keepalived-1.3.9]# ./configure --prefix=/ && make && make install
[root@localhost keepalived-1.3.9]# cp keepalived/etc/init.d/keepalived /etc/init.d/
[root@localhost keepalived-1.3.9]# chkconfig --add keepalived
[root@localhost keepalived-1.3.9]# chkconfig keepalived on
配置主緩存服務器
[root@localhost ~]# vim /etc/keepalived/keepalived.conf
修改:
global_defs {
router_id LVS_DEVEL_R1
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100
}
}
[root@localhost ~]# service keepalived restart
[root@localhost ~]# ip add show dev eth0
配置備緩存服務器
[root@localhost ~]# vim /etc/keepalived/keepalived.conf
修改:
global_defs {
router_id LVS_DEVEL_R2
}
vrrp_instance VI_1 {
state BACKUP
priority 99
......
virtual_ipaddress {
192.168.1.100
}
---其餘參數與主緩存服務器保持一致----
}
[root@localhost ~]# magent -u root -n 51200 -l 192.168.1.10 -p 12000 -s 192.168.1.201:11211 -b 192.168.1.202:11211
[root@localhost ~]# magent -u root -n 51200 -l 192.168.1.10 -p 12000 -s 192.168.1.201:11211 -b 192.168.1.202:11211
-u:用戶
-n:最大鏈接數
-l:magent 對外監聽IP 地址
-p:magent 對外監聽端口
-s:magent 主緩存IP 地址和端口
-b:magent 備緩存IP 地址和端口
[root@localhost ~]# ps -elf | grep magent
[root@localhost ~]# service keepalived restart
[root@localhost ~]# ip add show dev eth0
驗證:
客戶端ping 192.168.1.10 查看VIP的變化狀況。
五、驗證:
1)用主緩存節點鏈接上主緩存的1200端口插入數據
[root@localhost ~]# telnet 192.168.1.10 12000
Trying 192.168.1.10...
Connected to 192.168.1.10.
Escape character is '^]'.
set key 33 0 5
ggggg
STORED
quit
Connection closed by foreign host.
2)查看插入的數據
[root@localhost ~]# telnet 192.168.1.10 12000
Trying 192.168.1.10...
Connected to 192.168.1.10.
Escape character is '^]'.
get key
VALUE key 33 5
ggggg
END
quit
Connection closed by foreign host.
總結:
memcache的優勢:能夠作多主或者多從
memcache的缺點:當主緩存節點當掉又恢復,以前的緩存數據會丟失。