注册 | 登录
欢迎注册会员

当前位置:首页 > 狗万 怎么玩 > PHP技术 > 正文

Memcached在大型网站中应用

来源:程序人生 【 】 浏览:849 添加日期:2016-09-16 22:57:58 我要评论(0)

狗万 怎么玩? ? ? ? memcached是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采用。起初作者编写它可能是为了提高动态网页应用,为了减轻数据库检索的压力,来做的这个缓存系统。它的缓存是一种分布式的,也就是可以允许不同主机上的多个用户同时访问这个缓存系统, 这种方法不仅解决了共享内存只能是单机的弊端, 同时也解决了数据库检索的压力,最大的优点是提高了访问获取数据的速度!基于memcached作者对分布式cache的理解和解决方案。memcached完全可以用到其他地方 比如分布式数据库, 分布式计算等领域。

1、 memcached 协议理解

memcache是为了加快http://www.livejournal.com/访问速度而诞生的一个项目。

它的官方主页是:http://www.danga.com/memcached/

目前在网站开发中应用较少,主要的应用有:

http://www.danga.com/memcached/users.bml

在国内的网站开发中,还很少没见到有应用的,中文资料十分匮乏。

工作机制:通过在内存中开辟一块区域来维持一个大的hash表来加快页面访问速度,和数据库是独立的。但是目前主要用来缓存数据库的数据。允许多个server通过网络形成一个大的hash,用户不必关心数据存放在哪,只调用相关接口就可。存放在内存的数据通过LRU算法进行淘汰出内存。同时可以通过删除和设置失效时间来淘汰存放在内存的数据。

2、 memcached 使用入门

2.1 memcached的安装

? ?<1>memcached服务的安装

? 先检查linux内核版本,建议将memcached 安装在2.6以上。

? 因为memcached 需要用到libevent和 epoll 。

memcached安装前首先确定你的服务器上面安装了libevent库,

libevent下载地址( http://www.monkey.org/~provos/libevent/)。

下载memcached的源码( http://www.danga.com/memcached/download.bml)。

Memcached最初是用perl写的,现在的版本是用c写的。

下载后拷贝到一个目录,安装需要root用户来执行

tar -zxvf memcached-1.1.12.tar.gz

cd memcached-1.1.12

./configure

这里必须先要configure, 它会检测你的系统情况,然后生成一个config.h文件和其它的几个文件,另外和其它的configure一样,你可以配置它的安装路径等等。默认应用程序安装在/usr/local/bin目录下。

make //编译

make install //安装

<2>memcached客户端的安装

根据memcached协议,用户可以自己写出符合自己要求的客户端程序。目前http://www.danga.com/memcached/download.bml

提供perl,c,java,python,php等客户端程序供下载和参考。下面我就以perl客户端程序为例说明客户端的安装:

下载后拷贝到一个目录,安装需要root用户来执行

tar -zxvf Cache-Memcached-1.14.tar.gz

cd Cache-Memcached-1.14

perl makefile.pl

make

make install

make test

这样就安装好了memcahced, 启动memcached就可使用分布式缓存系统了!

2.2 快速入门

<1> memcached服务的启动?

memcached的启动非常简单,它没有配置文件,只要配置好几个参数就可以使用了。下面我以一个实际应用的例子,具体说明一下:

memcached –d –m 500 ?-l 64.128.191.151 -p 11211 -vv >>/var/www/kelly/test/logs/memcached_$$.log

启动的这个memcached为一个后台守护进程模式(-d), 然后缓存的空间为500M(-m), 监听(-l)服务器64.128.191.15的11211号端口(-p).,将日志写道/var/www/kelly/test/logs/memcached_$$.log(-vv)。

其实memcached的参数也非常的有限,就下面这几个:

? ?-p port number to listen on?

? ?-l interface to listen on, default is INDRR_ANY?

? ?-d run as a daemon?

? ?-r maximize core file limit?

? ?-u assume identity of (only when run as root)?

? ?-m max memory to use for items in megabytes, default is 64 MB?

? ?-M return error on memory exhausted (rather than removing items)?

? ?-c max simultaneous connections, default is 1024?

? ? ? ? ? ? ?-k lock down all paged memory?

? ?-v verbose (print errors/warnings while in event loop)?

? ?-vv very verbose (also print client commands/reponses)?

? ?-h print this help and exit?

? ?-i print memcached and libevent license?

我们也可以将这个启动脚本写道/etc/rc.d或者/erc/rc.local,这样可以在服务器启动时候执行。

<2> memcached客户端的连接

下面我就以perl客户端程序为例说明客户端的连接:

启动两个memcached server

memcached –d –m 500 ?-l 64.128.191.151 -p 11211 -vv >>/var/www/kelly/test/logs/memcached_$$.log

memcached –d –m 500 ?-l 64.128.191.151 -p 11212 -vv >>/var/www/kelly/test/logs/memcached_$$.log

perl客户端程序

#!/usr/bin/perl
use?Cache::Memcached;
my?$memd?=?new?Cache::Memcached?{
????'servers'?=>?[?"64.128.191.15:11211"?,?"64.128.191.15:11212"],
??};
my?$val?=?$memd->get(?"my_key"?);
if?(?$val?)
{
???print?"Value?is?'$val'
";
}
#?Set?a?value
$memd->set("my_key",?"123");
$memd->disconnect_all();

?运行测试

$ perl test-memcache.pl

$ perl test-memcache.pl

Value is '123'

可以看到,第一次没有取得my_key,第二次从memcached中得到my_key的值。

同时通过查看日志,可以发现的确存储在两个memcache ?server中。

这个简单的例子,解释了如何在memcached中存取数据,以及memcache是真正的分布式缓存系统。

当然,这还只是很简单的例子,体现不出memcache的优势,下面将通过一个很具体的例子,给出详细的应用。

3、 memcached在Zorpia的应用

http://www.zorpia.com 是一个网页相册,博客,交友,论坛的大型网站公司。现在已有超过140万活跃使用者遍布美国,香港,东南亚,欧洲,澳洲,亚洲等其它地区。每天的访问量都在增长,已成为全世界排名第五的社会生活关系网。

Memcached也采用了memcached来提高网站的访问速度,并且取得了很好的效果,我在负责zorpia的memcached项目时候积累了一些经验,主要的做法如下:

1) 通过对memcache的perl客户端进行包装,定制自己的客户端。

2) 通过制定符合zorpia规范的hash key命名规范

