A-A+

高性能分布式对象缓存系统-Memcached

2014年04月09日 负载集群 暂无评论 阅读 954 次

1. Memcached是高性能分布式对象缓存系统,官方主页http://memcached.org/,主页上对它的介绍是:为来自数据库调用、API调用、或者页面渲染的结果的小块任意数据(字符串、对象)的一个内存中的键值存储。
许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。
这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。

2. Memcached的基本工作原理
如下为memcached的工作流程示意图,
memcache_liucheng
首次访问:从RDBMS中取得数据保存在memcached;
第二次后:从memcached中取得数据显示页面。类似squid在web网页缓存中的作用。

3. Memcached的特征
memcached作为高速运行的分布式缓存服务器,具有以下的特点。
• 协议简单
memcached的服务器客户端通信并不使用复杂的XML等格式,而使用简单的基于文本行的协议。因此,通过telnet也能在memcached上保存数据、取得数据。

• 基于libevent的事件处理
libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥O(1)的性能。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。

• 内置内存存储方式
为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。

• memcached互不通信的分布式
memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。分布式的实现取决于客户端。如下为memcached分布式实现示意图,
memcache_fenbushi
4. 缓存与数据库的同步
比较保险的做法是:查询的时候从缓存中取,add、updae、delete的时候同时操作缓存与DB。
当然你也可以定时同步缓存与DB的数据,不同的业务应该有不同的选择。

2 Memcached安装、启动
________________________________________
2.1 安装前准备
memcached依赖于libevent库,在安装前需保证libevent库已经安装
yum install libevent libevent-devel

2.2 安装
可以从官网下载到最新版本的memcached,直接下载请戳http://www.memcached.org/files/memcached-1.4.17.tar.gz,解压、编译安装:
tar zxvf memcached-1.4.17.tar.gz ; cd memcached-1.4.17
./configure --prefix=/usr/local/memcached
make
make install

2.3 启动
启动前防火墙设置:关闭iptables或者添加以下内容到iptables中:
-A INPUT -m state NEW -m tcp -p tcp --dport 11211 -j ACCEPT
-A INPUT -m state NEW -m udp -p udp --dport 11211 -j ACCEPT

/usr/local/memcached/bin/memcached -u root -p 11211 -m 512m -vv
slab class 1: chunk size 80 perslab 13107
slab class 2: chunk size 104 perslab 10082
slab class 3: chunk size 136 perslab 7710
slab class 4: chunk size 176 perslab 5957
slab class 5: chunk size 224 perslab 4681
slab class 6: chunk size 280 perslab 3744
slab class 7: chunk size 352 perslab 2978
slab class 8: chunk size 440 perslab 2383
slab class 9: chunk size 552 perslab 1899
slab class 10: chunk size 696 perslab 1506
slab class 11: chunk size 872 perslab 1202
slab class 12: chunk size 1096 perslab 956
slab class 13: chunk size 1376 perslab 762
slab class 14: chunk size 1720 perslab 609
slab class 15: chunk size 2152 perslab 487
slab class 16: chunk size 2696 perslab 388
slab class 17: chunk size 3376 perslab 310
slab class 18: chunk size 4224 perslab 248
slab class 19: chunk size 5280 perslab 198
slab class 20: chunk size 6600 perslab 158
slab class 21: chunk size 8256 perslab 127
slab class 22: chunk size 10320 perslab 101
slab class 23: chunk size 12904 perslab 81
slab class 24: chunk size 16136 perslab 64
slab class 25: chunk size 20176 perslab 51
slab class 26: chunk size 25224 perslab 41
slab class 27: chunk size 31536 perslab 33
slab class 28: chunk size 39424 perslab 26
slab class 29: chunk size 49280 perslab 21
slab class 30: chunk size 61600 perslab 17
slab class 31: chunk size 77000 perslab 13
slab class 32: chunk size 96256 perslab 10
slab class 33: chunk size 120320 perslab 8
slab class 34: chunk size 150400 perslab 6
slab class 35: chunk size 188000 perslab 5
slab class 36: chunk size 235000 perslab 4
slab class 37: chunk size 293752 perslab 3
slab class 38: chunk size 367192 perslab 2
slab class 39: chunk size 458992 perslab 2
slab class 40: chunk size 573744 perslab 1
slab class 41: chunk size 717184 perslab 1
slab class 42: chunk size 1048576 perslab 1

