PHP 通过 PECL 扩展提供对 Memcache 函数的支持。要启用 PHPmemcache
扩展,
请在从源代码构建时
使用配置--enable-memcache
选项
构建 PHP。
如果您在基于 Red Hat 的服务器上安装,则可以安装php-pecl-memcache
RPM:
#> yum --install php-pecl-memcache
在基于 Debian 的发行版上,使用
php-memcache
包。
php.ini
要设置全局运行时配置选项,请在文件
中指定配置选项值
。下表提供了每个全局运行时配置选项的名称、默认值和说明。
配置选项 | 默认 | 描述 |
---|---|---|
memcache.allow_failover |
1个 | 指定如果选择的第一台服务器出现故障,是否应查询列表中的另一台服务器。 |
memcache.max_failover_attempts |
20 | 指定在返回失败之前要尝试的服务器数。 |
memcache.chunk_size |
8192 | 定义用于与 memcached服务器交换数据的网络块的大小。 |
memcache.default_port |
11211 | 定义与memcached服务器通信时使用的默认端口 。 |
memcache.hash_strategy |
标准 | 指定要使用的哈希策略。设置为
consistent 允许在池中添加或删除服务器,而不会导致密钥重新映射到其他服务器。设置为 时
standard ,将使用较旧的(模块)策略,该策略可能使用不同的服务器进行存储。 |
memcache.hash_function |
crc32 | 指定将键映射到服务器时要使用的函数。
crc32 使用标准的 CRC32 散列。
fnv 使用 FNV-1a 哈希算法。 |
要创建到Memcached服务器的连接,请创建一个新Memcache
对象,然后指定连接选项。例如:
<?php
$cache = new Memcache;
$cache->connect('localhost',11211);
?>
这会立即打开到指定服务器的连接。
要使用多个内存缓存服务器,您需要使用以下方法将服务器添加到内存缓存对象
addServer()
:
bool Memcache::addServer ( string $host [, int $port [, bool $persistent
[, int $weight [, int $timeout [, int $retry_interval
[, bool $status [, callback $failure_callback
]]]]]]] )
模块内的服务器管理机制
是接口的关键部分,因为它控制到memcachedphp-memcache
实例 的主要接口
以及如何通过哈希机制选择不同的实例。
要创建到两个 memcached实例的简单连接:
<?php
$cache = new Memcache;
$cache->addServer('198.51.100.100',11211);
$cache->addServer('198.51.100.101',11211);
?>
在这种情况下,实例连接并未显式打开,而是仅在您尝试存储或检索值时打开。要启用与
memcached实例的持久连接,请将
$persistent
参数设置为 true。这是默认设置,并使连接保持打开状态。
为了帮助控制密钥到不同实例的分发,请使用全局memcache.hash_strategy
设置。这设置了用于选择的散列机制。您还可以为每个服务器添加另一个权重,这会有效地增加实例条目在实例列表中出现的次数,从而增加该实例被选中的可能性高于其他实例。要设置权重,请将$weight
参数的值设置为大于 1。
设置和获取信息的功能与 提供的通用功能接口相同,
memcached
如下表所示。
PECLmemcache 函数 |
泛型函数 |
---|---|
get() |
通用get() 的。 |
set() |
通用set() 的。 |
add() |
通用add() 的。 |
replace() |
通用replace() 的。 |
delete() |
通用delete() 的。 |
increment() |
通用incr() 的。 |
decrement() |
通用decr() 的。 |
下面提供了 PECLmemcache
接口的完整示例。当用户提供电影名称时,代码会从 Sakila 数据库加载电影数据。存储到memcached
实例中的数据记录为
mysqli
结果行,API 会自动为您序列化该信息。
<?php
$memc = new Memcache;
$memc->addServer('localhost','11211');
if(empty($_POST['film'])) {
?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Simple Memcache Lookup</title>
</head>
<body>
<form method="post">
<p><b>Film</b>: <input type="text" size="20" name="film"></p>
<input type="submit">
</form>
<hr/>
<?php
} else {
echo "Loading data...\n";
$film = htmlspecialchars($_POST['film'], ENT_QUOTES, 'UTF-8');
$mfilms = $memc->get($film);
if ($mfilms) {
printf("<p>Film data for %s loaded from memcache</p>", $mfilms['title']);
foreach (array_keys($mfilms) as $key) {
printf("<p><b>%s</b>: %s</p>", $key, $mfilms[$key]);
}
} else {
$mysqli = mysqli('localhost','sakila','<replaceable>password</replaceable>','sakila');
if (mysqli_connect_error()) {
sprintf("Database error: (%d) %s", mysqli_connect_errno(), mysqli_connect_error());
exit;
}
$sql = sprintf('SELECT * FROM film WHERE title="%s"', $mysqli->real_escape_string($film));
$result = $mysqli->query($sql);
if (!$result) {
sprintf("Database error: (%d) %s", $mysqli->errno, $mysqli->error);
exit;
}
$row = $result->fetch_assoc();
$memc->set($row['title'], $row);
printf("<p>Loaded (%s) from MySQL</p>", htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8');
}
}
?>
</body>
</html>
使用 PHP, 只要 PHP 和关联的 Apache 实例保持运行,与memcached实例的连接就会保持打开状态。在正在运行的实例中从列表中添加或删除服务器时(例如,当启动另一个提到额外服务器的脚本时),连接是共享的,但脚本仅在脚本中显式配置的实例中进行选择。
为确保脚本中服务器列表的更改不会导致问题,请确保使用一致的散列机制。