php-memcache扩展分析(四) 验证缓存节点分布情况&总结

标签:

php-memcache配置环境

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行)

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) 地址

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;

类增加两个方法,用来输出调试信息。地址

    PHP_FUNCTION(memcache_get_debug);
    PHP_FUNCTION(memcache_points_debug);
    

增加多个函数,记录相应的数据。地址

    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
memcached服务
写入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 成比的情况

$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的一致性哈希的概念是:服务器所属的虚节点是连续不断的。请看下面的实验结果:

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的哈希值

我们可以看出,points的分布是随机的,所以按之前说的step(每个虚节点之间的距离)来算,其实每台服务器所属的虚节点在圆环的分布是随机的。并不是我们之前理解的连续不断。

因为结果有点长我就不全贴了,有兴趣自己去尝试下。


评论已关闭