目录
有关概念
Memcached介绍
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
Memcache工作流程
memcahed实例启动,根据 -f 和 -n 进行预分配slab。以 -n 为最小值开始,以 -f 为比值生成等比数列,直到1m为止(每个slab的chunk size都要按8的倍数进行补全,比如:如果按比值算是556的话,会再加4到560成为8的整倍数)。然后每个slab分配一个page。当用户发来存储请求时(key,value),memcached会计算key+value的大小,看看属于哪个slab。确定slab后看里面的是否有空闲chunk放key+value,如果不够就再向系统申请一个page(如果此时已经达到 -m 参数设置的内存使用上限,则看是否设置了 -M 。如果设置了 -M 则返回错误提示,否则按LRU算法删除数据)。申请后将该page按本slab的chunk size 进行切割,然后分配一个来存放用户数据。
注意:
1)chunk是在page里面划分的,而page固定为1m,所以chunk最大不能超过1m。
2)chunk实际占用内存要加48B,因为chunk数据结构本身需要占用48B。
3)如果用户数据大于1m,则memcached会将其切割,放到多个chunk内。
4)已分配出去的page不能回收
优化建议
1)-n 参数的设置,注意将此参数设置为1024可以整除的数(还要考虑48B的差值),否则余下来的部分就浪费了。
2)不要存储超过1m的数据。因为要拆成多个chunk,计算和时间成本都成倍增加。
3)善用stats命令查看memcached状态。
4)消灭eviction(被删除的数据)。
造成eviction是因为内存不够,有三个思路:
(1)在CPU有余力的情况下开启压缩(PHP扩展);
(2)增加内存;
(3)调整-f参数,减少内存浪费。
5)调整业务代码,提高命中率。
6)缓存小数据。省带宽,省网络I/O时间,省内存。
7)根据业务特点,为数据尺寸区间小的业务分配专用的memcached实例。这样可以调小 -f 参数,使数据集中存在少数几个slab上,内存浪费较少。
启动时最重要的参数:
-m 整个memcached最大内存
-f chunk大小增长因子
-n chunk最小分配空间
-C 禁用CAS
-vvv 打印详细信息
我们通过计算可以看出,每个slab的chunk size大小都是上一个大小的1.25倍,1.25就是memcached启动时制定的-f的值,所以,要根据不同的业务场景调整,既要尽可能少的减少内存浪费,又要存得下我们业务中的数据,再举个例子,加入我们的业务很BT,大小都是200kb,我们该怎么做?那当然是要保证我们申请的chunk大小都是200kb了,虽然memcached并不支持这么做。假如创建了38个slabs,最后数据全都落到了第20-25个slab中,那0-19和26-38的内存就被浪费了,这只是能评估出来的,还有一种情况,加入我们的chunk大小是500kb,数据才200kb,因为每个chunk都只能存储一个,所以一个chunk就会有500kb-200kb的空间浪费,如果有一千万个chunk要存,那将会浪费多少空间?所以,在使用memcached之前,先要评估你的数据,根据它去调整-f因子。
memcached参数使用介绍
-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
清空memcache缓存的方法
默认memcache会监听11221端口,如果想清空服务器上memecache的缓存:
1)第一种方法:
# telnet localhost 11221
进入后,执行flush_all
2)第二种方法:
# echo "flush_all"|nc localhost 11221
php的memcache和memcached扩展区别
memcache文档:http://pecl.php.net/package/memcache
memcached文档:http://pecl.php.net/package/memcached
1)首先看下开发时间:
memcache最早是在2004年2月开发的,最后更新是在2013年4月;
memcached最早是在2009年1月开发的,最后更新是在2014年1月更新的。
所以memcache的历史比memcached早。
2)memcache是一个原生版本,完全在php框架内开发的。与之对应的带d的memcached是建立在libmemcached的基础上,所以相对来说,memcached版本的功能更全一些。
在安装memcache扩展的时候并不要求安装其他东西,但是在安装memcached的时候会要求安装libmemcached;
libmemcached是memcache的C客户端,它具有的优点是低内存,线程安全等特点。
比如新浪微博之前就全面将php的memcache替换成php的memcached,在高并发下,稳定性果断提高。
3)memcache的方法特别少,比如getMulti,setMulti都是没有的,基本就剩下最简单的get和set了。
所以说memcached比memcache支持更多的memcache协议。
memcache方法列表:http://cn2.php.net/memcache
memcached方法列表:http://www.php.net/manual/zh/book.memcached.php
4)Memcache是原生实现的,支持OO和非OO两套接口并存。而memcached是使用libmemcached,只支持OO接口。
5)memcached直接配置了session支持,只要稍微修改下配置文件就可以把session存储在memcache中了。
6)memcached还有个非常称赞的地方,就是flag不是在操作的时候设置了,而是有了一个统一的setOption()。Memcached实现了更多的memcached协议。
7)memcached支持Binary Protocol,而memcache不支持。这意味着memcached会有更高的性能。不过memcached目前还不支持长连接。
Magent
Magent 是一款开源的 Memcached 代理软件,使用它可以搭建高可用性的集群应用的 Memcached 服务 ,备份 Memcached 数据,尽管 Memcached 服务挂掉,前端也能获取到数据,客户端先连到 Magent 代理服务器 ,然后Magent 代理服务器 在可以连接多台 Memcached 服务器,然后可以进行数据的保存和备份数据。这样数据就不会丢失,保存了数据完整性。
Keepalived介绍
keepalived是一个类似于layer3, 4 & 5交换机制的软件,也就是我们平时说的第3层、第4层和第5层交换。Keepalived是自动完成,不需人工干涉。在网络里面就是保持在线了,也就是所谓的高可用或热备,它集群管理中保证集群高可用的一个服务软件,其功能类似于heartbeat,用来防止单点故障(单点故障是指一旦某一点出现故障就会导致整个系统架构的不可用)的发生。
Keepalived工作原理
keepalived可提供vrrp以及health-check功能,可以只用它提供双机浮动的vip(vrrp虚拟路由功能),这样可以简单实现一个双机热备高可用功能;keepalived是以VRRP虚拟路由冗余协议为基础实现高可用的,可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip(该路由器所在局域网内其他机器的默认路由为该vip),master会发组播,当backup收不到VRRP包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以保证路由器的高可用了。
Keppalived的组件图
keepalived作用
Keepalived主要用作RealServer的健康状态检查以及LoadBalance主机和BackUP主机之间failover的实现。
Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。
VRRP协议介绍
学过网络的朋友都知道,网络在设计的时候必须考虑到冗余容灾,包括线路冗余,设备冗余等,防止网络存在单点故障,那在路由器或三层交换机处实现冗余就显得尤为重要。
在网络里面有个协议就是来做这事的,这个协议就是VRRP协议,Keepalived就是巧用VRRP协议来实现高可用性(HA)的发生。
VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。对于VRRP,需要清楚知道的是:
1)VRRP是用来实现路由器冗余的协议。
2)VRRP协议是为了消除在静态缺省路由环境下路由器单点故障引起的网络失效而设计的主备模式的协议,使得发生故障而进行设计设备功能切换时可以不影响内外数据通信,不需要再修改内部网络的网络参数。
3)VRRP协议需要具有IP备份,优先路由选择,减少不必要的路由器通信等功能。
4)VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个)。然而,在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话,就是master,或者是通过算法选举产生的,MASTER实现针对虚拟路由器IP的各种网络功能,如ARP请求,ICMP,以及数据的转发等,其他设备不具有该IP,状态是BACKUP。除了接收MASTER的VRRP状态通告信息外,不执行对外的网络功能,当主级失效时,BACKUP将接管原先MASTER的网络功能。
5)VRRP协议配置时,需要配置每个路由器的虚拟路由ID(VRID)和优先权值,使用VRID将路由器进行分组,具有相同VRID值的路由器为同一个组,VRID是一个0-255的整整数,;同一个组中的路由器通过使用优先权值来选举MASTER。,优先权大者为MASTER,优先权也是一个0-255的正整数。
Keepalived的配置文件
keepalived只有一个配置文件keepalived.conf,配置文件里面主要包括以下几个配置项,分别是global_defs、static_ipaddress、static_routes、VRRP_script、VRRP_instance和virtual_server。
总的来说,keepalived主要有三类区域配置,注意不是三种配置文件,是一个配置文件里面三种不同类别的配置区域:
1)全局配置(Global Configuration)
2)VRRPD配置
3)LVS配置
系统环境
主机名 |
操作系统 |
Ip地址 |
软件包 |
VIP地址 |
Memcached主缓存服务器 |
CentOS6.9 |
外网: 10.0.0.56 内网: 172.168.1.56
|
libevent-2.1.8-stable.tar.gz memcached-1.5.10.tar.gz magent-0.5.tar.gz keepalived |
172.168.1.150 |
Memcached从缓存服务器 |
CentOS6.9 |
外网: 10.0.0.56 内网: 172.168.1.56 |
libevent-2.1.8-stable.tar.gz memcached-1.5.10.tar.gz keepalived |
172.168.1.150 |
Web服务器 |
CentOS6.9 |
外网: 10.0.0.7 内网: 172.168.1.7 |
|
|
部署服务
配置Memcache主缓存节点和从缓存节点
安装Memcached和libevent软件包
----两台配置相同
cd /home/lk/tools
wget http://memcached.org/files/memcached-1.5.10.tar.gz
ll
tar xf memcached-1.5.10.tar.gz
yum install gcc gcc-c++ -y
wget https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz
ll
tar zxvf libevent-2.1.8-stable.tar.gz
cd /opt/libevent-2.1.8-stable
cd libevent-2.1.8-stable
./configure --prefix=/usr/local/libevent
make && make install
cd ..
tar xf memcached-1.5.10.tar.gz
cd memcached-1.5.10
./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent/
make && make install
echo $?
ln -s /usr/local/memcached/bin/* /usr/local/bin/
#将安装的libevent-2.1.so.6模块建立软链接到/usr/lib64目录下,否则在启动Magent时会出错
ln -s /usr/local/libevent/lib/libevent-2.1.so.6 /usr/lib64/libevent-2.1.so.6
在主缓存节点安装Magent软件包
因为官网无法打开,所以在网上找到了一个百度网盘的分享:
链接:https://pan.baidu.com/s/1ZY5HmFVvtc7xcFBHmui22Q 密码:nlmz
tar zxvf magent-0.5.tar.gz
mkdir magent
#因为解压软件包时发现时解压在当前目录的,所以创建了一个目录存放解压后的文件,防止文件存放过乱
tar xf magent-0.5.tar.gz -C magent/
cd magent
ll
#编译安装前需要先修改文件,否则会报错
vim ketama.h
#ifndef _KETAMA_H
#define _KETAMA_H
修改为
#ifndef SSIZE_MAX
#define SSIZE_MAX 32767
vim Makefile
# vim Makefile //添加路径
LIBS = -levent -lm -L/usr/local/libevent/lib
INCLUDE=-I/usr/local/libevent/include
make
编译后会生成一个可执行的文件,我们把生成的magent命令让系统识别,并发送到Memcached2服务器
cp magent /usr/bin/
#把生成的magent命令让系统识别
scp /opt/magent/magent [email protected]:/usr/bin
#把生成的magent命令复制到memcached2服务器
在两台Memcache服务器上安装Keepalived
主缓存节点
yum install keepalived -y
cp /etc/keepalived/keepalived.conf{,.bak}
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
13203*******@163.com
}
notification_email_from 13203*******@163.com
smtp_server 172.0.0.1
smtp_connect_timeout 30
router_id MASTER-HA
}
vrrp_script magent {
script "/server/scripts/magent.sh"
interval 2
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface eth1
virtual_router_id 51
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.168.1.150
}
}
track_script {
magent
}
}
cd /server/scripts/
magent --help
vim magent.sh
#!/bin/bash
K=`ps -ef | grep keepalived | grep -v grep | wc -l`
if [ $K -gt 0 ]; then
magent -u root -n 51200 -l 172.168.1.150 -p 12000 -s 172.168.1.56:11211 -b 172.168.1.57:11211
else
pkill -9 magent
fi
chmod +x magent.sh
/etc/init.d/keepalived status
/etc/init.d/keepalived start
脚本magent.sh解释
-n 51200 //定义用户最大连接数
-l //指定虚拟IP
-p 12000 //指定端口号
-s //指定主缓存服务器
-b //指定从缓存服务器
从缓存节点
yum install keepalived -y
cp /etc/keepalived/keepalived.conf{,.bak}
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
13203*******@163.com
}
notification_email_from 13203*******@163.com
smtp_server 172.0.0.1
smtp_connect_timeout 30
router_id Backup-HA
}
vrrp_script magent {
script "/server/scripts/magent.sh"
interval 2
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state BACKUP
interface eth1
# mcast_src_ip 10.0.0.57
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.168.1.150
}
track_script {
magent
}
}
cd /server/scripts/
magent --help
vim magent.sh
#!/bin/bash
K=`ps -ef | grep keepalived | grep -v grep | wc -l`
if [ $K -gt 0 ]; then
magent -u root -n 51200 -l 172.168.1.150 -p 12000 -s 172.168.1.56:11211 -b 172.168.1.57:11211
else
pkill -9 magent
fi
chmod +x magent.sh
/etc/init.d/keepalived status
/etc/init.d/keepalived start
测试
主memcache
/etc/init.d/keepalived status
ip addr
/etc/init.d/keepalived stop
ip addr
从memcache
/etc/init.d/keepalived status
ip addr
/etc/init.d/keepalived stop
ip addr
Web服务器
cd /home/lk/tools/
rz
wget http://pecl.php.net/get/memcache-2.2.7.tgz
tar xf memcache-2.2.7.tgz
cd memcache-2.2.7
./configure -enable-memcache --with-php-config=/application/php/bin/php-config
make && make install
#查看是否安装
ls -l /application/php/lib/php/extensions/no-debug-non-zts-20090626/
cd /application/php/lib/
vim php.ini
......
tail -2 /application/php/lib/php.ini
extension_dir = "/application/php/lib/php/extensions/no-debug-non-zts-20090626/"
extension = memcache.so
#检测语法是否正确,重启服务
/application/php/sbin/php-fpm -t
[16-Aug-2018 18:35:08] NOTICE: configuration file /application/php5.5.32/etc/php-fpm.conf test is successful
#重启服务
killall php-fpm
killall php-fpm
/application/php/sbin/php-fpm
#编写测试memcache文件
cat /var/html/bbs/test_memcache.php
<?php
$memcache = new Memcache;
$memcache->connect('172.168.1.150', 11211) or die ("Could not connect NFS server");
$memcache->set('key', 'Memcache connect OK');
$get = $memcache->get('key');
echo $get;
?>
/application/php/bin/php /var/html/bbstest_memcache.php
Memcache connect OK
#修改php配置,设置session共享
cp /application/php/lib/php.ini{,.bak}
vim /application/php/lib/php.ini
session.save_handler = memcache
session.save_path = "tcp://172.168.1.150:11211"
#重启php服务
killall php-fpm
killall php-fpm
/application/php/sbin/php-fpm
测试:
cat test_info.php
<?php phpinfo(); ?>
测试
在浏览器输出:域名/test_info.php
测试
telnet 172.168.1.150 11211
stats