Memcache 函数

目录

添加备注

用户贡献的备注 13 则备注

3
ed at me3inc dot com
17 年前
关于安装 memcache 扩展

我遇到了各种各样的麻烦才能将它连接起来,因为在我阅读的所有说明中,我从未获得最后也是最重要的一步 - 您必须拥有一个 php.ini,并且在其中包含“extension=memcache.so”。

所以,步骤
首先 - 使用 --enable-memcache 进行 ./configure。这应该显示在您的 phpinfo() 的顶部(即使 memcache 扩展的任何部分都无法正常工作)。

第二
要么 pecl install memcache
或者
下载源代码
tar -xzvf [thesourcetarball]
phpize
./configure
make
make install

最后:将 extension=memcache.so 添加到您的 php.ini 中。(如果您没有,它应该放在 php 被调用的根目录中,例如 /usr/local/lib)

调用 phpinfo(),您应该看到一个 memcache 部分。
2
mogmios at gmail dot com
16 年前
当为 Apache/PHP 安装 memcache 模块,其位置非标准时,似乎在配置构建时无法定义位置。您会收到错误,抱怨无法找到 php_session.h。我修改了 configure 以尝试 PREFIX 位置,这似乎也运行良好。

if test -f "${prefix}/include/php/ext/session/php_session.h"; then
session_inc_path="${prefix}/include/php"
elif test -f "$abs_srcdir/include/php/ext/session/php_session.h"; then
session_inc_path="$abs_srcdir/include/php"
elif test -f "$abs_srcdir/ext/session/php_session.h"; then
session_inc_path="$abs_srcdir"
elif test -f "$phpincludedir/ext/session/php_session.h"; then
session_inc_path="$phpincludedir"
fi
1
iliya at pisem dot net
18 年前
另一个“智能”缓存聚合器
https://svn.shadanakar.org/onPHP/ trunk/core/Cache/AggregateCache.class.php
可用于多个缓存连接器 - memcached、文件系统等。
(手动删除空格)
1
Ron
18 年前
这是一个简单的 memcached 聚合器类,它将缓存分布到多个缓存服务器上。如果服务器出现故障,负载会自动重新分配。它使用持久连接。

构造函数接受一个数组数组,每个内部数组代表一个服务器,具有一个“server”(字符串)属性,即 memcached 服务器的 IP 地址或主机名,以及一个“port”(整数)属性,即 memcached 在服务器上运行的端口号。

所有现有的 memcached API 函数都已实现,除了 getStats() 和 getVersion(),它们是特定于服务器的。

<?php
class MemcachedAggregator {
var
$connections;

public function
__construct($servers) {
// 尝试建立/检索所有服务器的持久连接。
// 如果其中任何一个失败,它们就不会被放到我们的活动连接列表中。
$this->connections = array();
for (
$i = 0, $n = count($servers); $i < $n; $i++) {
$server = $servers[$i];
$con = memcache_pconnect($server['host'], $server['port']);
if (!(
$con == false)) {
$this->connections[] = $con;
}
}
}

private function
_getConForKey($key) {
$hashCode = 0;
for (
$i = 0, $len = strlen($key); $i < $len; $i++) {
$hashCode = (int)(($hashCode*33)+ord($key[$i])) & 0x7fffffff;
}
if ((
$ns = count($this->connections)) > 0) {
return
$this->connections[$hashCode%$ns];
}
return
false;
}

public function
debug($on_off) {
$result = false;
for (
$i = 0; $i < count($connections); $i++) {
if (
$this->connections[$i]->debug($on_off)) $result = true;
}
return
$result;
}

public function
flush() {
$result = false;
for (
$i = 0; $i < count($connections); $i++) {
if (
$this->connections[$i]->flush()) $result = true;
}
return
$result;
}

/// 以下未实现:
///getStats()
///getVersion()

public function get($key) {
if (
is_array($key)) {
$dest = array();
foreach (
$key as $subkey) {
$val = get($subkey);
if (!(
$val === false)) $dest[$subkey] = $val;
}
return
$dest;
} else {
return
$this->_getConForKey($key)->get($key);
}
}

public function
set($key, $var, $compress=0, $expire=0) {
return
$this->_getConForKey($key)->set($key, $var, $compress, $expire);
}

public function
add($key, $var, $compress=0, $expire=0) {
return
$this->_getConForKey($key)->add($key, $var, $compress, $expire);
}

public function
replace($key, $var, $compress=0, $expire=0) {
return
$this->_getConForKey($key)->replace
($key, $var, $compress, $expire);
}

public function
delete($key, $timeout=0) {
return
$this->_getConForKey($key)->delete($key, $timeout);
}

public function
increment($key, $value=1) {
return
$this->_getConForKey($key)->increment($key, $value);
}

public function
decrement($key, $value=1) {
return
$this->_getConForKey($key)->decrement($key, $value);
}

}
?>
0
dweller at devonweller dot com
14 年前
在 memcache PECL 扩展版本 2.2.5 中,delete 函数无法与 memcached 1.4.3 一起使用。为了解决这个问题,这里有一个 memcache PECL 扩展版本,其中包含由 harv at pringo dot com 提供的补丁。

