非关系型数据库之Memcached

1.Memcached简介

Memcached是一款开源的、高性能的纯内存缓存服务软件。用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。

服务端Memcached 客户端Memcache

2.Memcached原理及优点

memcache 的工作就是在专门的机器的内存里维护一张巨大的 hash 表,来存储经常被读写的一些数组与文件,从而极大的提高网站的运行效率。

采用的是C/S模式,在 server 端启动服务进程,在启动时可以指定监听的 ip,自己的端口号,所使用的内存大小等几个关键参数。采用了单进程,单线程,异步I/O,基于事件 (event_based) 的服务方式.使用 libevent 作为事件通知实现。每个 Server 只是对自己的数据进行管理。Client 端通过指定 Server 端的 ip 地址(通过域名应该也可以)。以key->value形式,key 的值通过 hash 进行转换,然后确定对那台sever存储/获取数据。

优点:

  1. 对于用户来讲,访问网站的速度更快了,体验更好了
  2. 对网站来说,数据库压力降低了。只有当内存没有数据时才会去请求数据库。第一次写入的数据也会请求数据库。所以第一次公司没有预热,只有当用户读取过数据库才会放到Memcached中
  3. 提升了网站的并发访问,减少服务器数量

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分布式集群的特点:

  1. 所有MC服务器内存的容量都不是一样的。这些服务器内存加起来接近数据库的容量。比如1T的数据库,一台缓存数据库的内存没有这么大,因此分成10台缓存服务器
  2. 通过在客户端(web)程序或者MC的负载均衡器上用HASH算法,让同一内容都分配到一个MC服务器
  3. 普通的HASH算法对于节点宕机会带来大量的数据流动(失效),可能会引起雪崩效应
  4. 一致性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命中率

  1. 监听port或进程
  2. 可以模拟用户先set后get,比对get内容是不是set的。crond nagios zabbix
  3. 监控命中百分比
  4. 监控响应时间及需要的状态

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 对象缓存机制。

 

 

2
如无特殊说明,文章均为本站原创,转载请注明出处

该文章由 发布

这货来去如风,什么鬼都没留下!!!
发表我的评论

Hi,请填写昵称和邮箱!

取消评论
代码 贴图 加粗 链接 删除线 签到