咱們工做中可能會遇到key-value數據庫,若是咱們面對的不止一臺memcache服務器,而是不少臺。那麼如今就回出現一個問題:php
當咱們訪問nginx服務器的時候,咱們會判斷memcache中是否有相應的值,若是沒有咱們就從數據庫中讀取數據,可是這個時候咱們該在那一臺memcache服務器讀取,又應該在那一臺memcache服務器存儲呢?html
假設咱們有1/2/3/4/5臺memcache服務器,咱們第一次訪問nginx,全部memcache服務器都沒有相應的存儲。mysql
那麼咱們就應該要從關係型數據庫讀取數據,並保存到memcache服務器。nginx
假設,保存到1號服務器。git
如今,咱們用和第一次訪問參數同樣的url進行nginx訪問,那麼如今要從哪個memcache服務器讀取呢。nginx默認的集羣算法爲「取模」,也就是循環使用。github
也就是第二次的訪問,應該是到2號服務器上讀取,可是咱們存儲的數據卻在1號memcache服務器。這個時候就讀不到了,因此,咱們又會在2號memcache中存儲相應的值。這就不行了。算法
咱們但願達到的效果爲,相同的參數的url訪問nignx和memcache的時候,咱們讀取和存儲的memcache是同一臺。sql
這就須要用到咱們的hash一致性算法來解決了。數據庫
mysql數據庫爲:服務器
如下是咱們的解決步驟:
一、首先,咱們須要在nginx上添加hash一致性算法模塊。
下載ngx_http_consistent_hash算法插件。
下載地址:https://github.com/replay/ngx_http_consistent_hash
回到nginx安裝包:cd nginx-1.14.2/
make clean
./configure --prefix=/usr/local/nginx --add-module=/usr/installsoft/ngx_http_consistent_hash-master/
咱們的hash插件,是放在/usr/installsoft/文件夾下的。
make && make install
啓動nginx:/usr/local/nginx/sbin/nginx
二、編輯nginx.conf添加紅色部分
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"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
upstream imgserver {
server 111.231.226.228:81 weight=1 max_fails=2 fail_timeout=3;
server 111.231.226.228:82 weight=1 max_fails=2 fail_timeout=3;
}
upstream mcserver {
consistent_hash $request_uri;
server 111.231.226.228:11214;
server 111.231.226.228:11212;
server 111.231.226.228:11213;
}
編輯location,修改紅色部分。
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#以$rui爲memcache hash一致性算法的key
set $memcached_key "$uri";
memcached_pass mcserver;
#若是沒有讀取到,這執行回調callback.php
error_page 404 /callback.php;
# root html;
# index index.php index.html index.htm;
}
三、將php的hash算法改成:consistent
在/usr/local/fastphp/lib/php.ini中添加下面代碼。個人php是安裝在/usr/local/fastphp下的,大家的以本身爲準,上面的nginx同理。
memcache.hash_strategy=consistent
重啓php。先殺了,在啓動。
pkill -9 php-fpm
./sbin/php-fpm
四、編寫咱們的額回調callback.php程序。
<?php
$uri = $_SERVER['REQUEST_URI'];
$uid = substr($uri,5,strpos($uri,'.')-5);
//設置memcache集羣
$mem = new memcache();
$mem->addServer('111.231.226.228',11212);
$mem->addServer('111.231.226.228',11213);
$mem->addServer('111.231.226.228',11214);
//鏈接mysql數據庫
$conn = mysql_connect('127.0.0.1','root','');
$sql = 'use test';
mysql_query($sql,$conn);
$sql = 'set names utf8';
mysql_query($sql,$conn);
$sql = 'select * from user where uid='.$uid;
$rs = mysql_query($sql,$conn);
//echo一下好讓咱們知道是從memcache來的,仍是讀取數據庫來的。
echo 'from mysql query<br />';
$user = mysql_fetch_assoc($rs);
if(empty($user)) {
echo 'no this user';
}else{
$html = '<h1>'.$user['uname'].'</h1>';
echo $html;
//想memcache中添加值。
$mem->add($uri,$html,0,300);
$mem->close();
}
?>
以上步驟都作完後,咱們來看效果:
訪問nginx http 服務器。
第一次訪問/user8.html.從下圖,咱們能夠看到,由於memcache中沒有/html8.html的數據,因此是從mysql數據庫中讀取的。而且是在咱們打開的4號memcache會話框執行的(端口號11214)
咱們進行一次刷新,也就是相同的url再請求一次。有如下結果。咱們能夠看到,這天數據是從memcache中取出來的,而且走的也是4號窗口(11214)。
咱們再來測試一個。獲得相同的結果,可是請求的是,5號窗口(11214端口的memcache服務)
獲得以上結果,表明咱們配置成功。