? ?? memcache中需要存储的内容的key均由string组成。

这个string统一由一个memcache.pm的subroutine来实现。(假设这个subroutine是 get_key() )

? ?? memcache中存放两种形式的数据

? (1) result of SQL query :?

? (2) 普通变量(variable)

? 这两种数据的key的组合方式是不相同的,由get_key进行判断和完成

? ?? 关于get_key 和 naming rule

? get_key subroutine完成所有memcache key的命名,naming rule也是在它里边体现:

? (1)输入参数 -- hash结构,里边定义了当前需要存放的数据的信息

? ? ? 结构

? (2)返回值 -- string,返回数据的key_name

?必须确定 get_key 的传入hash的结构,

? ? ? hash中主要有两个元素

? ? ? type --- 定义当前数据结构的类型 ,有 'var' , 'sql'两种值

? ? ? object --- 存放当前数据结构的详细信息,

? ? ? 当 type eq 'var'时,object表示变量的名字,该名字由程序员指定

? ? ? 当 type eq 'sql'时,object包含所存放sql的主要基本信息,hash结构,也由程序员按照规则制定

? ? ?## 当variable 数据类型,比较简单

? ? ?$var_hash = {

? ? ? ? ? ? ?type => 'var', ? ? ?## var表示当前类型是 variable ??

? ? ? ? ? ? ?object => 'language', ?## ?language代表variable的名字

? ? ?};

生成的key是Zorpia::var| language

? ? ?## sql 数据

? ? ?比如select first_name from user where user_id =2那么hash为

? ? ?$sql_hash = {

? ? ? ? ? ? ?type => 'sql',

? ? ? ? ? ? ?object => {

? ? ? ? ? ? ? ? ?table => {table2=>"user",}, ? ? ? ? ## sql 查询的表

? ? ? ? ? ? ? ? ?column => {column1=>"first_name",}, ?## sql所要查询的column?

? ? ? ? ? ? ? ? ?condition => { user_id =>"2",}, ?## sql条件

? ? ? ? ? ? ?},

? ? ?};

生成的key是Zorpia::sql|user|first_name| user_id =2

? ? ?get_key subroutine必须对传入hash进行判断,对不同类型的数据按照不同的方式组合,形成key,返回给使用者。这个key,必须保证其唯一性:

比如:所有字母小写,一些数组在组合成key之前必须首先排序

? ? get_key函数

