基于Nginx的Mencached缓存配置详解

简介

memcached是一套分布式的高速缓存系统,memcached缺乏认证以及安全管制,这代表应该将memcached服务器放置在防火墙后。memcached的API使用三十二比特的循环冗余校验(CRC-32)计算键值后,将数据分散在不同的机器上。当表格满了以后,接下来新增的数据会以LRU机制替换掉。由于memcached通常只是当作缓存系统使用,所以使用memcached的应用程序在写回较慢的系统时(像是后端的数据库)需要额外的代码更新memcached内的数据

特征

memcached作为高速运行的分布式缓存服务器,具有以下的特点:

  • 协议简单
  • 基于libevent的事件处理
  • 内置内存存储方式
  • memcached不互相通信的分布式

前期准备

准备三台Centos7虚拟机,配置IP地址和hostname,关闭防火墙和selinux,同步系统时间,修改IP地址和hostname映射

ip hostname
192.168.29.132 master
192.168.29.138 bak
192.168.29.133 mid

master和bak机器部署Nginx和PHP

部署memcache

mid机器部署memcached客户端

[root@mid ~]# yum install memcached -y
#启动服务
[root@mid ~]# systemctl start memcached.service

#查看启动情况,点击回车出现ERROR则启动成功
[root@master ~]# telnet 192.168.29.133 11211
Trying 192.168.29.133...
Connected to 192.168.29.133.
Escape character is '^]'.

ERROR

master和mid机器部署PHP的memcached扩展

下载libmemcached和memcached压缩包

#解压并安装libmemcached
[root@master ~]#tar -xvf libmemcached-1.0.18.tar.gz
[root@master ~]#cd libmemcached-1.0.18
#若编译报错,将clients/memflush.cc中报错相应位置的false改为NULL
[root@master ~]#./configure --prefix=/usr/local/libmemcached
make && make install

#解压并安装memcached
[root@master ~]#tar -zxvf memcached-3.1.5.tgz
[root@master ~]#cd memcached-3.1.5
[root@master ~]#phpize
[root@master ~]#./configure --with-libmemcached-dir=/usr/local/libmemcached --disable-memcached-sasl
[root@master ~]#make && make install

#完成后观察php目录下的lib/php/extensions/no-debug-zts-20170718/是否有扩展
memcached.so

#添加扩展至php配置文件
[root@master ~]# vi /usr/local/php/etc/php.ini
extension=memcached.so

测试验证

[root@master ~]# vi /usr/local/nginx/html/test.php 

访问http://ip/test.php

基于Nginx的Mencached缓存配置详解_第1张图片

注:bak机器进行相同操作

配置缓存

配置Nginx配置文件

[root@master ~]# cat /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
  worker_connections 1024;
}
http {
  include    mime.types;
  default_type application/octet-stream;
  sendfile    on;
  keepalive_timeout 65;
  server {
    listen    80;
    server_name localhost;
    location / {
      root  html;
      index index.html index.htm;
    }
  #memcached缓存配置,有缓存则读取,没有缓存则报404错误
  location /demo/ {
    set $memcached_key $request_uri;
    add_header X-mem-key $memcached_key;
    memcached_pass 192.168.29.133:11211;
    default_type text/html;
    #报错后转到特定Location
    error_page 404 502 504 = @mymemcached;
  }
  #配置重写策略执行特定php文件
  location @mymemcached {
    rewrite .* /demo.php?key=$request_uri;
  }
    location ~ \.php$ {
      root      html;
      fastcgi_pass  127.0.0.1:9000;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      include    fastcgi_params;
    }
  }
}

编写PHP文件设置memcached缓存

#创建demo文件夹
[root@master ~] mkdir /usr/local/nginx/html/demo
#创建测试文件
[root@master ~] echo "123" >> /usr/local/nginx/html/demo/123.html

[root@master ~]# vi /usr/local/nginx/html/demo.php 
addServers($server);
    $r=$m->set($_GET['key'],$data);
    header('Content-Length:'.filesize($fn)."\r\n");
    header('Content-Type:file'."\r\n");
    header('X-cache:MISS:'."\r\n");
    echo $data;
  }
  #不存在demo文件夹则返回首页
  else{
    header('Location:../index.html'."\r\n");
  }
