Skip to content

Commit

Permalink
add cost benefit stats to memcached
Browse files Browse the repository at this point in the history
Summary: cost: slot-seconds
         benefit: hits
         
         additional tweaks:
         1) merged calls for size-buckets and cost-benefit stat collection
         2) removed \r\n from consideration in stat bytecounting
         3) removed the number of STAT_LOCK() and STAT_UNLOCK() calls by merging stat gathering blocks of code together
         4) "lifetime" -> "avrg lifetime" for size buckets
         5) reduced references to current_time, which is volatile

Reviewed By: marc

Test Plan: libmcc/test/test.py -a passes
           test/prefix_stats.py passes
           test/cost_benefit_stats.py passes

Revert: OK
  • Loading branch information
ttung committed May 7, 2008
1 parent 65fefa7 commit b6c7202
Show file tree
Hide file tree
Showing 6 changed files with 321 additions and 82 deletions.
4 changes: 2 additions & 2 deletions src/binary_sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ static void handle_get_cmd(conn* c)

STATS_LOCK();
stats.get_hits++;
stats_size_buckets_get(it->nkey + it->nbytes);
stats_get(it->nkey + it->nbytes - 2);
STATS_UNLOCK();

// fill out the headers.
Expand Down Expand Up @@ -862,7 +862,7 @@ static void handle_delete_cmd(conn* c)
if (it) {
if (exptime == 0) {
STATS_LOCK();
stats_size_buckets_delete(it->nkey + it->nbytes);
stats_delete(it->nkey + it->nbytes - 2);
STATS_UNLOCK();

item_unlink(it, UNLINK_NORMAL);
Expand Down
7 changes: 7 additions & 0 deletions src/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ AC_ARG_ENABLE(stat-buckets,
AC_DEFINE([STATS_BUCKETS],,[Define this if you want operation stats classified into buckets])
fi])

dnl Check whether the user wants cost-benefit stats to be collected.
AC_ARG_ENABLE(cost-benefit-stats,
[AS_HELP_STRING([--enable-cost-benefit-stats],[enable cost-benefit stats])],
[if test "$enableval" = "yes"; then
AC_DEFINE([COST_BENEFIT_STATS],,[Define this if you want cost-benefit stats])
fi])

AC_CHECK_FUNCS(mlockall)

AC_CONFIG_FILES(Makefile doc/Makefile)
Expand Down
4 changes: 2 additions & 2 deletions src/items.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,11 @@ void do_item_unlink_impl(item *it, long flags, bool to_freelist) {
* count */;
stats.curr_items -= 1;
if (flags & UNLINK_IS_EVICT) {
stats_size_buckets_evict(it->nkey + it->nbytes);
stats_evict(it->nkey + it->nbytes - 2);
}
STATS_UNLOCK();
if (settings.detail_enabled) {
stats_prefix_record_removal(ITEM_key(it), ITEM_ntotal(it), it->time, flags);
stats_prefix_record_removal(ITEM_key(it), it->nkey + it->nbytes - 2, it->time, flags);
}
assoc_delete(ITEM_key(it), it->nkey);
item_unlink_q(it);
Expand Down
44 changes: 30 additions & 14 deletions src/memcached.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ static void stats_init(void) {
stats.started = time(0) - 2;
stats_prefix_init();
stats_buckets_init();
stats_cost_benefit_init();
}

static void stats_reset(void) {
Expand Down Expand Up @@ -800,22 +801,17 @@ int do_store_item(item *it, int comm) {
window... in which case we have to find the old hidden item
that's in the namespace/LRU but wasn't returned by
item_get.... because we need to replace it */

int64_t size_change = ITEM_ntotal(it);

if (delete_locked) {
old_it = do_item_get_nocheck(key, it->nkey);
}

STATS_LOCK();
if (settings.detail_enabled) {
stats_prefix_record_byte_total_change(key, size_change);
stats_prefix_record_byte_total_change(key, it->nkey + it->nbytes - 2);
}

STATS_LOCK();
stats_size_buckets_set(it->nkey + it->nbytes);
if (old_it != NULL) {
stats_size_buckets_overwrite(old_it->nkey + old_it->nbytes);
}
stats_set(it->nkey + it->nbytes - 2,
(old_it == NULL) ? 0 : old_it->nkey + old_it->nbytes - 2);
STATS_UNLOCK();

if (old_it != NULL) {
Expand Down Expand Up @@ -1128,6 +1124,13 @@ static void process_stat(conn *c, token_t *tokens, const size_t ntokens) {
return;
}

if (strcmp(subcommand, "cost-benefit") == 0) {
int bytes = 0;
char *buf = cost_benefit_stats(&bytes);
write_and_free(c, buf, bytes);
return;
}

out_string(c, "ERROR");
}

Expand Down Expand Up @@ -1165,13 +1168,15 @@ static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens)
return;
}

it = item_get(key, nkey);

STATS_LOCK();
stats.get_cmds++;
STATS_UNLOCK();
it = item_get(key, nkey);
if (settings.detail_enabled) {
stats_prefix_record_get(key, NULL != it);
}
STATS_UNLOCK();

if (it) {
if (i >= c->isize) {
item **new_list = realloc(c->ilist, sizeof(item *) * c->isize * 2);
Expand Down Expand Up @@ -1200,7 +1205,7 @@ static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens)
/* item_get() has incremented it->refcount for us */
STATS_LOCK();
stats.get_hits++;
stats_size_buckets_get(it->nkey + it->nbytes);
stats_get(it->nkey + it->nbytes - 2);
STATS_UNLOCK();
item_update(it);
if ((it->it_flags & ITEM_VISITED) == 0) {
Expand Down Expand Up @@ -1360,9 +1365,11 @@ static void process_update_command(conn *c, token_t *tokens, const size_t ntoken
return;
}

STATS_LOCK();
if (settings.detail_enabled) {
stats_prefix_record_set(key);
}
STATS_UNLOCK();

if (settings.managed) {
int bucket = c->bucket;
Expand Down Expand Up @@ -1496,6 +1503,13 @@ char *do_add_delta(item *it, const int incr, const unsigned int delta, char *buf
snprintf(buf, 32, "%u", value);
res = strlen(buf);
assert(it->refcount >= 1);

// arithmetic operations are essentially a set+get operation.
STATS_LOCK();
stats_set(it->nkey + res, it->nkey + it->nbytes - 2);
stats_get(it->nkey + res);
STATS_UNLOCK();

if (res + 2 > it->nbytes ||
(it->refcount > 1)) { /* need to realloc */
item *new_it;
Expand Down Expand Up @@ -1563,15 +1577,17 @@ static void process_delete_command(conn *c, token_t *tokens, const size_t ntoken
}
}

STATS_LOCK();
if (settings.detail_enabled) {
stats_prefix_record_delete(key);
}
STATS_UNLOCK();

it = item_get(key, nkey);
if (it) {
if (exptime == 0) {
STATS_LOCK();
stats_size_buckets_delete(it->nkey + it->nbytes);
stats_delete(it->nkey + it->nbytes - 2);
STATS_UNLOCK();

item_unlink(it, UNLINK_NORMAL);
Expand Down Expand Up @@ -1797,7 +1813,7 @@ static void process_command(conn *c, char *command) {
strcmp(tokens[COMMAND_TOKEN + 1].value, "reassign") == 0)) {

int src, dst, rv;

/* the opengroup spec says that if we care about errno after strtol/strtoul, we have to zero
* it out beforehard. see
* http://www.opengroup.org/onlinepubs/000095399/functions/strtoul.html */
Expand Down
Loading

0 comments on commit b6c7202

Please sign in to comment.