一、修改test程序
在test程序中加入memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY),设置分布式算法。
二、memcached_behavior_set_distribution
memcached_behavior_set_distribution()仍然会调用run_distribution()。
memcached_return_t memcached_behavior_set_distribution(memcached_st *ptr, memcached_server_distribution_t type)
{
if (type < MEMCACHED_DISTRIBUTION_CONSISTENT_MAX)
{
if (MEMCACHED_DISTRIBUTION_CONSISTENT_WEIGHTED) //此处该项不为0,所以执行ptr->ketama.weighted = true;
{
ptr->ketama.weighted= true;
}
else
{
ptr->ketama.weighted= false;
}
ptr->distribution= type;
return run_distribution(ptr); //对于 MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY,调用update_continuum(ptr)
}
return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
memcached_literal_param("Invalid memcached_server_distribution_t"));
}
三、update_continuum
static memcached_return_t update_continuum(memcached_st *ptr)
{
uint32_t continuum_index= 0;
memcached_server_st *list;
uint32_t pointer_counter= 0;
uint32_t pointer_per_server= MEMCACHED_POINTS_PER_SERVER; //此值为100,表示产生100个虚拟节点
uint32_t pointer_per_hash= 1;
uint32_t live_servers= 0;
struct timeval now;
if (gettimeofday(&now, NULL))
{
return memcached_set_errno(*ptr, errno, MEMCACHED_AT);
}
list= memcached_server_list(ptr);
/* count live servers (those without a retry delay set) */
bool is_auto_ejecting= _is_auto_eject_host(ptr);
if (is_auto_ejecting) //此次执行为false,if不执行
{
live_servers= 0;
ptr->ketama.next_distribution_rebuild= 0;
for (uint32_t host_index= 0; host_index < memcached_server_count(ptr); ++host_index)
{
if (list[host_index].next_retry <= now.tv_sec)
{
live_servers++;
}
else
{
if (ptr->ketama.next_distribution_rebuild == 0 or list[host_index].next_retry < ptr->ketama.next_distribution_rebuild)
{
ptr->ketama.next_distribution_rebuild= list[host_index].next_retry; //设置下一次rebuild的时间,就是之后最靠前的retry时。
}
}
}
}
else
{
live_servers= memcached_server_count(ptr); //本例为3个服务器
}
uint64_t is_ketama_weighted= memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED); //本例为true,由memcached_behavior_set_distribution()设置
uint32_t points_per_server= (uint32_t) (is_ketama_weighted ? MEMCACHED_POINTS_PER_SERVER_KETAMA : MEMCACHED_POINTS_PER_SERVER);//前者为160,后者为100
if (not live_servers)
{
return MEMCACHED_SUCCESS;
}
if (live_servers > ptr->ketama.continuum_count)
{
memcached_continuum_item_st *new_ptr;
//MEMCACHED_CONTINUUM_ADDITION默认为10.此处分配了(3+10)*160个emcached_continuum_item_st元素的数组。
new_ptr= libmemcached_xrealloc(ptr, ptr