?>

注:bak机器进行相同的设置

测试验证

#可看出第一次memcache中没有缓存,第二次击中缓存
[root@bak ~]# curl -I http://192.168.29.132/demo/123.html
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Thu, 25 Jun 2020 02:23:00 GMT
Content-Type: file
Content-Length: 4
Connection: keep-alive
X-Powered-By: PHP/7.2.26
X-cache: MISS:

[root@bak ~]# curl -I http://192.168.29.132/demo/123.html
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Thu, 25 Jun 2020 02:23:01 GMT
Content-Type: text/html
Content-Length: 4
Connection: keep-alive
X-mem-key: /demo/123.html
Accept-Ranges: bytes

#当设置缓存后,访问相同的缓存key时,即使发起访问的机器不相同也同样能击中缓存
[root@master ~]# curl -I http://192.168.29.138/demo/123.html
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Thu, 25 Jun 2020 02:29:46 GMT
Content-Type: text/html
Content-Length: 4
Connection: keep-alive
X-mem-key: /demo/123.html
Accept-Ranges: bytes

查看memcached缓存状态

基于Nginx的Mencached缓存配置详解_第2张图片

基于Nginx的Mencached缓存配置详解_第3张图片

memcached监控文件

            |
 +----------------------------------------------------------------------+
*/
//memcached图形化小工具
$VERSION='$Id: memcache.php,v 1.1.2.3 2008/08/28 18:07:54 mikl Exp $';
#设置用户名
define('ADMIN_USERNAME','admin'); 
#设置密码
define('ADMIN_PASSWORD','123456'); 

define('DATE_FORMAT','Y/m/d H:i:s');
define('GRAPH_SIZE',200);
define('MAX_ITEM_DUMP',50);

#设置memcached主机信息
$MEMCACHE_SERVERS[] = '192.168.29.133:11211'; 

////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////

///////////////// Password protect ////////////////////////////////////////////////////////////////
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
      $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
      Header("WWW-Authenticate: Basic realm=\"Memcache Login\"");
      Header("HTTP/1.0 401 Unauthorized");

      echo <<
        

Rejected!

