[Modules] apr_memcache Errors on heavy access
Juhani Connolly
Juhani at ninja.co.jp
Tue Feb 17 21:41:56 EST 2009
I've written an apache module that among other things enters a visitors user
agent into a database and records the index in a flat file(or just records
the index if it already exists). To speed this process up I'm using
aprmemcache to store indexes with the user agent as the key.
At moderate access rates this works perfectly fine, and I've had it running
in the background for weeks on a site with about 500,000 daily accesses, but
when I run it full pelt with a tool like ab for 50,000 requests, it will go
at about 5000-8000 requests initially but most times towards the end I get
the following error in my logs(from my module, though the errno being
reported is the return from apr_memcache_getp):
[Tue Feb 17 19:38:07 2009] [notice] (99)Cannot assign requested address:
[access] Couldn't retrieve agent from mc
After this occurs, apr_memcache_getp won't get anything and index requests
end up going to mysql slowing the system to a crawl.
Taking a quick peek at the source which I had some trouble following, I
could see that pretty much any error will cause the server connected to be
marked as bad. What would the correct action be to take here? Can I just go
and open up the connection again(is this even safe when I'm running
multi-threaded? )?
Rest is optional reading that might be useful if anyone could spare some of
their valuable time to help.
Thanks,
Juhani Connolly
---------------------------------------------------------------------------------------------------
More specifics:
Using worker mpm
Currently I set up my memcache server list from the post_config hook.
memcache creation(error code/basic string manipulations like fetching the
server address/port stripped out for conciseness)
static int mna_hook_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t
*ptemp, server_rec *s)
{
// do other stuff, make sure we only run this once etc...
.
.
.
//**************************
mna_srv_conf* svr = ap_get_module_config(s->module_config, &access_module);
int thread_limit = 0;
ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
cache_config = apr_pstrdup(p, svr->servers); // memcache server info loaded
from config file
rv = apr_memcache_create(p, srv_count, 0, &(svr->mc));
// init memcache
while(getServer(cache_config)) // get the parameters
{
rv = apr_memcache_server_create(p, host_str, port, 0, 1, thread_limit,
600, &st); // I've tried using other settings for min and smax and the
problem persists
rv = apr_memcache_add_server(svr->mc, st);
}
}
memcache usage:
char * GetAgentInd(request_rec *r, mna_srv_conf* svr, char * agent)
{
char *agentIndex;
char *mcAgent = apr_psprintf(r->pool, "NA_%s", agent);
char *p = mcAgent;
apr_status_t rv = apr_memcache_getp(svr->mc, r->pool, mcAgent, &agentIndex,
&size, NULL);
if(rv != APR_NOTFOUND && rv != APR_SUCCESS)
ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, r->server, "[access] Couldn't
retrieve agent from mc");
After the fail case where we load from mysql we try to write to memcache
rv = apr_memcache_set(svr->mc, mcAgent, agentIndex, strlen(agentIndex),
86400, 0);
After the aforementioned 99(EADDRNOTAVAIL) error occurs this will start to
fail with(because the connection is presumably down)
(70015)Could not find specified socket in poll list.
More information about the Modules
mailing list