Hi Brian,

A careful perusal of the memcached_mget_by_key() function revealed the bug.

The code was generating the serverid by using the master key first. However
if the serverid was 0, the following check was causing re-evaluation of the
serverid by using the buffer key leading to the query being sent to another
server:

    if (master_server_key) /* if the serverid had evaluated to zero, we go
to else */
      server_key= master_server_key;
    else
      server_key= memcached_generate_hash(ptr, keys[x], key_length[x]);

After fixing this, the *_by_key logic appears to be working just fine.

Please find attached, a patch (diff -c format) which fixes this.

Regards,
Nikhils

On Tue, Apr 14, 2009 at 12:27 PM, Nikhils <[email protected]> wrote:

> Hi,
>
> I recently shifted to using the memcached_get/set_by_key APIs. The trouble
> is that even after warming the cache with all of the content, a subsequent
> query to fetch the key/value pair fails with a not found error. I am seeing
> this behaviour in a 2-node memcached cluster.
>
> Its occurring consistently and on reverting back to using the normal
> memcached_get/set APIs, the key/value pairs can be retrieved appropriately!
> However I do need to use these by_key APIs for my data consistency logic.
>
> I have added appropriate logging information in my C code (am linking to
> libmemcached 0.27) and confirmed that the master key is the same in both
> set_by_key/get_by_key calls.
>
> Anything obvious that I am missing? Has anyone observed such dubious
> behaviour before with these by_key calls? Comments appreciated.
>
> Regards,
> Nikhils
>
*** libmemcached/memcached_get.c	2009-03-24 00:20:38.000000000 +0530
--- ../worklibmemcached/libmemcached/memcached_get.c	2009-04-14 16:15:49.000000000 +0530
***************
*** 124,130 ****
    memcached_return rc= MEMCACHED_NOTFOUND;
    char *get_command= "get ";
    uint8_t get_command_length= 4;
!   unsigned int master_server_key= 0;
  
     if (ptr->flags & MEM_USE_UDP)
      return MEMCACHED_NOT_SUPPORTED;
--- 124,130 ----
    memcached_return rc= MEMCACHED_NOTFOUND;
    char *get_command= "get ";
    uint8_t get_command_length= 4;
!   unsigned int master_server_key= -1; /* 0 is a valid server id! */
  
     if (ptr->flags & MEM_USE_UDP)
      return MEMCACHED_NOT_SUPPORTED;
***************
*** 186,192 ****
    {
      unsigned int server_key;
  
!     if (master_server_key)
        server_key= master_server_key;
      else
        server_key= memcached_generate_hash(ptr, keys[x], key_length[x]);
--- 186,192 ----
    {
      unsigned int server_key;
  
!     if (master_server_key != -1)
        server_key= master_server_key;
      else
        server_key= memcached_generate_hash(ptr, keys[x], key_length[x]);

Reply via email to