http://code.google.com/p/phpmemcachepatch/downloads/list

安装方法:下载

http://phpmemcachepatch.googlecode.com/files/memcache-2.2.5b.tgz

然后执行

pecl install memcache-2.2.5b.tgz
0
restlessmind at I dot gmail dot HATE dot com dot SPAM
16 年前
如果你尝试在 Windows 下为 PHP 5.2 安装此模块,但它在启动时无法加载,请确保你拥有所有依赖项,包括正确的 PHP 线程安全构建版本。

我尝试了几个小时来找出为什么我无法加载 php_memcache.dll,最后使用 Dependency Walker(来自 http://www.dependencywalker.com)对 .dll 文件进行了检查。这让我意识到,虽然我使用的是 PHP 5.2.5 的非线程安全版本,但 pecl4win 提供的 .dll 期望的是 PHP 的线程安全版本。在我纠正了这个问题后,一切正常。
0
jcastromail at yahoo dot es
17 年前
您好

在 Windows 机器上运行 memcached:(在最新的 php、apache 和 memcache 中测试,使用 XP SP2)

a) 下载 php_memcache.dll,可以在 pecl 文件中找到它。

b) 将 dll 放置在扩展文件夹中(例如 c:/php/extension)。你不能错过这个文件夹,因为里面充满了 php*.dll 文件。在某些情况下,使用的扩展文件夹是 system32,这是一种非标准的放置 dll 的方式,但仍然有效。

c) 配置 php.ini
; 我像最新的扩展一样放置它
extension=php_memcache.dll

; 我不确定这一点,但不会造成伤害..
[Memcache]
memcache.allow_failover = 1
memcache.max_failover_attempts=20
memcache.chunk_size =8192
memcache.default_port = 11211

d) 这一点很重要,memcached 使用一个外部服务。该服务必须在使用 memcache 之前下载并安装。我使用的是:http://jehiah.cz/projects/memcached-win32/

e) 请记住安装该服务并启动 memcached.exe -d install 来安装,并运行 services.msc 来启动 memcached 服务(或重启系统)。

f) 检查防火墙端口。

最后,重启 apache/iis 并运行一些测试。至少在 phpinfo 中必须显示一些关于 memcache 的信息。

最后说明:memcache 的“魅力”不仅仅在于它可以帮助加速某些进程(或减少 CPU 使用率),它还可以像全局会话一样用于存储整个对象,而这个“全局会话”是所有用户共享的,就像 ASP 中使用的应用程序一样。因此(例如),可以执行用户计数器,而不需要数据库或写入文件。
-1
gil at squidoo dot com
17 年前
在使用 flush() 函数时,Aggregator 类中存在一个小错误。对 $connections 的引用应该是 $this->connections。

更改

public function flush() {
$result = false;
for ($i = 0; $i < count($connections); $i++) {
if ($this->connections[$i]->flush()) {
$result = true;
}
}
return $result;
}

To

public function flush() {
$result = false;
for ($i = 0; $i < count($this->connections); $i++) {
if ($this->connections[$i]->flush()) {
$result = true;
}
}
return $result;
}
-2
markfrawley at gmail dot com
17 年前
以下是上述 MemcacheAggregator 类的 PHP4 移植版本