sub?get_key{
my?$hash?=?shift;
return?undef?unless?$hash?&&?ref?$hash?eq?"HASH";
my?$type?=?$hash->{type};
my?$key_name;
if?($type?eq?'sql')?{
my?($table_key,$column_key,$condition_key);
$table_key=_get_key($hash->{object}->{table});
$column_key=_get_key($hash->{object}->{column});
$condition_key=_get_key($hash->{object}->{condition});
$key_name?=?join('|',$type,$table_key,$column_key,$condition_key);
#Currently?the?length?limit?of?a?key?is?set?at?250?characters
if?(length($key_name)>250)
{
$key_name=substr(0,250,$key_name);?
}
}
elsif($type?eq?'var')
{
$key_name?=?join('|',$type,$hash->{object});
}
return?$key_name;
}
sub?_get_key
{
my?$hash=shift;
return?undef?unless?$hash?&&?ref?$hash?eq?"HASH";
my?($t,$ret,$i);
foreach?$i?(sort?keys?%$hash)
{
??$i=~s/^s+|s+$//g;
??$hash->{$i}=~s/^s+|s+$//g;
???push(@$t,lc("$i=$hash->{$i}"));
}
$ret=join(':',sort?{?$a?cmp?$b?}?@$t);
return?$ret;????
}

3) 制定需要应用memcached的规则

?经常访问的表user,user_details

?合理设定变量在memcached的生存周期

?将活跃用户的信息预先导入到memcached

?分别在多台机器上启动多个memcached服务

?编写脚本监控memcached服务是否活动

4) User表的具体应用举例

? 在 select时候

先查询memcahce里有没有,有的话,返回;否则从数据库select,在memcache里设置,返回。

my?$sql_hash?=?{
?????????type?=>?'sql',
?????????object?=>?{
???????table?=>?{table1=>"user",},
???????column?=>?{column1=>"user_id",},
???????condition?=>?{email=>$user_id,},
????????},
?????????};
????????my?$key=Zorpia::MemCache::get_key($sql_hash);??
????????my?$user_id_by_email=Zorpia::MemCache::get($key);
???????if(!$user_id_by_email)
????????{
????????my?$sth;
????????my?$query?="select?user_id?from?user?where?email=?";
????????$sth?=?$dbh->prepare($query);
????????$sth->execute($user_id);
????????my?$user1?=?$sth->fetchrow_hashref();
????????$user_id_by_email=$user1->{'user_id'};
????????Zorpia::MemCache::set($key,$user_id_by_email,1800);
????????}

??在 update,insert,delete时候

先在数据库update,insert,delete,在memcache里设置,返回。

&Zorpia::DB::data_entry_no_return($dbh,"user","COUNT(*)","$account_information_insert_statement?user_id=$current_user_id",?"user_id=$current_user_id");
?#add?by?kelly
?my?$sql_hash?=?{
?????????type?=>?'sql',
?????????object?=>?{
???????table?=>?{table1=>"user",},
???????column?=>?{column1=>"user_id",},
???????condition?=>?{user_id=>$current_user_id,},
????????},
?????????};
??my?$key=Zorpia::MemCache::get_key($sql_hash);
??my?$query?=?"SELECT?*,?user_id?AS?id??FROM???user??WHERE?user_id=?";
??my?$sth_memc?=?$dbh->prepare($query);
??$sth_memc->execute($current_user_id);
??my?$user_memc?=?$sth_memc->fetchrow_hashref();
??&Zorpia::MemCache::set($key,$user_memc,21600);

4、 memcached的应用展望

使用了memcached以后, 我发现以前做过的很多的项目都可以应用它提高效率,包括最近做的“大单追踪”, “数码搜索”等等。当然既然memcahced是分布式的缓存系统,那么它就是建立了一个分布式的平台, 我们可以用它来进行分布式的记数, 因为对于一个键值key我们可以设置它的数值以及有效期在参数中,另外还可以重新设置这个键值的数值。 所以我总结了一下目前可以应用到的地方:

<1>.数据库检索结果的缓存,也就是说可以有机的和数据库结合起来应用,提高效率。

? ? 这也是目前memcached用到的最多的地方,比如用于大型网站等。

可以这样来实现:

打开memcached服务器连接

编写sql语句, 同时算出它的一个hash key值

获取这个hash值的memcached保存数据(get)

如果获取的这个hash值的数据存在。返回

否则连接数据库查找

把这个查找结果保存在memcached中(set),可以设置有效期

返回查找结果

?<2>.分布式计算

?<3>.分布式共享数据

?总之,memcached的机制比较灵活,可以适用于一切需要分布式缓存数据的地方,随着memcached逐渐为人所知,必将在更多的分布式应用领域大放异彩。



你浏览的文章是 - 《Memcached在大型网站中应用》!
文章出处:https://www.procedurelife.com/content/akkjhf.html
100% (3)
0% (0)
评论0
头像 游客
1 2