以下是网站 groops.cn 在 2009-11 的历史页面存档,小提示:CTRL+U 查看源码
本站和 groops.cn 的作者无关,不对其内容负责。本历史页面谨为网络历史索引,不代表被查询网站的即时页面。 *号[x]表示已屏蔽显示的敏感字。
原网页标题:雕刻时光

雕刻时光

A simple guy living in Shanghai, will working for creative and freedom

说说 php 的 memcache 和 memcached 模块以及 TokyoTyrant

最近项目中要使用 memcache 和 TokyoTyrant,于是花时间仔细研究了一番。

PECL 中有两个 memcache 的扩展:


memcache : memcached extension
memcached : PHP extension for interfacing with memcached via libmemcached library

Memcached版本建立在libmemcached的基础上,所以说Memcached版本的功能更全一些。

可以在phpinfo中查看你当前安装的版本,或者用这个命令来看


php -m | grep mem

memcached 最新版本是 1.0.0, 和 不带d的memcache相比,增加了很多方法,如


cas, fetch, prepend, replace 等。

现在拿Memcached::cas来测试一下,手册的说法是:

Memcached::cas() performs a "check and set" operation,
so that the item will be stored only if no other client has updated it
since it was last fetched by this client. The check is done via the
cas_token
parameter which is a unique 64-bit
value assigned to the existing item by memcache. See the documentation for
Memcached::get* methods for how to obtain this
token. Note that the token is represented as a double due to the
limitations of PHP's integer space.


也就是说,它实现了传说中的“乐观锁定”功能。这个特性在某些情况下会非常有用:假设一个计数器的初始值是一个整数,不使用increment方法,通过get/set完成每次加一。

在Memcache版本里,我们只能按照大致如下的方式来进行:


$m = new Memcache();

$m->addServer('localhost', 11211);

$v = $m->get('counter');

$m->set('counter', $v + 1);



由于get/set这两个动作无法作为一个原子来操作,所以当多个进程同时处理时,会出现丢失的可能,更让人恼火的是,你根本就不知道什么时候出现丢失。

那么再看看Memcached版本里,我们是如何做的:

$md = new Memcached();

$md->addServer('localhost', 11211);

$v = $md->get('counter', null, $token);
$md->cas($token, 'counter', $v + 1);

如果你把$token的值var_dump出来,就会发现$token其实就是一个版本号,如果通过get得到的$token版本号在cas的时候不对应,就说明已经有别的操作更新了,此时cas操作会失败,至于如何继续操作,就看你自己了。


然后再说说最近在研究的TokyoTyrant ,很多人都转载用 PECL::MemcachePECL::Memcached 与 Tokyo Tyrant 通讯的方法,也有人打补丁在 Memcache 中自动进行 unserialize


不能自动 unserialize 是个问题,另一个问题则是 memcache
的自动清除过期条目功能是无效的。由此看来,无论 PECL::Memcache 还是 PECL::Memcached,都是一个壳,方便在
PHP 中把 Tokyo Tyrant 当作 DBM 使用而已。

目前比较知名的有两个 PHP Library,一个是 OpenPear 的 Net_TokyoTyrant,另一个是参考前者做的 TokyoTyrant_php,文档都不是很全,不过我认为这比使用 Memcache 或 Memcached 都要好;例如这个使用后者的例子:



$tt = new TokyoTyrant_RDB();
$tt->open('localhost', 1978);
$tt->fwmkeys('prefix');

这里的 fwmkeys('prefix') 能取出以 prefix 为前缀的 key list,这比作为兼容方案的 Memcache 或 Memcached 强多了吧?


至于 serialize 和 unserialize,对于 Tokyo Tyrant 来说,这不是主要考虑的;Tokyo Tyrant
本身就具备搜索功能,而且可以外挂 Lua 扩展,除非只使用 PHP 读写 Tokyo Tyrant,并且不以其他语言(Python, Lua,
etc.)来做特殊需要的读写,否则用 Memcache 和 Memcached 操作 Tokyo Tyrant 实在鸡肋。 



这里是从功能上来说的,接下来测试一下效率会有多大的差距。

追寻打动人心的力量

总该为大片空白的时光留下点什么,即便是在不久以后这里可能就会荒芜地如同原始雨林地深处,而在数百年以后没有人会怀疑为什么我不留下点什么——因为没有人会记得我,或者知道我的存在过。


现在的我处在一个尴尬的境遇,我知道我能够做些什么,也知道做不到什么。


论我能做的,我知道自己在器物级上的能力。告诉我需要做一个碗,我已经可以做出一个很好的碗——这是在过去我所不曾能够做到的;然而我不知道为什么要做一个碗,甚至不知道谁需要这样一个碗,他们用碗来做什么?这是一种超越于器物级以上的能力。然而这是至关重要的,因为如果要求一个碗的人其实是希望用碗
来给花浇水,那么他更加需要的显然是一个完全自动化的灌溉系统,包括水渠、净水和矿化、定时定量自动抽水的水泵,以及输送到花根的输水管,等等——然而这
些描述都出自于我经验的想象,我现在还无法凭借自身的力量求证需求这个碗的人到底想要什么。


我只知道,我在以一种近乎无脑的方式在追逐我和这个世界的距离,追寻着可以那些打动人心的力量,这种力量如阳光般简单、坚定、灿烂、透彻和热情,更不用说,它是一种如此单纯然赐予和延续人类生命的力量。


软件版本号检测的一个思路

不知道QQ、360这类拥有大量用户的软件的版本升级检测是怎么做的。如果是去网上某个地址读一个文本或者 XML 文件,里面写着版本号,有变化就去下载新版本的的话。这么大的访问量,服务器和带宽也是一笔不小的投入。

用这个办法,你的成本可以降到 0:不读文本,读dns,把ip当作版本号。

比方说检查 ver.domain.com 这个域名的 ip,软件版本是 10.5.8,查 ip 一看是 10.6.0.0,哦,有新版了,那就升级吧。
一切理、事,以心为本:心异则千差竞起,心平则法界坦然;空谷回音,声高则响大,宝镜照人,身歪则影邪。万行由心,一切在我:内虚外终不实,内细外终不粗;善因还值善缘,恶行难逃恶境。天堂非他所授,地狱皆自所为;只在最初一念,致此升沉。

解决SnowLeopard无法安装mongo php扩展的问题

官方的
$ pecl install mongo
行不通。
下载安装包来编译安装。
http://pecl.php.net/get/mongo-1.0.0.tgz

$ tar zxvf mongodb-mongodb-php-driver-<commit_id>.tar.gz
$ cd mongodb-mongodb-php-driver-<commit_id>
$ phpize
关键在这里,先打开 configure 在 4844 行删掉 ppc 相关的参数,改完之后试这样的:
CFLAGS="$CFLAGS -arch i386 -arch x86_64"
然后继续:
$ ./configure
$ sudo make install


有时间搞一个 nginx(代替apache) + php + mongo(代替mysql)+ mongoGirdFS(存储) 组合的应用。
More Information
登录并关注 夏天加入Snakr