zoukankan      html  css  js  c++  java
  • nginx+php+memcache实现hash一致性memcache 集群

    我们工作中可能会遇到key-value数据库,如果我们面对的不止一台memcache服务器,而是很多台。那么现在就回出现一个问题:

    当我们访问nginx服务器的时候,我们会判断memcache中是否有相应的值,如果没有我们就从数据库中读取数据,但是这个时候我们该在那一台memcache服务器读取,又应该在那一台memcache服务器存储呢?

    假设我们有1/2/3/4/5台memcache服务器,我们第一次访问nginx,所有memcache服务器都没有相应的存储。

    那么我们就应该要从关系型数据库读取数据,并保存到memcache服务器。

    假设,保存到1号服务器。

    现在,我们用和第一次访问参数一样的url进行nginx访问,那么现在要从哪一个memcache服务器读取呢。nginx默认的集群算法为“取模”,也就是循环使用。

    也就是第二次的访问,应该是到2号服务器上读取,但是我们存储的数据却在1号memcache服务器。这个时候就读不到了,所以,我们又会在2号memcache中存储相应的值。这就不行了。

    我们希望达到的效果为,相同的参数的url访问nignx和memcache的时候,我们读取和存储的memcache是同一台。

    这就需要用到我们的hash一致性算法来解决了。

    mysql数据库为:

    以下是我们的解决步骤:

    1、首先,我们需要在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

    2、编辑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;
    }

    3、将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 

    4、编写我们的额回调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服务)

    得到以上结果,代表我们配置成功。

  • 相关阅读:
    Java实现 洛谷 P1060 开心的金明
    (Java实现) 洛谷 P1605 迷宫
    (Java实现) 洛谷 P1605 迷宫
    (Java实现)洛谷 P1093 奖学金
    (Java实现)洛谷 P1093 奖学金
    Java实现 洛谷 P1064 金明的预算方案
    Java实现 洛谷 P1064 金明的预算方案
    (Java实现) 洛谷 P1031 均分纸牌
    QT树莓派交叉编译环开发环境搭建(附多个exe工具下载链接)
    武则天红人对唐睿宗的桃色报复(如此缺少城府,注定了要在宫廷中过早地出局)
  • 原文地址:https://www.cnblogs.com/573734817pc/p/10130814.html
Copyright © 2011-2022 走看看