作者:zhanhailiang 日期:2013-12-08
结论
Memcached默认对Key和Value长度做如下限制:
-
Key字符串的长度不能超过255个字符;
-
Value字符串的长度不能超过1024 * 1024个字符, 即存储数据不能超过1M;
推荐使用默认配置, 也可以通过直接修改memcached.h源码来加大长度限制.
// memcached.h #define KEY_MAX_LENGTH 1000 #define MAX_ITEM_SIZE (1024 * 1024 * 2)
也可以启动Memcached时通过-I参数来配置:
-I Override the size of each slab page. Adjusts max item size (default: 1mb, min: 1k, max: 128m)
源码分析
// memcached.h #define KEY_MAX_LENGTH 255 #define MAX_ITEM_SIZE (1024 * 1024)
// flat_storage.c /** * Returns true if an item will fit in the cache (its size does not exceed * the maximum for a cache entry.) */ bool item_size_ok(const size_t nkey, const int flags, const int nbytes) { return (nkey <= KEY_MAX_LENGTH) && (nbytes <= MAX_ITEM_SIZE); }
//memcached.c //... if (! item_size_ok(nkey, flags, vlen)) out_string(c, "SERVER_ERROR object too large for cache"); else out_string(c, "SERVER_ERROR out of memory"); //...
测试
测试用例如下:
<?php
/**
* @version 1.0
* @author wade
* @date 2013-12-08
*/
ini_set('memory_limit', '512M');
$mCached = new Memcached();
$mCached->addServer('127.0.0.1', 7503);
// 当开启的时候, item的值超过某个阈值(当前是100bytes)时, 会首先对值进行压缩然后存储, 并在获取该值时进行解压缩然后返回, 使得压缩对应用层透明. 默认Memcached开启压缩功能. 此处为了测试, 需要暂时先关闭压缩功能.
$ret = $mCached->setOption(Memcached::OPT_COMPRESSION, FALSE);
var_dump($mCached->getOption(Memcached::OPT_COMPRESSION));
$key = 'memcached_test';
$ret = $mCached->delete($key);
var_dump($ret);
$ret = $mCached->get($key);
var_dump($ret);
$values = array();
// 为什么是85呢, 因为存储$value数据需要额外存储其它元素数据, 包括key, 管理信息
// 每记录需要内存数 = key长度 + value长度 + 管理信息(64 字节 + 1~9字节的value size的字符数).
// 14 + 1024 * 1024 - 85 + 1 + 64 + 7 = 1024 * 1024 + 1
for ($i = 0; $i < 1024 * 1024 - 85 + 1; $i++) {
$values[] = 1;
}
$value = implode('', $values);
echo strlen($value).PHP_EOL;
$ret = $mCached->set($key, $value, 10);
var_dump($ret);
$ret = $mCached->get($key);
var_dump($ret);
$values = array();
// 为什么是85呢, 因为存储$value数据需要额外存储其它元素数据, 包括key, 管理信息
for ($i = 0; $i < 1024 * 1024 - 85; $i++) {
$values[] = 1;
}
$value = implode('', $values);
echo strlen($value).PHP_EOL;
$ret = $mCached->set($key, $value, 10);
var_dump($ret);
$ret = $mCached->get($key);
var_dump($ret);
测试结果:
[user_00@srv-10 ~/wade/20131206]$ /usr/local/php/bin/php memcachedTest.php bool(false) bool(false) bool(false) 1048492 bool(false) bool(false) 1048491 bool(true) string(1048491) "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"...