memcached常用参数说明:
-d:启动一个守护进程.
-m:分配给Memcache使用的内存数量,单位是MB
-u:运行Memcache的用户
-l:监听的服务器IP地址
-p:设置Memcache监听的端口,默认为11211
-c:最大运行的并发连接数,默认是1024,可按照服务器的负载量来设定.
-P:设置保存Memcache的pid文件
-vv:详细的输出信息显示

2.4 制作memcached启动脚本
cat memcached.sh:
#!/bin/bash
# Description: start|stop|restart the Memcached services.
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
. /etc/rc.d/init.d/functions

memcached="/usr/local/bin/memcached"
[ -e $memcached ] || exit 1

start()
{
echo "Start memcached:"
daemon $memcached -d -m 521m -u root -l localhost -p 11211 -c 1500 -P /tmp/memcached.pid
}

stop()
{
echo "Stop memcached:"
#kill -9 ps aux | grep memcached | awk '{print $2}'
killproc memcached
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 3
start
;;
*)
echo $"Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?
添加可执行权限:chmod +x memcached.sh
拷贝到/etc/rc.d/init.d/目录下:cp memcached.sh /etc/rc.d/init.d/memcached
将memcached加入系统启动项:
chkconfig --add memcached
chkconfig --level 35 memcached on
启动memcached:/etc/init.d/memcached start
Start memcached:
[ OK ]
查看memcached是否启动:ps aux | grep memcached

3 Memcached分布式集群实现
________________________________________
由于Memcached本身没有内置分布式功能,多个memcached之间互不通信,导致无法实现使用多台Memcache服务器来存储不同的数据,最大程度的使用相同的资源;无法同步数据,容易造成单点故障。如果需要实现高可用性,需要通过其他的代理或者客户端来实现:
________________________________________
3.1 使用magent来实现Memcached集群
________________________________________
1. magent是一款简单且有效的memcached服务器代理软件,项目主页请戳http://code.google.com/p/memagent/

2. magent的特征
• 能够保持与memcached服务器的连接
• 支持以下的memcached命令:
get gets
delete
incr decr
add set replace prepebd append
cas
• 基于libevent库的事件驱动机制
• 支持ketama算法
• 备份服务器工厂
• unix域socket

3. magent编译安装
mkdir magent && cd magent/
wget http://memagent.googlecode.com/files/magent-0.6.tar.gz
tar zxvf magent-0.6.tar.gz
/sbin/ldconfig
sed -i "s#LIBS = -levent#LIBS = -levent -lm#g" Makefile
make
cp magent /usr/bin/magent
cd ../

注解:编译的时候可能报错:
gcc -Wall -g -O2 -I/usr/local/include -c -o magent.o magent.c
magent.c: In function ‘writev_list’:
magent.c:729: error: ‘SSIZE_MAX’ undeclared (first use in this function)
magent.c:729: error: (Each undeclared identifier is reported only once
magent.c:729: error: for each function it appears in.)
make: *** [magent.o] Error 1
出错原因是在Linux系统上,SSIZE_MAX是定义在limits.h文件中,需要加入“#include ”到magent.c中

4. magent命令参数说明:
magent 命令参数说明:
-h this message
-u uid
-g gid
-p port, default is 11211. (0 to disable tcp support)
-s ip:port, set memcached server ip and port
-b ip:port, set backup memcached server ip and port
-l ip, local bind ip address, default is 0.0.0.0
-n number, set max connections, default is 4096
-D do not go to background
-k use ketama key allocation algorithm
-f file, unix socket path to listen on. default is off
-i number, max keep alive connections for one memcached server, default is20
-v verbose

5. 集群实例测试
memcached -m 1 -u root -d -l 127.0.0.1 -p 11211
memcached -m 1 -u root -d -l 127.0.0.1 -p 11212
memcached -m 1 -u root -d -l 127.0.0.1 -p 11213
magent -u root -n 51200 -l 127.0.0.1 -p 12000 -s 127.0.0.1:11211 -s 127.0.0.1:11212 -b 127.0.0.1:11213
注解:
1、分别在11211、11212、11213端口启动3个Memcached进程,在12000端口开启magent代理程序;

