Libmemcached consistent hash implementation source code analysis

Source: Internet
Author: User
Due to the need for data cache consistency between multiple languages at work, I personally analyzed the implementation of libmemcached and learned some about the implementation of underlying consistency. Here I will share some analysis processes, take notes for yourself. I use PHP. It is most convenient to analyze the extensions of PHP. Here we will start with the memcached: add method of PHP extension to find the desired content. The PHP extension code for the method file php_memcached.cadd method is as follows (File memcached-2.0.1/php_memcached.c ):
PHP_METHOD(Memcached, add){    php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_ADD, 0);}

Here is an implementation package. Let's look at php_memc_store_impl again. Here we omit some code to directly view the call operations of the database.

case MEMC_OP_ADD:if (!server_key) {     status = memcached_add(m_obj->memc, key, key_len, payload, payload_len, expiration, flags);} else {     status = memcached_add_by_key(m_obj->memc, server_key, server_key_len, key,                 key_len, payload, payload_len, expiration, flags);}break;

The following part is the addbykey, and the above is the Add call. Here m_obj-> MEMC is the memcached_st, and m_obj is the memc_obj structure pointer.

struct memc_obj {        memcached_st *memc;        zend_bool compression;        enum memcached_serializer serializer;        enum memcached_compression_type compression_type;#if HAVE_MEMCACHED_SASL        zend_bool has_sasl_data;#endif    } *obj;

Then enter the memcached_add method. In the libmemcached/storage. CC file, different versions of libmemcached may be different. Here is libmemcached1.0.4.

memcached_return_t memcached_add(memcached_st *ptr,                                 const char *key, size_t key_length,                                 const char *value, size_t value_length,                                 time_t expiration,                                 uint32_t flags){  memcached_return_t rc;  LIBMEMCACHED_MEMCACHED_ADD_START();  rc= memcached_send(ptr, key, key_length,                     key, key_length, value, value_length,                     expiration, flags, 0, ADD_OP);  if (rc == MEMCACHED_NOTSTORED or rc == MEMCACHED_DATA_EXISTS)  {    memcached_set_error(*ptr, rc, MEMCACHED_AT);  }  LIBMEMCACHED_MEMCACHED_ADD_END();  return rc;}

Here is a call and some error detection. Continue to enter the memcached_send function, which not only detects parameters and initialization data, but also completes data distribution calculation and storage. Use memcached_generate_hash_with_redistribution (PTR, group_key, group_key_length) to obtain the server index corresponding to the key configured in the current environment. The function code is as follows:

uint32_t memcached_generate_hash_with_redistribution(memcached_st *ptr, const char *key, size_t key_length){  uint32_t hash= _generate_hash_wrapper(ptr, key, key_length);  _regen_for_auto_eject(ptr);  return dispatch_host(ptr, hash);}

Here, the hash of the key is completed, and then the calculation falls on that server. The _ generate_hash_wrapper function knows the function that finally calculates the hash,

static inline uint32_t _generate_hash_wrapper(const memcached_st *ptr, const char *key, size_t key_length){  WATCHPOINT_ASSERT(memcached_server_count(ptr));  if (memcached_server_count(ptr) == 1)    return 0;  if (ptr->flags.hash_with_namespace)  {    size_t temp_length= memcached_array_size(ptr->_namespace) + key_length;    char temp[MEMCACHED_MAX_KEY];    if (temp_length > MEMCACHED_MAX_KEY -1)      return 0;    strncpy(temp, memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace));    strncpy(temp + memcached_array_size(ptr->_namespace), key, key_length);    return generate_hash(ptr, temp, temp_length);  }  else  {    return generate_hash(ptr, key, key_length);  }}

Hash_with_namespace is included in the parameter configurationPrefix_key. Here we call generate_hash to obtain the key hash.The libhashkit/digest. CC libhashkit_digest function is used for calculation. Then enter the dispatch_host function, which is the final implementation part of Distributed Hash processing.

static uint32_t dispatch_host(const memcached_st *ptr, uint32_t hash){  switch (ptr->distribution)  {  case MEMCACHED_DISTRIBUTION_CONSISTENT:  case MEMCACHED_DISTRIBUTION_CONSISTENT_WEIGHTED:  case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:  case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:    {      uint32_t num= ptr->ketama.continuum_points_counter;      WATCHPOINT_ASSERT(ptr->ketama.continuum);      memcached_continuum_item_st *begin, *end, *left, *right, *middle;      begin= left= ptr->ketama.continuum;      end= right= ptr->ketama.continuum + num;      while (left < right)      {        middle= left + (right - left) / 2;        if (middle->value < hash)          left= middle + 1;        else          right= middle;      }      if (right == end)        right= begin;      return right->index;    }  case MEMCACHED_DISTRIBUTION_MODULA:    return hash % memcached_server_count(ptr);  case MEMCACHED_DISTRIBUTION_RANDOM:    return (uint32_t) random() % memcached_server_count(ptr);  case MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET:    {      return memcached_virtual_bucket_get(ptr, hash);    }  default:  case MEMCACHED_DISTRIBUTION_CONSISTENT_MAX:    WATCHPOINT_ASSERT(0); /* We have added a distribution without extending the logic */    return hash % memcached_server_count(ptr);  }  /* NOTREACHED */}

The case section of the first section calculates the server_key that the key falls on that server based on some configuration parameters and uses binary search. The subsequent cases include hash modulo mode and random modulo mode to implement server indexing.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.