1.Memcached简介
Memcached是一款开源的、高性能的纯内存缓存服务软件。用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
服务端Memcached 客户端Memcache
2.Memcached原理及优点
memcache 的工作就是在专门的机器的内存里维护一张巨大的 hash 表,来存储经常被读写的一些数组与文件,从而极大的提高网站的运行效率。
优点:
- 对于用户来讲,访问网站的速度更快了,体验更好了
- 对网站来说,数据库压力降低了。只有当内存没有数据时才会去请求数据库。第一次写入的数据也会请求数据库。所以第一次公司没有预热,只有当用户读取过数据库才会放到Memcached中
- 提升了网站的并发访问,减少服务器数量
3.Memcached企业使用场景
3.1作为数据库的前端缓存应用
1.完整缓存
例如京东的商品分类,就可以事先放到Memcached内存里,然后再对外提供数据访问。这个叫预热,此时可以只读取缓存就能读到商品分类数据,无需读取数据库,所以数据库的压力就降下来了,因为商品分类是由内部员工管理的,可以增加编辑后推送到Memcached内存里
当然,分类做成静态化文件,放到存储上,然后,放到web缓存里。这种实现方法更好
2.热点缓存-难在数据一致性
热点缓存一般是指由用户更新的商品,例如淘宝的卖家,当卖家新增商品后,淘宝网的程序就会写入数据库,然后读取写入的数据,把这部分数据放入到Memcached内存中,当下次访问这个商品的请求直接从Memcached内存中取数据。这种方法用来缓存网站热点数据,即Memcached中缓存经常被访问的数据
特别提示:这个过程可以通过程序实现,也可以在数据库上安装Memcached插件,直接由数据库触发更新内容到Memcached中。
淘宝京东双11场景:
要事先预热Memcached,先把数据放入内存预热,然后再逐步动态更新。先读取缓存,如果缓存里没有数据,再去读取数据库,然后再把读到的数据放入缓存。如果数据库里的数据更新,则触发缓存更新,防止给用户过期的数据
作为数据库的前端缓存最大的目的:减少数据库被大量访问的压力
3.2作为集群后端的session会话保持
把所有应用服务器session会话统一放到memcached里,web都读共享memcached,就保存一致了。php程序php.ini里配置。其他NOSQL软件也可以
4.Memcached分布式缓存集群
为缓解数据库的高并发访问压力,可以在数据库层配置数据读写分离,并对读数据库做负载均衡,但更简单高效的方法是部署缓存数据库,把部分数据保存在内存中。由于单台Memcached的内存容量有限,并且单台也是单点,因此Memcached也有负载均衡及分布式应用的场景。注:Memcached没有数据同步的功能
Memcached分布式集群的特点:
- 所有MC服务器内存的容量都不是一样的。这些服务器内存加起来接近数据库的容量。比如1T的数据库,一台缓存数据库的内存没有这么大,因此分成10台缓存服务器
- 通过在客户端(web)程序或者MC的负载均衡器上用HASH算法,让同一内容都分配到一个MC服务器
- 普通的HASH算法对于节点宕机会带来大量的数据流动(失效),可能会引起雪崩效应
- 一致性HASH可以让节点宕机对节点的数据流动(失效)降到最低
web服务器、memcached缓存服务器、数据库服务器三者开启的顺序①数据库 ②memcached缓存服务器 ③web服务器
5.Memcached安装使用
5.1安装环境
[root@node01 ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@node01 ~]# uname -r 3.10.0-327.el7.x86_64
5.2安装Memcached服务
[root@node01 ~]# yum install -y memcached
5.3启动Memcached服务
[root@node01 ~]# memcached -h ##查看帮助 [root@node01 ~]# systemctl start memcached.service [root@node01 ~]# lsof -i:11211 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME memcached 15882 memcached 26u IPv4 40055 0t0 TCP *:memcache (LISTEN) memcached 15882 memcached 27u IPv6 40056 0t0 TCP *:memcache (LISTEN) memcached 15882 memcached 28u IPv4 40059 0t0 UDP *:memcache memcached 15882 memcached 29u IPv6 40060 0t0 UDP *:memcache ##或者使用如下命令启动Memcached [root@node01 ~]# memcached -d -c 10240 -p 11211 -m 16 -P /var/run/memcached.pid -u root -l 118.190.201.68 ##命令说明: -d 后台运行 -c 并发访问连接数 -p 指定端口 -m 指定内存 -P 指定pid路径 -l 绑定监听的网卡 启用多实例的时候可以应用次命令更改端口号 [root@node01 ~]# lsof -i:11211 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME memcached 15909 root 26u IPv4 38523 0t0 TCP 118.190.201.68:memcache (LISTEN) memcached 15909 root 27u IPv4 38524 0t0 UDP 118.190.201.68:memcache
验证是否连接
5.4管理Memcached
向Memcached添加数据:键值对
key1--->values1 key2--->values2
MySQL与Memcached对比
MySQL Memcached/Redis insert set select get delete delete
语法说明:
set key 0 0 10 <command name> <key> <flags> <exptime> <bytes>\r\n ##注释说明 - <flags>是在取回内容时,与数据和发送块一同保存服务器上的任意16位无符号整形(用十进制来书写)客户端可以用它作为“位域”来存储 一些特定的信息;他对服务器是不透明的 - <exptime>是终止时间。如果为0,该项永不过期(虽然它可能被删除,以便为其他缓存项目腾出位置)如果非0(Unix时间戳或当时时刻 的秒偏移)到达终止时间后,客户端无法再获得这项内容 - <bytes>是随后的数据区块的字节长度,不包括用于分页的"\r\n"。它可以是0(这时后面跟随一个空的数据区块) <data block>\r\n - <data block>是大段的8位数据,其长度由前面的命令行中的<bytes>指定 \n换行且光标移至行首 \r光标移至行首,但不换行
1.通过nc写入
[root@node01 ~]# yum install -y nc ##10对应后面插入数据10个字符 [root@node01 ~]# printf "set key001 0 0 10\r\nchengzi008\r\n"|nc 127.0.0.1 11211 STORED ##查看数据 [root@node01 ~]# printf "get key001\r\n"|nc 127.0.0.1 11211 VALUE key001 0 10 chengzi008 END ##删除数据 [root@node01 ~]# printf "delete key001\r\n"|nc 127.0.0.1 11211 DELETED ~]# echo stats | nc 127.0.0.1 11211 ##查看运行状态信息 [root@node01 ~]# printf "get stats\r\n"|nc 127.0.0.1 11211 ##查看运行状态信息
5.5监控-hit命中率
- 监听port或进程
- 可以模拟用户先set后get,比对get内容是不是set的。crond nagios zabbix
- 监控命中百分比
- 监控响应时间及需要的状态
6.Memcache客户端
6.1安装memcache客户端
#以扩展的方式安装到php 需要有php的支持 安装php参考https://www.xionghaier.cn/?p=10这篇文章 [root@node02 ~]# mkdir /application/tools -p [root@node02 ~]# cd /application/tools/ [root@node02 tools]# wget http://pecl.php.net/get/memcache-2.2.5.tgz [root@node02 tools]# tar zxvf memcache-2.2.5.tgz [root@node02 memcache-2.2.5]# /application/php/bin/phpize Configuring for: PHP Api Version: 20121113 Zend Module Api No: 20121212 Zend Extension Api No: 220121212 config9.m4 config.guess config.m4 config.sub configure config.w32 [root@node02 memcache-2.2.5]# ./configure --enable-memcache --with-php-config=/application/php/bin/php-config --with-zlib-dir [root@node02 memcache-2.2.5]# echo $? 0 [root@node02 memcache-2.2.5]# make && make install [root@node02 memcache-2.2.5]# ll /application/php-5.5.32/lib/php/extensions/no-debug-non-zts-20121212/ total 284 -rwxr-xr-x 1 root root 289178 Jun 8 13:09 memcache.so [root@node02 memcache-2.2.5]# sed -i '$a extension=memcache.so' /application/php/lib/php.ini ##或者使用绝对路径 extension_dir="/application/php-5.5.32/lib/php/extensions/no-debug-non-zts-20121212/" [root@node02 memcache-2.2.5]# pkill php [root@node02 memcache-2.2.5]# /application/php/sbin/php-fpm -t [08-Jun-2018 13:11:33] NOTICE: configuration file /application/php-5.5.32/etc/php-fpm.conf test is successful [root@node02 memcache-2.2.5]# /application/php/sbin/php-fpm [root@node02 memcache-2.2.5]# /application/php/bin/php -m|grep memcache memcache 命令说明: 显示出memcache说明已经编译到php里了
6.2PHP测试
~]# vim mc.php ##web服务根目录创建
<?php
$memcache = new Memcache;
$memcache->commect('118.190.201.38',11211) or die ("could not connect");
$memcache->set('key20180611','chengzi008');
$get_value = $memcache->get('key20180611');
echo $get_value
?>
~]# printf "get key20180611\r\n"|nc 127.0.0.1 11211
6.3集群共享Session会话
~]# sed -i 's#session.save_handler = files#session.save_handler = memcache#;$a session.save_path = "tcp://118.190.201.38:11211"' /application/php/lib/php.ini ~]# egrep "^session.save_handler|^session.save_path" /application/php/lib/php.ini session.save_handler = memcache session.save_path = "tcp://118.190.201.38:11211" ~]# pkill php ~]# /application/php/sbin/php-fpm -t [08-Jun-2018 13:57:07] NOTICE: configuration file /application/php-5.5.32/etc/php-fpm.conf test is successful ~]# /application/php/sbin/php-fpm
所有的PHP客户端的配置文件都修改,这样它们就能共享session了
修改了配置参数,同时也需要程序支持session
~]# vim session.php ##web服务的根目录 <?php session_start(); if (!isset($_SESSION['TEST'])) { $_SESSION['TEST'] = time(); } $_SESSION['TEST3'] = time(); print $_SESSION['TEST']; print "<br><br>"; print $_SESSION['TEST3']; print "<br><br>"; print session_id(); ?> ##命令说明 时间随机 测试名test test3
使用session去memcached里查询一下
~]# printf "get 浏览器访问session.php获取到的session值\r\n" |nc 118.190.201.38 11211
6.4配置WEB界面管理Memcached服务
##下载memadmin-1.0.12.tar.gz软件包 [root@node02 tools]# wget http://www.junopen.com/memadmin/memadmin-1.0.12.tar.gz ##安装nginx
#!/bin/bash
yum -y install epel-release
yum install -y pcre pcre-devel openssl openssl-devel
mkdir -p /home/dilusense/tools
cd /home/dilusense/tools
yum install -y wget
wget http://nginx.org/download/nginx-1.10.2.tar.gz
tar xf nginx-1.10.2.tar.gz
cd nginx-1.10.2/
useradd -s /sbin/nologin -M www
./configure --prefix=/usr/local/nginx-1.10.2 --user=www --group=www \
--with-http_stub_status_module --with-http_ssl_module
make && make install
ln -s /usr/local/nginx-1.10.2 /usr/local/nginx
echo 'export PATH=$PATH:/usr/local/nginx/sbin/' >>/etc/profile
source /etc/profile
/usr/local/nginx/sbin/nginx
##解压包组到nginx如下目录
[root@node02 tools]# tar xvf memadmin-1.0.12.tar.gz -C /usr/local/nginx/html/blog/
##配置文件如下
[root@node02 conf]# vim nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
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;
server {
listen 80;
server_name blog.openstarck.org;
location / {
root html/blog;
index index.php index.html index.htm;
}
location ~* .*\.(php|php5)?$ {
root html/blog;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
error_page 500 502 503 504 /50x.html;
}
}
浏览器进行访问如下
管理memcached
统计参数如下
参数 | 值 | 描述 |
---|---|---|
pid | 11969 | memcache服务器进程ID |
uptime | 11350 | 服务器已运行秒数 |
time | 1528443934 | 服务器当前Unix时间戳 |
version | 1.4.15 | memcache版本 |
libevent | 2.0.21-stable | libevent版本 |
pointer_size | 64 | 操作系统指针大小 |
rusage_user | 0.429458 | 进程累计用户时间 |
rusage_system | 0.250517 | 进程累计系统时间 |
curr_connections | 11 | 当前连接数量 |
total_connections | 28 | Memcached运行以来连接总数 |
connection_structures | 12 | Memcached分配的连接结构数量 |
reserved_fds | 20 | 内部使用的FD数 |
cmd_get | 15 | get命令请求次数 |
cmd_set | 9 | set命令请求次数 |
cmd_flush | 0 | flush命令请求次数 |
cmd_touch | 0 | touch命令请求次数 |
get_hits | 9 | get命令命中次数 |
get_misses | 6 | get命令未命中次数 |
delete_misses | 0 | delete命令未命中次数 |
delete_hits | 0 | delete命令命中次数 |
incr_misses | 0 | incr命令未命中次数 |
incr_hits | 0 | incr命令命中次数 |
decr_misses | 0 | decr命令未命中次数 |
decr_hits | 0 | decr命令命中次数 |
cas_misses | 0 | cas命令未命中次数 |
cas_hits | 0 | cas命令命中次数 |
cas_badval | 0 | 使用擦拭次数 |
touch_hits | 0 | touch命令命中次数 |
touch_misses | 0 | touch命令未命中次数 |
auth_cmds | 0 | 认证命令处理的次数 |
auth_errors | 0 | 认证失败数目 |
bytes_read | 1855 | 读取总字节数 |
bytes_written | 1567 | 发送总字节数 |
limit_maxbytes | 67108864 | 分配的内存总大小(字节) |
accepting_conns | 1 | 接受新的连接 |
listen_disabled_num | 0 | 失效的监听数 |
threads | 4 | 当前线程数 |
conn_yields | 0 | 连接操作主动放弃数目 |
hash_power_level | 16 | hash表等级 |
hash_bytes | 524288 | 当前hash表大小 |
hash_is_expanding | 0 | hash表正在扩展 |
bytes | 498 | 当前存储占用的字节数 |
curr_items | 2 | 当前存储的数据总数 |
total_items | 9 | 启动以来存储的数据总数 |
expired_unfetched | 0 | 已过期但未获取的对象数目 |
evicted_unfetched | 0 | 已驱逐但未获取的对象数目 |
evictions | 0 | LRU释放的对象数目 |
reclaimed | 0 | 已过期的数据条目来存储新数据的数目 |
7.wordpress使用memcache缓存
wordpress会自动检查wp-content
目录下是否有object-cache.php
文件,如果有,直接调用它作为WordPress对象缓存机制。
或者
去 wordpress 后台插件搜索 memcached is your friend 并安装。插件在 wp-content 目录下会自动生成 object-cache.php 文件,并调用它作为 WordPress 对象缓存机制。
- 转载请注明来源:非关系型数据库之Memcached
- 本文永久链接地址:https://www.xionghaier.cn/archives/373.html