Dear apr_memcache developers,
I am currently using the apr-util 1.3.X (rev 692755) of apr_memcache
and have noticed that for every active reslist (hard minimum) a
"quit." message is sent to the memcached server before the intended
query. Is there a way to avoid this? This never used to happen on
earlier versions.
An example below:
1. set the apr_memcache_create hard min to 32
2. call apr_memcache_getp on a any "key"
3. watch ngrep spam 32 "quit."'s before the intended query:
ie:
---------------------
######
T 2008/09/09 22:39:45.984160 127.0.0.1:57116 -> 127.0.0.1:15879 [AP]
quit.
#####
T 2008/09/09 22:39:45.984218 127.0.0.1:57115 -> 127.0.0.1:15879 [AP]
quit.
######
T 2008/09/09 22:39:45.984271 127.0.0.1:57114 -> 127.0.0.1:15879 [AP]
quit.
######
T 2008/09/09 22:39:45.984318 127.0.0.1:57113 -> 127.0.0.1:15879 [AP]
quit.
...
etc
...
########
T 2008/09/09 22:39:45.984428 127.0.0.1:57145 -> 127.0.0.1:15879 [AP]
get mykey.
##
T 2008/09/09 22:39:45.984457 127.0.0.1:15879 -> 127.0.0.1:57145 [AP]
VALUE mykey 0 7.
myvalue.
END.
---------------------
I have attached a test program (main.c) showing how I triggered this
issue. It has a hard min of 32, and sends a "set" and
a "get", once every 5 seconds. This triggers 32 quits every 5 seconds.
Can anyone see what I'm doing wrong here?
I'm trying to maintain a connection pool of 32 connections to our
memcached server to reduce the number of TCP sessions establishments
under high load conditions
Thanks,
Peter Baer
/**
* test program for apr_memcache
*
* gcc -Wall -D_LARGEFILE64_SOURCE -fpic -I/usr/include -I/opt/apr/include/apr-1 -I/opt/apr-util/include/apr-1 -L/opt/apr-util/lib -laprutil-1 -o main main.c
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "apr_memcache.h"
//#define DEFAULT_SLEEP_USEC 100
#define DEFAULT_SLEEP_SEC 5
#define GET_COUNT 10
apr_status_t mc_set(apr_memcache_t *_mc)
{
apr_status_t rv;
rv = apr_memcache_set(_mc, "mykey", "myvalue", strlen("myvalue"), 120, 0);
if (rv != APR_SUCCESS)
printf("apr_memcache_set error.\n");
else
printf("apr_memcache_set successful mc=%p.\n", _mc);
return rv;
}
apr_status_t mc_get(apr_memcache_t *_mc, apr_pool_t *_p)
{
apr_status_t rv;
int len = 0;
char *s = NULL;
rv = apr_memcache_getp(_mc, _p, "mykey", &s, &len, 0);
if (rv != APR_SUCCESS)
printf("apr_memcache_get error.\n");
else
printf("apr_memcache_getp returned key '%s', len=%d, mc=%p.\n", s, len, _mc);
return rv;
}
int main(void)
{
int i;
char *server_hostname = "localhost";
int server_port = 15879;
int server_conn_min = 32;
int server_conn_smax = 64;
int server_conn_max = 128;
int server_conn_ttl = 120;
apr_status_t rv;
apr_memcache_t *mc = NULL;
apr_memcache_server_t *server = NULL;
apr_pool_t *pool = NULL;
// apr_pool_t *get_pool = NULL;
rv = apr_initialize();
if (rv != APR_SUCCESS) goto error;
printf("apr_initialize successful.\n");
rv = apr_pool_create(&pool, NULL);
if (rv != APR_SUCCESS) goto error;
printf("apr_pool_create successful pool=%p.\n", pool);
// rv = apr_pool_create(&get_pool, NULL);
// if (rv != APR_SUCCESS) goto error;
// printf("apr_pool_create successful get_pool=%p.\n", get_pool);
rv = apr_memcache_create(pool, 1, 0, &mc);
if (rv != APR_SUCCESS) goto error;
printf("apr_memcache_create successful mc=%p.\n", mc);
rv = apr_memcache_server_create(pool, server_hostname, server_port,
server_conn_min, server_conn_smax, server_conn_max,
server_conn_ttl, &server);
if (rv != APR_SUCCESS) goto error;
printf("apr_memcache_server_create successful server=%p.\n", server);
rv = apr_memcache_add_server(mc, server);
if (rv != APR_SUCCESS) goto error;
printf("apr_memcache_add_server successful.\n");
sleep(1);
for(i=0; i<GET_COUNT; i++) {
// usleep(DEFAULT_SLEEP_USEC);
sleep(DEFAULT_SLEEP_SEC);
mc_set(mc);
mc_get(mc, pool);
}
return 1;
error:
printf("mc api returned non-success, quitting.\n");
return -1;
}