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服务)

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

  • 相关阅读:
    佛洛依德
    Python2.7利用Tesseract进行中英文图像识别
    批量生成二维码打包成exe文件
    python基础5—文件 | json序列化
    python基础6—(高阶,匿名,偏)函数 | 装饰器
    python基础4—面向对象
    python基础2—集合框架
    一不小心翻车了-(angularjs 1.6X) 由Eventbus使用异常说起
    简单说下js闭包之setTimeout
    html5上传本地图片,在线预览及裁剪(filereader,canvas)
  • 原文地址:https://www.cnblogs.com/573734817pc/p/10130814.html
Copyright © 2011-2022 走看看