Wrong Username or Password! EOB; exit; } ///////////MEMCACHE FUNCTIONS ///////////////////////////////////////////////////////////////////// function sendMemcacheCommands($command){ global $MEMCACHE_SERVERS; $result = array(); foreach($MEMCACHE_SERVERS as $server){ $strs = explode(':',$server); $host = $strs[0]; $port = $strs[1]; $result[$server] = sendMemcacheCommand($host,$port,$command); } return $result; } function sendMemcacheCommand($server,$port,$command){ $s = @fsockopen($server,$port); if (!$s){ die("Cant connect to:".$server.':'.$port); } fwrite($s, $command."\r\n"); $buf=''; while ((!feof($s))) { $buf .= fgets($s, 256); if (strpos($buf,"END\r\n")!==false){ // stat says end break; } if (strpos($buf,"DELETED\r\n")!==false || strpos($buf,"NOT_FOUND\r\n")!==false){ // delete says these break; } if (strpos($buf,"OK\r\n")!==false){ // flush_all says ok break; } } fclose($s); return parseMemcacheResults($buf); } function parseMemcacheResults($str){ $res = array(); $lines = explode("\r\n",$str); $cnt = count($lines); for($i=0; $i< $cnt; $i++){ $line = $lines[$i]; $l = explode(' ',$line,3); if (count($l)==3){ $res[$l[0]][$l[1]]=$l[2]; if ($l[0]=='VALUE'){ // next line is the value $res[$l[0]][$l[1]] = array(); list ($flag,$size)=explode(' ',$l[2]); $res[$l[0]][$l[1]]['stat']=array('flag'=>$flag,'size'=>$size); $res[$l[0]][$l[1]]['value']=$lines[++$i]; } }elseif($line=='DELETED' || $line=='NOT_FOUND' || $line=='OK'){ return $line; } } return $res; } function dumpCacheSlab($server,$slabId,$limit){ list($host,$port) = explode(':',$server); $resp = sendMemcacheCommand($host,$port,'stats cachedump '.$slabId.' '.$limit); return $resp; } function flushServer($server){ list($host,$port) = explode(':',$server); $resp = sendMemcacheCommand($host,$port,'flush_all'); return $resp; } function getCacheItems(){ $items = sendMemcacheCommands('stats items'); $serverItems = array(); $totalItems = array(); foreach ($items as $server=>$itemlist){ $serverItems[$server] = array(); $totalItems[$server]=0; if (!isset($itemlist['STAT'])){ continue; } $iteminfo = $itemlist['STAT']; foreach($iteminfo as $keyinfo=>$value){ if (preg_match('/items\:(\d+?)\:(.+?)$/',$keyinfo,$matches)){ $serverItems[$server][$matches[1]][$matches[2]] = $value; if ($matches[2]=='number'){ $totalItems[$server] +=$value; } } } } return array('items'=>$serverItems,'counts'=>$totalItems); } function getMemcacheStats($total=true){ $resp = sendMemcacheCommands('stats'); if ($total){ $res = array(); foreach($resp as $server=>$r){ foreach($r['STAT'] as $key=>$row){ if (!isset($res[$key])){ $res[$key]=null; } switch ($key){ case 'pid': $res['pid'][$server]=$row; break; case 'uptime': $res['uptime'][$server]=$row; break; case 'time': $res['time'][$server]=$row; break; case 'version': $res['version'][$server]=$row; break; case 'pointer_size': $res['pointer_size'][$server]=$row; break; case 'rusage_user': $res['rusage_user'][$server]=$row; break; case 'rusage_system': $res['rusage_system'][$server]=$row; break; case 'curr_items': $res['curr_items']+=$row; break; case 'total_items': $res['total_items']+=$row; break; case 'bytes': $res['bytes']+=$row; break; case 'curr_connections': $res['curr_connections']+=$row; break; case 'total_connections': $res['total_connections']+=$row; break; case 'connection_structures': $res['connection_structures']+=$row; break; case 'cmd_get': $res['cmd_get']+=$row; break; case 'cmd_set': $res['cmd_set']+=$row; break; case 'get_hits': $res['get_hits']+=$row; break; case 'get_misses': $res['get_misses']+=$row; break; case 'evictions': $res['evictions']+=$row; break; case 'bytes_read': $res['bytes_read']+=$row; break; case 'bytes_written': $res['bytes_written']+=$row; break; case 'limit_maxbytes': $res['limit_maxbytes']+=$row; break; case 'threads': $res['rusage_system'][$server]=$row; break; } } } return $res; } return $resp; } ////////////////////////////////////////////////////// // // don't cache this page // header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1 header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); // HTTP/1.0 function duration($ts) { global $time; $years = (int)((($time - $ts)/(7*86400))/52.177457); $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400)); $weeks = (int)(($rem)/(7*86400)); $days = (int)(($rem)/86400) - $weeks*7; $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24; $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60; $str = ''; if($years==1) $str .= "$years year, "; if($years>1) $str .= "$years years, "; if($weeks==1) $str .= "$weeks week, "; if($weeks>1) $str .= "$weeks weeks, "; if($days==1) $str .= "$days day,"; if($days>1) $str .= "$days days,"; if($hours == 1) $str .= " $hours hour and"; if($hours>1) $str .= " $hours hours and"; if($mins == 1) $str .= " 1 minute"; else $str .= " $mins minutes"; return $str; } // create graphics // function graphics_avail() { return extension_loaded('gd'); } function bsize($s) { foreach (array('','K','M','G') as $i => $k) { if ($s < 1024) break; $s/=1024; } return sprintf("%5.1f %sBytes",$s,$k); } // create menu entry function menu_entry($ob,$title) { global $PHP_SELF; if ($ob==$_GET['op']){ return "
  • $title
  • "; } return "
  • $title
  • "; } function getHeader(){ $header = << MEMCACHE INFO

    memcache.php by Harun Yayli


    EOB; return $header; } function getFooter(){ global $VERSION; $footer = '
    '; return $footer; } function getMenu(){ global $PHP_SELF; echo "

    到此这篇关于基于Nginx的Mencached缓存配置详解的文章就介绍到这了,更多相关Nginx Mencached缓存配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    你可能感兴趣的:(基于Nginx的Mencached缓存配置详解)