<?php
class MemcachedAggregator {
var
$connections;
var
$_servers;

function
MemcachedAggregator($servers) {
$this->_servers = $servers;
// 尝试建立/检索所有服务器的持久连接。
// 如果任何服务器失败,它们将不会被添加到我们的活动连接列表中。
$this->connections = array();
for (
$i = 0, $n = count($servers); $i < $n; $i++) {
$server = $servers[$i];
$con = memcache_connect($server['host']);
//memcache_debug(1);
//$memcache = &new Memcache;
//$con = $memcache->connect($server['host']);
if (!($con == false)) {
$this->connections[] = &$con;
}

}
}

function
_getConForKey($key) {
$hashCode = 0;
for (
$i = 0, $len = strlen($key); $i < $len; $i++) {
$hashCode = (int)(($hashCode*33)+ord($key[$i])) & 0x7fffffff;
}
if ((
$ns = count($this->connections)) > 0) {
return
$this->connections[$hashCode%$ns];
//return $this->connections[0];
}
return
false;
}

function
debug($on_off) {
$result = false;
for (
$i = 0; $i < count($this->connections); $i++) {
if (
$this->connections[$i]->debug($on_off)) $result = true;
}
return
$result;
}

function
flush() {
$result = false;
for (
$i = 0; $i < count($this->connections); $i++) {
if (
$this->connections[$i]->flush()) $result = true;
}
return
$result;
}

/// 以下未实现:
///getStats()
///getVersion()

function get($key) {
if (
is_array($key)) {
$dest = array();
foreach (
$key as $subkey) {
$val = get($subkey);
if (!(
$val === false)) $dest[$subkey] = $val;
}
return
$dest;
} else {
$conn = &$this->_getConForKey($key);
return
$conn->get($key);
}
}

function
set($key, $var, $compress=0, $expire=0) {
$conn = &$this->_getConForKey($key);
return
$conn->set($key, $var, $compress, $expire);
}

function
add($key, $var, $compress=0, $expire=0) {
$conn = &$this->_getConForKey($key);
return
$conn->add($key, $var, $compress, $expire);
}

function
replace($key, $var, $compress=0, $expire=0) {
$conn = &$this->_getConForKey($key);
return
$conn->replace($key, $var, $compress, $expire);
}

function
delete($key, $timeout=0) {
$conn = &$this->_getConForKey($key);
return
$conn->delete($key, $timeout);
}

function
increment($key, $value=1) {
$conn = &$this->_getConForKey($key);
return
$conn->increment($key, $value);
}

function
decrement($key, $value=1) {
$conn = &$this->_getConForKey($key);
return
$conn->decrement($key, $value);
}

function
showStats($server=null) {
$stats_out = '';
if(
$server == null) {
$i=0;
foreach(
$this->connections as $conn) {
$server = $this->_servers[$i];
$stats_array = memcache_get_stats($conn);
$stats_out .= "</br><b>Server: ".$server['host'].": </b><br/>";
foreach(
$stats_array as $key => $val) {
$stats_out .= "$key => $val <br/>";
}
$i++;
}
}
return
$stats_out;
}
}
?>
-1
moazzamk at gmail dot com
17 年前
如果您扩展了 memcache 类,则无法在类的构造函数中调用 parent::__construct()。但是,不运行构造函数仍然会启动它并正常工作。

<?php

// 错误

class a extends Memcache {
function
__construct($host, $port)
{
parent::__construct();
$this->connect($host, $port);
}

// 正确
class a extends Memcache {
function
__construct($host, $port)
{
parent::__construct();
$this->connect($host, $port);
}

?>

我猜这适用于所有原生/PECL 类。
-2
Ron
18 年前
上面代码的改进

如果所有缓存服务器都关闭,上面的类会导致错误。首选的行为是只是缓存未命中(或在写入操作的情况下不采取任何操作)并返回 false,这样应用程序即使所有缓存服务器都关闭也能在非缓存模式下运行。

要实现这一点,只需将每个受影响函数中的连接使用方式更改为如下所示。此代码适用于 get() 函数

$con = $this->_getConForKey($key);
if ($con === false) return false;
return $con->get($key);

同样,set() 函数中受影响的代码将如下所示
$con = $this->_getConForKey($key);
if ($con === false) return false;
return $con->set($key, $var, $compress, $expire);

相应地修改每个函数,如果所有缓存服务器都关闭,您仍然可以正常运行(尽管由于 100% 缓存未命中率,速度会更慢)。
-1
contact at codeassembly dot com
16 年前
请注意,没有办法拥有自己的哈希机制,将一组对象分组到服务器的最佳方法是手动选择要使用的服务器。

我想将所有特定用户的对象保留在同一服务器上。

user_54_description
user_54_info
user_54_comments
user_54_etc
.
.

如果将所有这些对象都放在同一服务器上,我就可以通过一次调用 memcache->get(get_multi)来获取所有数据,这样可以大大提高性能。

我的做法是将用户/对象 ID 哈希到服务器数量。

<?php
$memcache_hosts
= array
(
'192.168.1.1',
'192.168.1.2',
'192.168.1.3',
'192.168.1.4',
'192.168.1.5',
);

$server = $id % count($memcache_hosts);

$memcache = new Memcache;
$memcache->connect($memcache_hosts[$server], 11211);

// 在此处获取或设置您的对象
?>

您可以将不想分组的其他对象留给 memcache 扩展进行哈希并选择相应的服务器。
-1
Colin Guthrie
16 年前
我发现了一个错误/文档错误

上面的文档对 session.save_path 参数的说明如下
"每个 URL 都可能包含应用于该服务器的参数,这些参数与 Memcache::addServer() 方法的参数相同。"

addServer 方法的文档说明
"port

指向 memcached 监听连接的端口。此参数是可选的,其默认值为 11211。在使用 UNIX 域套接字时,将此参数设置为 0。"

但是,在指定 save_path 时,我发现使用 PHP 5.2.3 和 memcache 2.1.2,端口是字符串的*必需*部分。

希望这对一些挠头的人有所帮助。
To Top