2、11211、11212端口为主Memcached,11213端口为备份Memcached;

3、连接上12000的magent,set key1和set key2,根据哈希算法,key1被写入11212和11213端口的Memcached,key2被写入11212和11213端口的Memcached;

4、当11211、11212端口的Memcached死掉,连接到12000端口的magent取数据,数据会从11213端口的Memcached取出;

5、当11211、11212端口的Memcached重启复活,连接到12000端口,magent会从11211或11212端口的Memcached取数据,由于这两台Memcached重启后无数据,因此magent取得的将是空值,尽管11213端口的Memcached还有数据。可采用定时维护服务器,恢复memcached。

6、memcached和magent可以采用混合的方式来实现分布式集群,如下为模型图,
memcache
6. 测试流程
[root@rango ~]# telnet 127.0.0.1 12000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
stats
memcached agent v0.4
matrix 1 -> 127.0.0.1:11211, pool size 0
matrix 2 -> 127.0.0.1:11212, pool size 0
END
set key1 0 0 8
rangochen
STORED
set key2 0 0 8
rangochen
STORED
quit
Connection closed by foreign host.

[root@rango ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get key1
END
get key2
VALUE key2 0 8
rangochen
END
quit
Connection closed by foreign host.

[root@rango ~]# telnet 127.0.0.1 11212
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get key1
VALUE key1 0 8
rangochen
END
get key2
END
quit
Connection closed by foreign host.

[root@rango ~]# telnet 127.0.0.1 11213
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get key1
VALUE key1 0 8
rangochen
END
get key2
VALUE key2 0 8
rangochen
END
quit
Connection closed by foreign host.

模拟11211、11212端口的Memcached死掉
[root@rango ~]# ps -ef | grep memcached
root 6589 1 0 01:25 ? 00:00:00 memcached -m 1 -u root -d -l 127.0.0.1 -p 11211
root 6591 1 0 01:25 ? 00:00:00 memcached -m 1 -u root -d -l 127.0.0.1 -p 11212
root 6593 1 0 01:25 ? 00:00:00 memcached -m 1 -u root -d -l 127.0.0.1 -p 11213
root 6609 6509 0 01:44 pts/0 00:00:00 grep memcached
[root@rango ~]# kill -9 6589
[root@rango ~]# kill -9 6591
[root@rango ~]# telnet 127.0.0.1 12000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get key1
VALUE key1 0 8
rangochen
END
get key2
VALUE key2 0 8
rangochen
END
quit
Connection closed by foreign host.

模拟11211、11212端口的Memcached重启复活
[root@rango ~]# memcached -m 1 -u root -d -l 127.0.0.1 -p 11211
[root@rango ~]# memcached -m 1 -u root -d -l 127.0.0.1 -p 11212
[root@rango ~]# telnet 127.0.0.1 12000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get key1
END
get key2
END
quit
Connection closed by foreign host.

3.2 java客户端
________________________________________
3.2.1 XMemcached是一个基于Java nio的memcached客户端。它线程安全,结构简单,支持所有的memcached文本协议和二进制协议,并且有比较优异的性能表现。它还支持一些高级特性,如JMX、动态增删节点、客户端统计以及nio连接池等。

3.2.2 与同是基于java nio的spymemcached相比来说,XMemcached具有以下特点:
1)API模型是同步,异步的API使用比较繁琐,在memcached协议加入noreply后,异步模型的存在价值就更可疑了;
2)支持设置memcached的节点权重;
3)支持动态增删节点,可以通过编程或者JMX;
4)支持nio连接池,并且允许让用户对网络层面有更多的控制,提供更多的性能优化选项;
5)支持客户端数据统计;
6)支持Kestrel,Kestrel是一个scala编写的MQ server。

