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]);