memcache support => enabled
Version => 3.0.8
Revision => $Revision: 329835 $
Directive => Local Value => Master Value
memcache.allow_failover => 1 => 1
memcache.chunk_size => 32768 => 32768
memcache.compress_threshold => 20000 => 20000
memcache.default_port => 11211 => 11211
memcache.hash_function => crc32 => crc32
memcache.hash_strategy => consistent => consistent
memcache.lock_timeout => 15 => 15
memcache.max_failover_attempts => 20 => 20
memcache.protocol => ascii => ascii
memcache.redundancy => 1 => 1
memcache.session_redundancy => 2 => 2
php-memcache扩展版本:基于3.0.8 beta的修改版本: 链接
增加一个hash表,记录每台服务器在圆环上的节点总数。地址 (39 - 52行)
<!-- lang: cpp -->
typedef struct mmc_consistent_point {
mmc_t *server;
unsigned int point;
char *host;/* DEBU 增加host,用于对比*/
unsigned int seed;
} mmc_consistent_point_t;
typedef struct mmc_consistent_state {
int num_servers;
mmc_consistent_point_t *points;
int num_points;
mmc_t *buckets[MMC_CONSISTENT_BUCKETS];
int buckets_populated;
mmc_hash_function_t *hash;
mmc_debug_servers_t *debug;//debug信息hash
} mmc_consistent_state_t;
修改两个结构体,用来标记节点对应的服务器信息(host+port) 地址
<!-- lang: cpp -->
typedef struct mmc_consistent_point {
mmc_t *server;
unsigned int point;
char *host;/* DEBU 增加host,用于对比*/
unsigned int seed;
} mmc_consistent_point_t;
typedef struct mmc_consistent_state {
int num_servers;
mmc_consistent_point_t *points;
int num_points;
mmc_t *buckets[MMC_CONSISTENT_BUCKETS];
int buckets_populated;
mmc_hash_function_t *hash;
mmc_debug_servers_t *debug;//debug信息hash
} mmc_consistent_state_t;
类增加两个方法,用来输出调试信息。地址
<!-- lang: cpp -->
PHP_FUNCTION(memcache_get_debug);
PHP_FUNCTION(memcache_points_debug);
增加多个函数,记录相应的数据。地址
<!-- lang: cpp -->
static void mmc_debug_info_hash_init(void *s);
static int mmc_debug_info_hash_update(mmc_consistent_state_t *state, unsigned int point);
static int mmc_debug_info_hash_add(mmc_debug_servers_t *ht, char *host, unsigned int hash);
启动4个端口的memcache服务:11211 - 11214
写入10240次缓存,对比缓存数据分布比例:
1) weight 相同的情况
if (!extension_loaded('memcache')) {
exit('memcache extension not load!');
}
$cache = new Memcache();
$cache->addServer('localhost', 11211, true, 1);
$cache->addServer('localhost', 11212, true, 1);
$cache->addServer('localhost', 11213, true, 1);
$cache->addServer('localhost', 11214, true, 1);
sleep(2);
for ($i = 0; $i < 10240; $i++) {
$cache->add(md5('test:key:'.$i), 'value:'.$i, false, 247600);
}
var_dump($cache->getDebug());
结果:
上面输出数组的字段解释:
host:host+port
weight:host的哈希值
nodes:所属的虚节点的数量
add_total:暂未实现记录添加的缓存数。
从上面的输出信息可知:相对于大多数缓存服务,权重相同的情况下,每台服务器分配的节点数大致相当。
查询每个缓存服务的状态:
nodes:293 => telnet localhost 11211 => STAT cmd_set 2934
nodes:174 => telnet localhost 11212 => STAT cmd_set 1749
nodes:261 => telnet localhost 11213 => STAT cmd_set 2501
nodes:296 => telnet localhost 11214 => STAT cmd_set 3056
基本上缓存的数量和所属虚节点数量是成正比的。
但是由于hash值的问题,可能会使得某个缓存服务所属的节点数量严重不符比例。
2)weight 成比的情况
<!-- lang: cpp -->
$cache = new Memcache();
$cache->addServer('localhost', 11211, true, 1);
$cache->addServer('localhost', 11212, true, 2);
$cache->addServer('localhost', 11213, true, 4);
$cache->addServer('localhost', 11214, true, 8);
sleep(2);
for ($i = 0; $i < 10240; $i++) {
$cache->add(md5('test:key:'.$i), 'value:'.$i, false, 247600);
}
var_dump($cache->getDebug());
结果:
总结:
weight:1 =>nodes:66 => telnet localhost 11211 => STAT cmd_set 658
weight:2 =>nodes:116 => telnet localhost 11212 => STAT cmd_set 1211
weight:4 =>nodes:261 => telnet localhost 11213 => STAT cmd_set 2582
weight:8 =>nodes:581 => telnet localhost 11214 => STAT cmd_set 5789
总体来说,分布还算按比例分布。不过总是有一些特例出现,虽然不常见。
之前也说到了points会间接影响缓存节点在圆环上的位置,也已经知道权重影响某个服务器所属的points的数量,也就间接的影响到了该缓存服务器的虚节点的位置(折半查找)。
这里只拿权重相等的情况下做演示。我们之前的看的关于memcached的一致性哈希的概念是:服务器所属的虚节点是连续不断的。请看下面的实验结果:
<!-- lang: cpp -->
if (!extension_loaded('memcache')) {
exit('extension not load!');
}
$cache = new Memcache();
$cache->addServer('192.168.247.132', 11211, true, 1);
$cache->addServer('192.168.247.132', 11212, true, 1);
$cache->addServer('192.168.247.132', 11213, true, 1);
$cache->addServer('192.168.247.132', 11214, true, 1);
sleep(2);
$tmp = $cache->pointsDebug();
ksort($tmp['points']);
echo "points_total:\t{$tmp['points_total']}\n==================================================\n";
foreach($tmp['points'] as $k=>$v) {
echo "{$v}:\t{$k}\n";
}
结果:第一行是points的数量,左边是point所属的缓存服务,右边的points的值
我们可以看出,points的分布是随机的,所以按之前说的step(每个虚节点之间的距离)来算,其实每台服务器所属的虚节点在圆环的分布是随机的。并不是我们之前理解的连续不断。
因为结果有点长我就不全贴了,有兴趣自己去尝试下。