Beispiel #1
0
 def __init__(self, ip="127.0.0.1", port="11211"):
     # connect to the memcache-python
     self.m = memcache.Client([ip + ":" + port])
     # connect to the local memcached file
     self.mem_s = MemcachedStats(ip, port)
Beispiel #2
0
class mem:
    # regular expression for keys saved in the cache
    _miss_key_regex = re.compile(ur"(.*)_miss$")
    _hash_key_regex = re.compile(ur"(.*)_hash$")

    def __init__(self, ip="127.0.0.1", port="11211"):
        # connect to the memcache-python
        self.m = memcache.Client([ip + ":" + port])
        # connect to the local memcached file
        self.mem_s = MemcachedStats(ip, port)

    def stats(self):
        """
        stats
        """
        # data from the cache
        stats_dict = self.m.get_stats()[0][1]
        # filter for analysis
        stats_analysis = self.__stats_analysis(stats_dict)
        return stats_dict, stats_analysis

    def __stats_analysis(self, stats_dict):
        """
        hits%, miss%, get%, set%, occupy%, unfteched_evicted%, unfetched_expired%
        """
        hits_p, miss_p, get_p, set_p, unftch_evict, unftch_exp = 0, 0, 0, 0, 0, 0
        ana_dict = {}
        if float(stats_dict["cmd_get"]) != 0:
            # percentage hits, miss
            hits_p = float(stats_dict["get_hits"]) / float(stats_dict["cmd_get"]) * 100
            miss_p = float(stats_dict["get_misses"]) / float(stats_dict["cmd_get"]) * 100
        if float(stats_dict["cmd_get"]) != 0 or float(stats_dict["cmd_set"]) != 0:
            # percentage gets, sets
            get_p = (float(stats_dict["cmd_get"]) / (float(stats_dict["cmd_get"]) + float(stats_dict["cmd_set"]))) * 100
            set_p = 100 - get_p
        # percentage occupied
        occupy_p = (float(stats_dict["bytes"]) / float(stats_dict["limit_maxbytes"])) * 100
        if stats_dict.has_key("evicted_unfetched"):
            if float(stats_dict["evictions"]) != 0:
                # percentage evicted unfetched out of total evicted
                unftch_evict = float(stats_dict["evicted_unfetched"]) / float(stats_dict["evictions"]) * 100
            ana_dict["unftc_ev"] = "%.2f" % unftch_evict
        if stats_dict.has_key("expired_unfetched"):
            if float(stats_dict["total_items"]) != 0:
                # percentage expired unfetched out of total items
                unftc_exp = (float(stats_dict["expired_unfetched"]) / float(stats_dict["total_items"])) * 100
            ana_dict["expired_unfetched"] = "%.2f" % unftc_exp
        ana_dict.update(
            {
                "hits": "%.2f" % hits_p,
                "miss": "%.2f" % miss_p,
                "get": "%.2f" % get_p,
                "set": "%.2f" % set_p,
                "occupy": "%.2f" % occupy_p,
            }
        )
        return ana_dict

    def slabs(self):
        """
        stats slabs
        stats items
        """
        slab_data = self.m.get_slabs()[0][1]
        slab_chunks = self.m.get_slab_chunks()[0][1]
        # merge the data from stats-slabs and stats-items
        for k, v in slab_chunks.items():
            if slab_data.has_key(k):
                for sub_k, sub_v in slab_chunks[k].items():
                    slab_data[k][sub_k] = sub_v
        # filter the slabs data
        return self.__filter_slab(slab_data)

    def __filter_slab(self, slab_data):
        ban_list = ["cas_hits", "cas_badval", "decr_hits", "delete_hits", "reclaimed", "tailrepairs", "free_chunks_end"]
        attr_list = [
            "total_pages",
            "total_chunks",
            "chunks_per_page",
            "used_chunks",
            "total_chunks",
            "free_chunks",
            "chunk_size",
            "mem_requested",
        ]
        evict_list = ["evicted", "evicted_time", "evicted_unfetched", "evicted_nonzero", "outofmemory"]
        data_list = ["number", "cmd_set", "get_hits", "incr_hits"]
        # data_list = ['number', 'cmd_set', 'get_hits', 'age', 'incr_hits']
        label_dict = {
            "used_chunks": "used_ch",
            "chunks_per_page": "ch/page",
            "number": "no.",
            "expired_unfetched": "exp_unftch",
            "evicted": "evic",
            "evicted_time": "evic_t",
            "touch_hits": "tch_hits",
            "total_chunks": "tot_ch",
            "incr_hits": "i_hits",
            "free_chunks": "free_ch",
            "evicted_unfetched": "evic_unftc",
            "age": "age",
            "evicted_nonzero": "evic_nzero",
            "total_pages": "tot_pgs",
            "get_hits": "hits",
            "cmd_set": "set",
            "chunk_size": "ch_size",
            "mem_requested": "mem_req",
            "outofmemory": "out_mem",
        }
        attr_dict = {}
        data_dict = {}
        sum_slab_hits = 0
        sum_slab_sets = 0

        # merging the data_list and evict_list
        data_list = data_list + evict_list
        # separate the data into two dictionaries
        for k, v in slab_data.items():
            attr_dict[k] = dict((label_dict[sub_k], sub_v) for sub_k, sub_v in v.items() if sub_k in attr_list)
            data_dict[k] = dict((label_dict[sub_k], sub_v) for sub_k, sub_v in v.items() if sub_k in data_list)
            # adding the analysis column for attr
            if v.has_key("mem_requested"):
                attr_dict[k]["%wst_mem"] = str(
                    100 - (float(v["mem_requested"]) / (float(v["used_chunks"]) * float(v["chunk_size"]))) * 100
                )[:4]
            attr_dict[k]["%capacity"] = str(float(v["used_chunks"]) / float(v["total_chunks"]) * 100)[:4]
            data_dict[k]["hit/set%"] = str((float(v["get_hits"]) / float(v["cmd_set"])) * 100)[:4]

            if k in ["1", "2", "3", "42"]:
                # print "not", k, v['get_hits'], v['cmd_set']
                pass
            else:
                # print k, sum_slab_hits, sum_slab_sets
                sum_slab_hits += int(v["get_hits"])
                sum_slab_sets += int(v["cmd_set"])
        return attr_dict, data_dict, str(float(sum_slab_hits) / float(sum_slab_sets))
        # return attr_dict, data_dict, str(float(sum_slab_hits))

    def sizes(self):
        """
        stats sizes
        """
        size = self.m.get_stat_sizes()[0][1]
        return size

    def keys(self):
        """
        stats cachedump slab-id count
        using memcachedstats
        """
        # get data from the memcachedstats
        data_dict = self.mem_s.key_details()
        # key=slab_id, value = tuple( #0=key, #1=size, #2=expiry_time)
        for k, v in data_dict.items():
            data_dict[k] = [(sub_v[0], sub_v[1].split(" ")[0], sub_v[2].split(" ")[0]) for sub_v in v]

        return self.count_miss_hash_keys(data_dict)

    def count_miss_hash_keys(self, data_dict):
        """
        Count the number of normal, miss and hash keys in a particular slab
        Count the total normal, miss and hash keys
        """
        timeline_dict = {}
        count_dict = {}
        # total key
        key, miss_key, hash_key = 0, 0, 0
        for slab_id, value_list in data_dict.items():
            key_count, miss_key_count, hash_key_count = 0, 0, 0
            for value in value_list:
                # key
                key_value = value[0]
                if self._miss_key_regex.findall(key_value):
                    # miss key found
                    miss_key_count += 1
                elif self._hash_key_regex.findall(key_value):
                    # hash key found
                    hash_key_count += 1
                else:
                    # normal key found
                    key_count += 1
                # human_exp_time = human_time(value[2].split(" ")[0])
                human_exp_time = float(value[2].split(" ")[0])
                if timeline_dict.has_key(human_exp_time):
                    timeline_dict[human_exp_time] += 1
                else:
                    timeline_dict[human_exp_time] = 1
            count_dict[int(slab_id)] = {
                "key_count": key_count,
                "miss_key_count": miss_key_count,
                "hash_key_count": hash_key_count,
            }
            # adding the total count
            key += key_count
            miss_key += miss_key_count
            hash_key += hash_key_count
        total = key + miss_key + hash_key
        """
        now = time.time()
        timeline_dict = { human_time(timeline): str((float(count_exp)/float(total))*100)[:4] 
                                                                     for timeline, count_exp in timeline_dict.items() 
                                                                                                     if float(timeline) > float(now) } 
        """
        timeline_dict = self.__max_min_timeline(timeline_dict)
        miss_p, hash_p, key_p = 0, 0, 0
        if total != 0:
            miss_p, hash_p, key_p = (
                (float(miss_key) / float(total)) * 100,
                (float(hash_key) / float(total)) * 100,
                (float(key) / float(total)) * 100,
            )
        return (
            count_dict,
            {"key": str(key_p)[:4], "miss_key": str(miss_p)[:4], "hash_key": str(hash_p)[:4]},
            timeline_dict,
        )

    def sortby_slab(self, count_dict):
        return [(slab_id, count_dict[slab_id]) for slab_id in sorted(count_dict)]

    def __max_min_timeline(self, timeline_dict):
        # sorted_timeline_tup = [ ( human_time(exp), timeline_dict[exp] ) for exp in sorted(timeline_dict.keys()) ]
        sorted_exp = sorted(timeline_dict.keys())
        timeline_dict = {}
        expired_count, fresh_count = 0, 0
        for exp in sorted_exp:
            if exp < time.time():
                expired_count += 1
            else:
                fresh_count += 1
        if len(sorted_exp) > 0:
            timeline_dict["first-expiry"] = human_time(sorted_exp[0])
        if len(sorted_exp) > 1:
            timeline_dict["last-expiry"] = human_time(sorted_exp[-1])
        if len(sorted_exp) > 2:
            timeline_dict["second_last-expiry"] = human_time(sorted_exp[-2])
        if len(sorted_exp) > 3:
            timeline_dict["third-last-expiry"] = human_time(sorted_exp[-3])

        timeline_dict.update({"expired": expired_count, "fresh": fresh_count})
        return timeline_dict