memcached-数据结构

1、item(_stritem)结构体(memcached.h 293行-310行):

    item是memcached中存储数据的最小单位,是key-value的抽象,还记录了最近访问时间、消亡时间等重要信息。下面根据源代码一一介绍:

typedef struct _stritem {
    
struct _stritem *next; //下一个item
    
struct _stritem *prev; //上一个item
    
struct _stritem *h_next; //hash表的下一项
    rel_time_t 
time; //最近访问时间
    rel_time_t exptime
; //消亡时间
    
int nbytes; //数据大小
    
unsigned short refcount; //引用计数
    
uint8_t nsuffix; // **的长度 
    
uint8_t it_flags; /* ITEM_* above */
    
uint8_t slabs_clsid;// item所存入的slab
    
uint8_t nkey; //key长度
    
void * end[];
    
/* if it_flags & ITEM_CAS we have 8 bytes CAS */
    
/* then null-terminated key */
    
/* then " flags length\r\n" (no terminating null) */
    
/* then data with terminating \r\n (no terminating null; it's binary!) */
} item;


     在memcached中每个item 是存储在其对应大小的slabclass_t 里的,同时又在hash 表中有记录。既可以使用自己的内存分配机制来减少操作系统在处理内存碎片,添加释放等多余的操作,又可以使用hash 表的性质对其进行快速的定位。

2、slab(slabclass_t)结构体(slabs.c 26行-44行):
     slabclass_t保存了分级大小的空间槽,以分别适用于不同大小的item存放.取决于两个命令行参数,-f和-n.在应用slabclass_t时,定义的是一个数组,该数组长度取决于增长的指数级别和初始值大小(32+chunk_size),每个空间槽是不允许大于1M的,也就是1048576。slabclass是由(MAX_NUMBER_OF_SLAB_CLASSES)个slabclass_t结构体构成的数组,每个slabclass_t结构体的大小是根据增长因子递增的,增长因子可以由客户端来设定,1.28版本的默认值为2,合理的调优增长因子可以避免空间的浪费

typedef struct {
    
unsigned int size; //items大小
    
unsigned int perslab; //每个slab有多少个item

    
 void **slots; //item链表
    
unsigned int sl_total; //已有item的数量
    
unsigned int sl_curr; //第一个空闲链表位置

    
 void *end_page_ptr; //指向下一个空闲item槽的页面结尾地址的指针或者是0
    
unsigned int end_page_free; //在最后分配页面中,存在的items的数量。

    
 unsigned int slabs; //在这个级别中分配了多少个slab

    
 void **slab_list; //slab数组的指针
    
unsigned int list_size; //slab数组大小

    
 unsigned int killing; /* index+1 of dying slab, or zero if none */
    
size_t requested; //需要的字节数
} slabclass_t;

static slabclass_t slabclass[MAX_NUMBER_OF_SLAB_CLASSES];


3、conn结构体(memcached.h 331行-418行):
     conn结构是联系上下文的关键对象。对于每个连接的到来,都有一个conn结构与其对应,并且对应到某个连接状态,进入状态转换而完成操作。
    conn在程序开始也进行了一次预分配,分配200个连接空间。当200个使用完之后便是按需分配,到达一个分配一个。
    connitem、iovec(内核级别缓冲结构)关联

typedef struct conn conn;
struct conn {
    int sfd;
    sasl_conn_t *sasl_conn;
    enum conn_states state;
    enum bin_substates substate;
    struct event event;
    short ev_flags;
    short which; //刚刚被触发的事件

    char *rbuf; //缓存读入的命令
    char *rcurr; //语法分析的位置
    int rsize; //缓存读入命令的大小
    int rbytes; //从rcur开始还有多少信息没有进行语法分析

    char *wbuf;
    char *wcurr;
    int wsize;
    int wbytes;
    
    enum conn_states write_and_go;//在写操作完成后加入什么状态
    void *write_and_free; //在写操作完成后释放该内存

    char *ritem; //指向读入item的value
    int rlbytes;

    //nread信息数据

    /**
     * 在读取数据之前,item被用来保存一个item结构体,

     *这个结构体在读入命令行(set/add/replace)后被创建,
     *数据被读入ITEM_data(item)防止多余拷贝
     */


    void *item; //保存set/add/replace命令

    //总体情况
    int sbytes; //总字节数

    //nwrite信息数据
    struct iovec *iov;
    int iovsize; //在iov[]数组中分配的元素个数
    int iovused; /* number of elements used in iov[] */在iov[]数组中被使用元素的个数


    struct msghdr *msglist;
    int msgsize; //在msglist[]数组中分配的元素个数
    int msgused; //在msglist[]数组中被用的元素个数
    int msgcurr; //正在传送的元素个数
    int msgbytes; //当前msg中的字节数

    item **ilist; //需要输出的item链表
    int isize;
    item **icurr;
    int ileft;

    char **suffixlist;
    int suffixsize;
    char **suffixcurr;
    int suffixleft;

    enum protocol protocol; //此次连接的端口
    enum network_transport transport; //此次连接的传输工具

    //UDP客户端的数据
    int request_id; //UDP连接需要一个ID
    struct sockaddr request_addr; //最近发出请求的地址
    socklen_t request_addr_size;
    unsigned char *hdrbuf; //udp包的头
    int hdrsize; //头部空间

    bool noreply; //如果没发送应答,将被置为true
    //当前环境的命令
    struct {
        char *buffer;
        size_t size;
        size_t offset;
    } stats;