3.2.3 简单实例
MemcachedClient client;
try {
client = new XMemcachedClient("localhost",11211);//默认端口
// store a value for one hour(synchronously).
String someObject = "缓存这个一个小时可以吗?";
client.set("key", 3600, someObject);
// Retrieve a value.(synchronously).
Object getSomeObject = client.get("key");
// delete
client.delete("key");
System.out.println(getSomeObject.toString());
} catch (TimeoutException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (MemcachedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
以上代码是没有经过Spring管理的,XMemcachedClient是一个常驻程序。所以可以考虑将它置入到Spring中,配置方式前面已讲过。
使用方式见下:
private MemcachedClient memcachedClient;
public void setMemcachedClient(MemcachedClient memcachedClient) {
this.memcachedClient = memcachedClient;
}
注入后直接可使用。

4 Memcached监控
________________________________________
Memcached的监控方式有多种,对应单机和分布式集群配置:
________________________________________
4.1 使用memcache.php来监控memcached
________________________________________
这是一种非常方便、快捷的memcached监控方式,下载该文件请戳http://livebookmark.net/memcachephp/memcachephp.zip
下载完后将该文件移动到网页存放目录即可,如/var/www/html/(apache)。在使用之前需要设置登录账户、密码等配置信息:vim memcache.php:
......
define('ADMIN_USERNAME','memcache'); // Admin Username
define('ADMIN_PASSWORD','131415'); // Admin Password
......
$MEMCACHE_SERVERS[] = '192.168.56.1:11211'; // 添加要监控的memcached服务器ip及端口
$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; //集群环境下添加多个ip及端口

登录http://ip/memcache.php ,查看相应的监控信息。

4.2 使用Nagios的memcached监控插件来实现
________________________________________
1. 可从以下地址下载该插件,请戳 http://cpan.uwinnipeg.ca/cpan/authors/id/Z/ZI/ZIGOROU/Nagios-Plugins-Memcached-0.02.tar.gz

2. 需要保证系统安装有perl环境:
#rpm -q perl
perl-5.10.1-136.el6.i686
#which perl
/usr/bin/perl

3. 编译安装:
#tar zxvf Nagios-Plugins-Memcached-0.02.tar.gz ; cd Nagios-Plugins-Memcached-0.02
#cat README:
......
INSTALLATION

To install this module, run the following commands:

perl Makefile.PL
make
make test
make install
......
#perl Makefile.PL
报错:Can't locate CPAN.pm in @INC (@INC contains: inc /usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5 /usr/share/perl5 .) at inc/Module/AutoInstall.pm line 635, line 1.
原因是没有安装相应的perl的CPAN模块,解决:yum install perl-CPAN

#make
编译。会下载一些编译所需要的文件。

#make install
安装。从输出信息中可以知道,默认会将check_memcached安装到/usr/bin目录下,将该文件拷贝到Nagios的libexec目录下:cp /usr/bin/check_memcached /usr/local/nagios/libexec/

测试check_memcached:/usr/local/nagios/libexec/check_memcached -h
报以下错误:Base class package "Nagios::Plugin" is empty.
(Perhaps you need to 'use' the module which defines that package first,
or make that module available in @INC (@INC contains: /usr/local/nagios/libexec/../lib /usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5 /usr/share/perl5 .).
at /usr/local/share/perl5/Nagios/Plugins/Memcached.pm line 6
BEGIN failed--compilation aborted at /usr/local/share/perl5/Nagios/Plugins/Memcached.pm line 6.
Compilation failed in require at /usr/local/nagios/libexec/check_memcached line 12.
BEGIN failed--compilation aborted at /usr/local/nagios/libexec/check_memcached line 12.
原因是缺少perl的nagios模块:yum search perl-nagios
Loading mirror speeds from cached hostfile
* epel: mirrors.hust.edu.cn
* rpmforge: mirrors.neusoft.edu.cn
======================== N/S Matched: perl-nagios =========================
perl-Nagios-NSCA.noarch : Nagios::NSCA Perl module
perl-Nagios-Object.noarch : Nagios::Object - Nagios object configuration
: parsing
perl-Nagios-Plugin.noarch : Family of perl modules to streamline writing
: Nagios
perl-Nagios-Plugin-WWW-Mechanize.noarch : Login to a web page as a user and
: get data as a Nagios plugin

Name and summary matches only, use "search all" for everything.
安装perl-Nagios-Plugin.noarch:yum install perl-Nagios-Plugin.noarch
再执行测试,报以下错误:
Can't locate Carp/Clan.pm in @INC (@INC contains: /usr/local/nagios/libexec/../lib /usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5 /usr/share/perl5 .) at /usr/local/share/perl5/Nagios/Plugins/Memcached.pm line 8.
BEGIN failed--compilation aborted at /usr/local/share/perl5/Nagios/Plugins/Memcached.pm line 8.
Compilation failed in require at /usr/local/nagios/libexec/check_memcached line 12.
BEGIN failed--compilation aborted at /usr/local/nagios/libexec/check_memcached line 12.
原因是没有安装perl的carp:clan包,安装:yum install perl-Carp-Clan.noarch
最后安装cache:memcached模块:yum install perl-Cache-Memcached.noarch
执行:/usr/local/nagios/libexec/check_memcached -h
check_memcached 0.02 [http://search.cpan.org/dist/Nagios-Plugins-Memcached/bin/check_memcache]

This library is free software, you can redistribute it and/or modify
it under the same terms as Perl itself.

Usage: check_memcached [-H host] [-w warnings] [-c critical] [--size-warnng size-warnng] [--size-critical size-critical] [--hit-warning hit-warning] [--hit-critical hit-critical] [-t timeout] [-v] [-h] [-?] [-V] [--extra-opts section@config_file]
......

4. 配置Nagios:
4.1 修改commands.cfg文件,添加监控命令定义:vim /usr/local/nagios/etc/objects/commands.cfg
#check response time(msec) for memcached
define command {
command_name check_memcached_response_11211
command_line /usr/local/bin/check_memcached -H 192.168.56.1 -w 300 -c 500
}
#check cache size ratio(bytes/limit_maxbytes[%]) for memcached
define command {
command_name check_memcached_11211
command_line $USER1$/check_memcached -H 192.168.56.1:11211 --size-warning 80 --size-critical 90
}
#check cache hit ratio(get_hits/cmd_get[%]) for memcached
define command {
command_name check_memcached_hit
command_line /usr/local/bin/check_memcached -H 192.168.56.1 --hit-warning 10 --size-critical 5
}
注解:以上三个命令分别为:监控memcached是否有响应、监控memcached的内存使用比例 、监控memcached的击中率。

4.2 添加主机和服务:vim /usr/local/nagios/etc/objects/memcached.cfg
define host{
use linux-server
host_name memcache
alias Memcache_server
address 192.168.56.1
}

define service{
use generic-service
host_name memcache
service_description Memcached_response
check_command check_memcached_response_11211
}

define service{
use generic-service
host_name memcache
service_description Memcached_size
check_command check_memcached_11211
}
define service{
use generic-service
host_name memcache
service_description Memcached_hit
check_command check_memcached_hit
}

4.3 将memcached.cfg添加到Nagios主配置文件中:
cfg_file=/usr/local/nagios/etc/objects/memcached.cfg

4.4 检查Nagios配置是否有误:/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg

4.5 重启Nagios,并登录Nagios web监控界面查看:
/etc/init.d/nagios restart
登录:http://localhost/nagios

4.3 使用MemAdmin监控管理工具来实现
________________________________________
MemAdmin是一款基于 PHP5 & JQuery、 可视化的Memcached管理与监控工具,使用PHP开发,体积小,操作简单。主页请戳http://www.junopen.com/memadmin/

主要功能:
• 服务器参数监控:STATS、SETTINGS、ITEMS、SLABS、SIZES实时刷新
• 服务器性能监控:GET、DELETE、INCR、DECR、CAS等常用操作命中率实时监控
• 支持数据遍历,方便对存储内容进行监视
• 支持条件查询,筛选出满足条件的KEY或VALUE
• 数组、JSON等序列化字符反序列显示
• 兼容memcache协议的其他服务,如Tokyo Tyrant (遍历功能除外)
• 支持服务器连接池,多服务器管理切换方便简洁
具体配置安装和使用不再赘述,可自行查看相关文档,lol

5 总结
________________________________________
本文就Memcached原理、安装、分布式安装和监控等一一较为详细的介绍,关于高阶的Memcached内部实现原理,还有待研究和学习

windows /Linux 系统运维交流群 30733661 欢迎各位圈内好友加盟

蜗牛的梦想
Copyright © Linux系统运维联盟 保留所有权利.   Theme  Ality 京公网安备11011402000199号 京ICP备14047887号

用户登录