nginx+php+memcache實現hash一致性memcache 集羣

咱們工做中可能會遇到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服務)

 

獲得以上結果,表明咱們配置成功。

相關文章
相關標籤/搜索