    //二进制协议
    //二进制协议的头
    protocol_binary_request_header binary_header;
    uint64_t cas; //所要返回的cas
    short cmd; //当前所处理的命令
    int opaque;
    int keylen;
    conn *next; /*/用来创建一个conn结构体链表
    LIBEVENT_THREAD *thread; //指向服务的线程
};

http://blog.chinaunix.net/space.php?uid=20548989&do=blog&cuid=2226620

/**
 * Globally accessible settings as derived from the commandline.
 */
struct settings {
    //最大内存, 默认64M,最大2G。通过-m 设定
    size_t maxbytes;
    //最大连接数,默认1024 通过-c设定
    int maxconns;
    //tcp 端口号,通过-p 设置
    int port;
    //ucp 端口号,通过-U 设置
    int udpport;
    //监听IP或SOCKET地址 ,通过-l设定
    char *inter;
    //是否输出debug信息。由-v,-vvv参数设定
    int verbose;
    //时间设定,当使用flsuh时,只需要修改本值,当取出的值时间小于本值时,将被忽略。
    rel_time_t oldest_live; /* ignore existing items older than this */
    //当内存存满时,是否淘汰老数据。默认是是。可用-M修改为否。此时内容耗尽时,新插入数据时将返回失败。
    int evict_to_free;
    //socket模式,使用-s设定。
    char *socketpath;   /* path to unix socket if using local socket */
    //socket文件的文件权限,使用-a设定
    int access;  /* access mask (a la chmod) for unix domain socket */
    //slab分配增量因子,默认围1.25, 可通过-f设定
    double factor;          /* chunk size growth factor */
    //给一个key+value+flags 分配的最小字节数。 默认值为48. 可通过-n修改。
    int chunk_size;
    //工作线程数。默认围4, 可通过-t设定
    int num_threads;        /* number of worker (without dispatcher) libevent threads to run */
    //状态详情的key前缀
    char prefix_delimiter;  /* character that marks a key prefix (for stats) */
    //开启状态详情记录
    int detail_enabled;     /* nonzero if we're collecting detailed stats */
    //每个event处理的请求数
    int reqs_per_event;     /* Maximum number of io to process on each  io-event. */
    //开启cas,"cas"是一个存储检查操作。用来检查脏数据的存操作。在取出数据后,如果没有其他人修改此数据时,本进程才能够存储数据。默认为开启。需要版本:1.3+
    bool use_cas;
    //使用协议, 试过-B参数设定。 可能值为:ascii, binary, or auto, 版本: 1.4.0+
    enum protocol binding_protocol;
    //等待处理的排队队列长度。默认值为1024.
    int backlog;
     //单个item最大字计数。默认1M。可通过-I参数修改。在1.4.2版本之后,这个值可以大于1M,必须小于128M。但memcached会抛出警告,大于1M将导致整体运行内存的增加和内存性能的降低。 版本: 1.4.2+
    int item_size_max;        /* Maximum item size, and upper end for slabs */
    //是否开启sasl
    bool sasl;              /* SASL on/off */
};
Memcached有个stats命令,通过它可以查看Memcached服务的许多状态信息。使用方法如下:
先在命令行直接输入telnet 主机名端口号,连接到memcached服务器,然后再连接成功后,输入stats 命令,即可显示当前memcached服务的状态信息。
比如在我本机测试如下:
stats
STAT pid 1552
STAT uptime 3792
STAT time 1262517674
STAT version 1.2.6
STAT pointer_size 32
STAT curr_items 1
STAT total_items 2
STAT bytes 593
STAT curr_connections 2
STAT total_connections 28
STAT connection_structures 9
STAT cmd_get 3
STAT cmd_set 2
STAT get_hits 2
STAT get_misses 1
STAT evictions 0
STAT bytes_read 1284
STAT bytes_written 5362
STAT limit_maxbytes 67108864
STAT threads 1
END
这里显示了很多状态信息,下边详细解释每个状态项:
1.  pid: memcached服务进程的进程ID
2.  uptime: memcached服务从启动到当前所经过的时间,单位是秒。
3.  time: memcached服务器所在主机当前系统的时间,单位是秒。
4.  version: memcached组件的版本。这里是我当前使用的1.2.6。
5.  pointer_size:服务器所在主机操作系统的指针大小,一般为32或64.
6.  curr_items:表示当前缓存中存放的所有缓存对象的数量。不包括目前已经从缓存中删除的对象。
7.  total_items:表示从memcached服务启动到当前时间,系统存储过的所有对象的数量,包括目前已经从缓存中删除的对象。
8.  bytes:表示系统存储缓存对象所使用的存储空间,单位为字节。
9.  curr_connections:表示当前系统打开的连接数。
10. total_connections:表示从memcached服务启动到当前时间,系统打开过的连接的总数。
11. connection_structures:表示从memcached服务启动到当前时间,被服务器分配的连接结构的数量,这个解释是协议文档给的,具体什么意思,我目前还没搞明白。
12. cmd_get:累积获取数据的数量,这里是3,因为我测试过3次,第一次因为没有序列化对象,所以获取数据失败,是null,后边有2次是我用不同对象测试了2次。
13. cmd_set:累积保存数据的树立数量,这里是2.虽然我存储了3次,但是第一次因为没有序列化,所以没有保存到缓存,也就没有记录。
14. get_hits:表示获取数据成功的次数。
15. get_misses:表示获取数据失败的次数。
16. evictions:为了给新的数据项目释放空间,从缓存移除的缓存对象的数目。比如超过缓存大小时根据LRU算法移除的对象,以及过期的对象。
17. bytes_read:memcached服务器从网络读取的总的字节数。
18. bytes_written:memcached服务器发送到网络的总的字节数。
19. limit_maxbytes:memcached服务缓存允许使用的最大字节数。这里为67108864字节,也就是是64M.与我们启动memcached服务设置的大小一致。
20. threads:被请求的工作线程的总数量。这个解释是协议文档给的,具体什么意思,我目前还没搞明白。

http://codedestiny.iteye.com/blog/706538

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值