zoukankan      html  css  js  c++  java
  • Memcached缓存服务器

    MemCache 是一个自由、源码开放、高性能、分布式的分布式内存对象缓存系统,用于动态 Web 应用以减轻数据库的负载。它通过在内存中缓存数据和对象来减少读取数据库的次数, 从而提高了网站访问的速度。 MemCaChe 是一个存储键值对的 HashMap,在内存中对任意 的数据(比如字符串、对象等)所使用的 key-value 存储,数据可以来自数据库调用、API 调用,或者页面渲染的结果。MemCache 设计理念就是小而强大,它简单的设计促进了快速 部署、易于开发并解决面对大规模的数据缓存的许多难题,而所开放的 API 使得 MemCache 能用于 Java、C/C++/C#、Perl、Python、PHP、Ruby 等大部分流行的程序语言。

    另外,说一下为什么会有 Memcache 和 memcached 两种名称?

    其实 Memcache 是这个项目 的名称,而 memcached 是它服务器端的主程序文件名

    MemCache 的官方网站为 http://memcached.org/

    MemCache 访问模型

    为了加深对 memcache 的理解,以 memcache 为代表的分布式缓存,访问模型如下:

    特别澄清一个问题,MemCache 虽然被称为”分布式缓存”,但是 MemCache 本身完全不具备 分布式的功能,

    MemCache 集群之间不会相互通信(与之形成对比的,比如 JBoss Cache,某 台服务器有缓存数据更新时,会通知集群中其他机器更新缓存或清除缓存数据),所谓的” 分布式”,完全依赖于客户端程序的实现,

    就像上面这张图的流程一样。 同时基于这张图,理一下 MemCache 一次写缓存的流程:

    1、应用程序输入需要写缓存的数据

    2、API 将 Key 输入路由算法模块,路由算法根据 Key 和 MemCache 集群服务器列表得到一 台服务器编号

    3、由服务器编号得到 MemCache 及其的 ip 地址和端口号

    4、API 调用通信模块和指定编号的服务器通信,将数据写入该服务器,完成一次分布式缓 存的写操作 读缓存和写缓存一样,只要使用相同的路由算法和服务器列表,只要应用程序查询的是相同 的 Key,MemCache 客户端总是访问相同的客户端去读取数据,只要服务器中还缓存着该数 据,就能保证缓存命中。

    这种 MemCache 集群的方式也是从分区容错性的方面考虑的,假如 Node2 宕机了,那么 Node2 上面存储的数据都不可用了,此时由于集群中 Node0 和 Node1 还存在,下一次请求 Node2 中存储的 Key 值的时候,肯定是没有命中的,这时先从数据库中拿到要缓存的数据, 然后路由算法模块根据 Key 值在 Node0 和 Node1 中选取一个节点,把对应的数据放进去, 这样下一次就又可以走缓存了,这种集群的做法很好,但是缺点是成本比较大。

    一致性 Hash 算法 从上面的图中,可以看出一个很重要的问题,就是对服务器集群的管理,路由算法至关重要, 就和负载均衡算法一样,路由算法决定着究竟该访问集群中的哪台服务器,先看一个简单的 路由算法。

    1、余数 Hash 简单的路由算法可以使用余数 Hash:用服务器数目和缓存数据 KEY 的 hash 值相除,余数为服 务器列表下标编号,假如某个 str 对应的 HashCode 是 52、服务器的数目是 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)通过模拟请求的方式逐渐预热缓存,使缓存服务器中的数据重新分布

    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 的数据存放在内存中

    1、访问数据的速度比传统的关系型数据库要快,因为 Oracle、MySQL 这些传统的关系型数 据库为了保持数据的持久性,数据存放在硬盘中,IO 操作速度慢

    2、MemCache 的数据存放在内存中同时意味着只要 MemCache 重启了,数据就会消失

    3、既然 MemCache 的数据存放在内存中,那么势必受到机器位数的限制,32 位机器最多只 能使用 2GB 的内存空间,64 位机器可以认为没有上限 然后我们来看一下 MemCache 的原理,MemCache 最重要的是内存如何分配的,MemCache 采用的内存分配方式是固定空间分配,如下图所示:

     

     

    二、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

    1、安装 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

    2、安装 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 

    3、安装 mysql 在239.129之前有安装配置,省略,自己装

    4、安装 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

    5、配置 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 测试页

    6、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 扩展是否正确安装

    1、[root@www html]# /usr/local/php5.6/bin/php -m

    2、创建 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

    7、测试 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 需要重新从数据库中 取得数据

     

    实验:

    1、安装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

    2、安装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

    3、安装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服务)

    4、安装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的变化情况。

    5、验证:

    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的缺点:当主缓存节点当掉又恢复,之前的缓存数据会丢失。

     

  • 相关阅读:
    关于开源的RTP——jrtplib的使用
    常见hash算法的原理
    cocos2dx触屏响应(单点触摸)CCTouchBegan,CCTouchMove,CCTouchEnd
    SD卡中FAT32文件格式高速入门(图文具体介绍)
    HDU 4916 树形dp
    图像识别技术
    shell语法简单介绍
    MATLAB新手教程
    java堆栈 (转)
    给字符数组赋值的方法
  • 原文地址:https://www.cnblogs.com/ljl1366136/p/9562818.html
Copyright © 2011-2022 走看看