用到memcached,记下
memcached中保存的数据都存储在memcached内置的内存存储空间中。
由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。
另外,内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。
memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。
memcached是“分布式”缓存服务器,但服务器端并没有分布式功能。
各个memcached不会互相通信以共享信息。进行分布式完全取决于客户端的实现。
memcached需要 libevent库 #yum install libevent libevent-devel
$ wget http://www.danga.com/memcached/dist/memcached-1.×.×.tar.gz
$ tar zxf memcached-1.×.×.tar.gz
$ cd memcached-1.×.×$ ./configure
$ make
$ sudo make install
#/usr/local/bin/memcached -p 11211 -m 64m -d
选项 |
说明 |
-p |
使用的TCP端口。默认为11211 |
-m |
最大内存大小。默认为64M |
-vv |
用very vrebose模式启动,调试信息和错误输出到控制台 |
-d |
作为daemon在后台启动 |
memcached客户端API
:http://www.danga.com/memcached/apis.bml
Perl的memcached客户端有
- Cache::Memcached
- Cache::Memcached::Fast
- Cache::Memcached::libmemcached
等几个CPAN模块。
http://search.cpan.org/dist/Cache-Memcached/
#!/usr/bin/perl
use strict;
use warnings;
use Cache::Memcached;
my $key = "foo";
my $value = "bar";
my $expires = 3600; # 1 hour
my $memcached = Cache::Memcached->new({
servers => ["127.0.0.1:11211"],
compress_threshold => 10_000
});
$memcached->add($key, $value, $expires);
my $ret = $memcached->get($key);
print "$ret\n";
在这里,为Cache::Memcached指定了memcached服务器的IP地址和一个选项,以生成实例。
Cache::Memcached常用的选项如下所示。
选项 |
说明 |
servers |
用数组指定memcached服务器和端口 |
compress_threshold |
数据压缩时使用的值 |
namespace |
指定添加到键的前缀 |
另外,Cache::Memcached通过Storable模块可以将Perl的复杂数据序列化之后再保存,
因此散列、数组、对象等都可以直接保存到memcached中。
保存数据
向memcached保存数据的方法有
- add
- replace
- set
它们的使用方法都相同:
my $add = $memcached->add( '键', '值', '期限' );
my $replace = $memcached->replace( '键', '值', '期限' );
my $set = $memcached->set( '键', '值', '期限' );
向memcached保存数据时可以指定期限(秒)。不指定期限时,memcached按照LRU算法保存数据。
这三个方法的区别如下:
选项 |
说明 |
add |
仅当存储空间中不存在键相同的数据时才保存 |
replace |
仅当存储空间中存在键相同的数据时才保存 |
set |
与add和replace不同,无论何时都保存 |
获取数据
获取数据可以使用get和get_multi方法。
my $val = $memcached->get('键');
my $val = $memcached->get_multi('键1', '键2', '键3', '键4', '键5');
一次取得多条数据时使用get_multi。get_multi可以非同步地同时取得多个键值,
其速度要比循环调用get快数十倍。
删除数据
删除数据使用delete方法,不过它有个独特的功能。
$memcached->delete('键', '阻塞时间(秒)');
删除第一个参数指定的键的数据。第二个参数指定一个时间值,可以禁止使用同样的键保存新数据。
此功能可以用于防止缓存数据的不完整。但是要注意,set函数忽视该阻塞,照常保存数据
增一和减一操作
可以将memcached上特定的键值作为计数器使用。
my $ret = $memcached->incr('键');
$memcached->add('键', 0) unless defined $ret;
增一和减一是原子操作,但未设置初始值时,不会自动赋成0。因此,
应当进行错误检查,必要时加入初始化操作。
Cache::Memcached的分布式方法
Perl的memcached客户端函数库Cache::Memcached是
memcached的作者Brad Fitzpatrick的作品,可以说是原装的函数库了。
该函数库实现了分布式功能,是memcached标准的分布式方法。
根据余数计算分散
Cache::Memcached的分布式方法简单来说,就是“根据服务器台数的余数进行分散”。
求得键的整数哈希值,再除以服务器台数,根据其余数来选择服务器。
下面将Cache::Memcached简化成以下的Perl脚本来进行说明。
use strict;
use warnings;
use String::CRC32;
my @nodes = ('node1','node2','node3');
my @keys = ('tokyo', 'kanagawa', 'chiba', 'saitama', 'gunma');
foreach my $key (@keys) {
my $crc = crc32($key); # CRC値
my $mod = $crc % ( $#nodes + 1 );
my $server = $nodes[ $mod ]; # 根据余数选择服务器
printf "%s => %s\n", $key, $server;
}
Cache::Memcached在求哈希值时使用了CRC。
首先求得字符串的CRC值,根据该值除以服务器节点数目得到的余数决定服务器。
上面的代码执行后输入以下结果:
tokyo => node2
kanagawa => node3
chiba => node2
saitama => node1
gunma => node1
根据该结果,“tokyo”分散到node2,“kanagawa”分散到node3等。
多说一句,当选择的服务器无法连接时,Cache::Memcached会将连接次数
添加到键之后,再次计算哈希值并尝试连接。这个动作称为rehash。
不希望rehash时可以在生成Cache::Memcached对象时指定“rehash => 0”选项。
根据余数计算分散的缺点
余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。
那就是当添加或移除服务器时,缓存重组的代价相当巨大。
添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,
从而影响缓存的命中率。用Perl写段代码来验证其代价。
use strict;
use warnings;
use String::CRC32;
my @nodes = @ARGV;
my @keys = ('a'..'z');
my %nodes;
foreach my $key ( @keys ) {
my $hash = crc32($key);
my $mod = $hash % ( $#nodes + 1 );
my $server = $nodes[ $mod ];
push @{ $nodes{ $server } }, $key;
}
foreach my $node ( sort keys %nodes ) {
printf "%s: %s\n", $node, join ",", @{ $nodes{$node} };
}
这段Perl脚本演示了将“a”到“z”的键保存到memcached并访问的情况。
将其保存为mod.pl并执行。
首先,当服务器只有三台时:
$ mod.pl node1 node2 nod3
node1: a,c,d,e,h,j,n,u,w,x
node2: g,i,k,l,p,r,s,y
node3: b,f,m,o,q,t,v,z
结果如上,node1保存a、c、d、e……,node2保存g、i、k……,
每台服务器都保存了8个到10个数据。
接下来增加一台memcached服务器。
$ mod.pl node1 node2 node3 node4
node1: d,f,m,o,t,v
node2: b,i,k,p,r,y
node3: e,g,l,n,u,w
node4: a,c,h,j,q,s,x,z
添加了node4。可见,只有d、i、k、p、r、y命中了。像这样,添加节点后
键分散到的服务器会发生巨大变化。26个键中只有六个在访问原来的服务器,
其他的全都移到了其他服务器。命中率降低到23%。在Web应用程序中使用memcached时,
在添加memcached服务器的瞬间缓存效率会大幅度下降,负载会集中到数据库服务器上,
有可能会发生无法提供正常服务的情况。
mixi的Web应用程序运用中也有这个问题,导致无法添加memcached服务器。
但由于使用了新的分布式方法,现在可以轻而易举地添加memcached服务器了。
这种分布式方法称为 Consistent Hashing。
Consistent Hashing
关于Consistent Hashing的思想,mixi株式会社的开发blog等许多地方都介绍过,
这里只简单地说明一下。
Consistent Hashing的简单说明
Consistent Hashing如下所示:首先求出memcached服务器(节点)的哈希值,
并将其配置到0~232
的圆(continuum)上。
然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。
然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。
如果超过232
仍然找不到服务器,就会保存到第一台memcached服务器上。
图4 Consistent Hashing:基本原理
从上图的状态中添加一台memcached服务器。余数分布式算法由于保存键的服务器会发生巨大变化
而影响缓存的命中率,但Consistent Hashing中,只有在continuum上增加服务器的地点逆时针方向的
第一台服务器上的键会受到影响。
图5 Consistent Hashing:添加服务器
因此,Consistent Hashing最大限度地抑制了键的重新分布。
而且,有的Consistent Hashing的实现方法还采用了虚拟节点的思想。
使用一般的hash函数的话,服务器的映射地点的分布非常不均匀。
因此,使用虚拟节点的思想,为每个物理节点(服务器)
在continuum上分配100~200个点。这样就能抑制分布不均匀,
最大限度地减小服务器增减时的缓存重新分布。
通过下文中介绍的使用Consistent Hashing算法的memcached客户端函数库进行测试的结果是,
由服务器台数(n)和增加的服务器台数(m)计算增加服务器后的命中率计算公式如下:
(1 - n/(n+m)) * 100
支持Consistent Hashing的函数库
本连载中多次介绍的Cache::Memcached虽然不支持Consistent Hashing,
但已有几个客户端函数库支持了这种新的分布式算法。
第一个支持Consistent Hashing和虚拟节点的memcached客户端函数库是
名为libketama的PHP库,由last.fm开发。
至于Perl客户端,连载的第1次
中介绍过的Cache::Memcached::Fast和Cache::Memcached::libmemcached支持
Consistent Hashing。
两者的接口都与Cache::Memcached几乎相同,如果正在使用Cache::Memcached,
那么就可以方便地替换过来。Cache::Memcached::Fast重新实现了libketama,
使用Consistent Hashing创建对象时可以指定ketama_points选项。
my $memcached = Cache::Memcached::Fast->new({
servers => ["192.168.0.1:11211","192.168.0.2:11211"],
ketama_points => 150
});
另外,Cache::Memcached::libmemcached 是一个使用了Brain Aker开发的C函数库libmemcached的Perl模块。
libmemcached本身支持几种分布式算法,也支持Consistent Hashing,
其Perl绑定也支持Consistent Hashing。
分享到:
相关推荐
Chapter 10: Memcached Functions for MySQL Chapter 11: Apache Chapter 12: Contact List Application Chapter 13: mod_perl Chapter 14: Using mod_perl Handlers Chapter 15: More mod_perl Chapter 16: ...
ASP源码—Memcached For Classic ASP v1.0.9.0.zip是一个针对经典ASP(Active Server Pages)环境的Memcached客户端实现。Memcached是一种高性能的分布式内存对象缓存系统,广泛应用于减轻数据库负载,提高Web应用...
ActivePerl 5.8.8.819 for Windows 下载地址:[华军软件园] [中国站长站] 注意事项: 迅雷、Skype、PPLive、BT等软件启动后默认会占用80端口,导致Apache无法启动。解决方法:先关闭这些软件,启动完APMServ...
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 设置session共享 proxy_session off; proxy_cache_bypass $cookie_session; proxy_next_upstream error timeout invalid_header ...
ActivePerl 5.8.8.819 for Windows 下载地址:[华军软件园] [中国站长站] 注意事项: 迅雷、Skype、PPLive、BT等软件启动后默认会占用80端口,导致Apache无法启动。解决方法:先关闭这些软件,启动完APMServ...
ActivePerl 5.8.8.819 for Windows 下载地址:[华军软件园] [中国站长站] 注意事项: 迅雷、Skype、BT等软件启动后默认会占用80端口,导致Apache无法启动。解决方法:先关闭这些软件,启动完APMServ之后,再...
memcached的基本设置:-p 监听的端口 -l 连接的IP地址, 默认是本机 -d start 启动memcached服务 -d restart 重起memcached服务 -d stop|shutdown 关闭正在运行的memcached服务 -d install 安装memcached服务 -d ...
名称 Cache :: Memcached :: AnyEvent-AnyEvent兼容的Memcached客户端 概要 ... warn "got $value for $key"; }); $memd->disconnect(); # use ketama algorithm instead of the traditional one m
Memcached 支持多种编程语言的客户端库,如 Python、Java、PHP、Ruby、Perl 等。以 Java 为例,我们可以使用 `spymemcached` 库。 - 添加 `spymemcached` 依赖到项目中(如 Maven 项目): ```xml <groupId>...
Redis Desktop Manager for windows是一款可以跨平台的redis可视化工具,兼容win、mac等操作系统,该工具可以说很大程度上弥补了memcached这类key/value存储的不足,为Java、C/C++、C#、PHP、JavaScript、Perl、...
6. **启用UDF**:有两种方式使Memcached Functions生效,一是通过MySQL shell执行`install_functions.sql`,二是运行`install.pl` Perl脚本。 7. **测试Memcached Functions**:创建一个简单的测试环境,例如一个...
redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,...
Redis Desktop Manager for windows是一款可以跨平台的redis可视化工具,兼容win、mac等操作系统,该工具可以说很大程度上弥补了memcached这类key/value存储的不足,为Java、C/C++、C#、PHP、JavaScript、Perl、...
4. **缓存层**:利用缓存技术(如Redis或Memcached)提高数据访问速度,减少对数据库的直接压力。 5. **日志和监控**:记录系统运行状态,提供实时监控,及时发现并解决问题。 6. **API接口**:与第三方系统集成,...
redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,...
9. **PHP性能优化**:包括配置优化、代码优化、缓存技术如APC、Memcached、Redis等。 10. **安全实践**:防止SQL注入、XSS跨站脚本攻击、CSRF跨站请求伪造等,以及使用`htmlspecialchars`、`strip_tags`等函数进行...
1. **基础语法**:包括变量、常量、数据类型、运算符、流程控制(如if-else、switch-case、for、while等)、数组、字符串处理等基本概念和操作。 2. **函数**:PHP拥有庞大的内置函数库,如数学函数、字符串函数、...
其语法与C和Perl类似,易于学习,同时拥有强大的功能,支持多种数据库连接,如MySQL、PostgreSQL等。 1. 变量:PHP的变量以$符号开头,无须提前声明,数据类型包括整型、浮点型、字符串、数组、对象、布尔型和NULL...
AWS是适用于所有Web开发人员和Web设计人员的Web服务器的特殊版本,它基于Apache,NGINX,Subversion for Apache,Perl,PHP和MySQL的多个版本,PostgreSQL,MongoDB,SQLite,Filezilla FTP Server,memcached,...