16.2.3.4 通过Perl使用 MySQL 和memcached

该模块为 Memcache 协议提供了一个本地接口,并为memcachedCache::Memcached提供的核心功能提供支持。使用操作系统的包管理系统或使用以下命令安装模块: CPAN

Press CTRL+C to copy
#> perl -MCPAN -e 'install Cache::Memcached'

要通过模块从 Perl 使用memcachedCache::Memcached,首先要创建一个新 Cache::Memcached对象来定义服务器列表和连接的其他参数。唯一的参数是包含缓存接口选项的散列。例如,要创建一个使用三个 memcached服务器的新实例:

Press CTRL+C to copy
use Cache::Memcached; my $cache = new Cache::Memcached { 'servers' => [ '198.51.100.100:11211', '198.51.100.101:11211', '198.51.100.102:11211', ], };
笔记

Cache::Memcached接口与多个服务器一起使用时,API 会自动在组中的所有服务器上执行某些操作。例如,通过 获取统计信息 Cache::Memcached返回一个散列,其中包含逐个主机的数据,以及组中所有服务器的一般统计信息。

通过将选项指定为选项散列的一部分,您可以在创建缓存对象实例时设置其他属性。或者,您可以在实例上使用相应的方法:

  • servers或方法 set_servers():指定要使用的服务器列表。服务器列表应该是对服务器数组的引用,每个元素都是地址和端口号的组合(用冒号分隔)。您还可以通过 Unix 套接字指定本地连接(例如/tmp/sock/memcached)。要指定具有权重的服务器(指示服务器在散列过程中应使用的频率),请指定一个包含 memcached服务器实例和权重数的数组引用。数字越大优先级越高。

  • compress_threshold或 method set_compress_threshold():指定压缩值时的阈值。大于指定数量的值 zlib在存储和检索期间会自动压缩(使用 )。

  • no_rehash或方法 set_norehash():如果原始选择不可用,则禁用查找新服务器。

  • readonly或方法 :禁用对内存缓存服务器 set_readonly()的写入 。

配置Cache::Memcached对象实例后,您可以使用set()get()方法从memcached服务器存储和检索信息。Storable存储在缓存中的对象使用该模块 自动序列化和反序列化。

Cache::Memcached接口支持以下用于存储/检索数据的方法,并与表中所示的通用方法相关。

Cache::Memcached功能 等效的通用方法
get() 通用get()的。
get_multi(keys) keys仅使用一个查询从内存缓存中获取多个。返回键值对的哈希引用。
set() 通用set()的。
add() 通用add()的。
replace() 通用replace()的。
delete() 通用delete()的。
incr() 通用incr()的。
decr() 通用decr()的。

下面是将 memcached与 Perl 和 Cache::Memcached模块一起使用的完整示例:

Press CTRL+C to copy
#!/usr/bin/perl use Cache::Memcached; use DBI; use Data::Dumper; # Configure the memcached server my $cache = new Cache::Memcached { 'servers' => [ 'localhost:11211', ], }; # Get the film name from the command line # memcached keys must not contain spaces, so create # a key name by replacing spaces with underscores my $filmname = shift or die "Must specify the film name\n"; my $filmkey = $filmname; $filmkey =~ s/ /_/; # Load the data from the cache my $filmdata = $cache->get($filmkey); # If the data wasn't in the cache, then we load it from the database if (!defined($filmdata)) { $filmdata = load_filmdata($filmname); if (defined($filmdata)) { # Set the data into the cache, using the key if ($cache->set($filmkey,$filmdata)) { print STDERR "Film data loaded from database and cached\n"; } else { print STDERR "Couldn't store to cache\n"; } } else { die "Couldn't find $filmname\n"; } } else { print STDERR "Film data loaded from Memcached\n"; } sub load_filmdata { my ($filmname) = @_; my $dsn = "DBI:mysql:database=sakila;host=localhost;port=3306"; $dbh = DBI->connect($dsn, 'sakila','password'); my ($filmbase) = $dbh->selectrow_hashref(sprintf('select * from film where title = %s', $dbh->quote($filmname))); if (!defined($filmname)) { return (undef); } $filmbase->{stars} = $dbh->selectall_arrayref(sprintf('select concat(first_name," ",last_name) ' . 'from film_actor left join (actor) ' . 'on (film_actor.actor_id = actor.actor_id) ' . ' where film_id=%s', $dbh->quote($filmbase->{film_id}))); return($filmbase); }

该示例使用 Sakila 数据库,从数据库中获取电影数据并将电影和演员的复合记录写入memcached。当为不存在的电影调用它时,您会得到以下结果:

Press CTRL+C to copy
$> memcached-sakila.pl "ROCK INSTINCT" Film data loaded from database and cached

访问已添加到缓存中的电影时:

Press CTRL+C to copy
$> memcached-sakila.pl "ROCK INSTINCT" Film data loaded from Memcached