文章链接:http://www.hcoding.com/?p=121

  个人站点:JC&hcoding.com

  memcached是什么呢?memcached是一个优秀的、高性能的内存缓存工具。

  memcached具有以下的特点:

  • 协议简单:memcached的服务器客户端通信并不使用复杂的MXL等格式,而是使用简单的基于文本的协议。
  • 基于libevent的事件处理:libevent是个程序库,他将Linux 的epoll、BSD类操作系统的kqueue等时间处理功能封装成统一的接口。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。(libevent是什么)
  • 内置内存存储方式:为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached,重启操作系统会导致全部数据消失。另外,内容容量达到指定的值之后memcached回自动删除不适用的缓存。
  • Memcached不互通信的分布式:memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。他的分布式主要是通过客户端实现的。

  本文主要讲解memcached的连接模型,memcached由一条主线程(连接线程)监听连接,然后把成功的连接交给子线程(工作线程)处理读写操作。N条【启动memcached通过-t命令指定】子线程(工作线程)负责读写数据,一条子线程(工作线程)维护着多个连接。一个conn结构体对象对应着一个连接,主线程(连接线程)成功连接后,会把连接的内容赋值到一个conn结构体对象,并把这个conn结构体对象传递给一条子线程(工作线程)处理。

memcached学习笔记——连接模型

 

conn结构体:

  1 typedef struct conn conn;
  2 struct conn {
  3     int    sfd;
  4     sasl_conn_t *sasl_conn;
  5 
  6     // 连接状态
  7     enum conn_states  state;
  8     enum bin_substates substate;
  9     struct event event;
 10     short  ev_flags;
 11 
 12     // 刚刚出发的事件
 13     short  which;   /** which events were just triggered */
 14 
 15     // read buffer
 16     char   *rbuf;   /** buffer to read commands into */
 17 
 18     // 已经解析了一部分的命令, 指向已经解析结束的地方
 19     char   *rcurr;  /** but if we parsed some already, this is where we stopped */
 20 
 21     // rbuf 已分配的大小
 22     int    rsize;   /** total allocated size of rbuf */
 23 
 24     // 尚未解析的命令大小
 25     int    rbytes;  /** how much data, starting from rcur, do we have unparsed */
 26 
 27     // buffer to write
 28     char   *wbuf;
 29 
 30     // 指向已经返回的地方
 31     char   *wcurr;
 32 
 33     // 写大小
 34     int    wsize;
 35 
 36     // 尚未写的数据大小
 37     int    wbytes;
 38 
 39     /** which state to go into after finishing current write */
 40     // 当写回结束后需要即刻转变的状态
 41     enum conn_states  write_and_go;
 42 
 43     void   *write_and_free; /** free this memory after finishing writing */
 44 
 45     char   *ritem;  /** when we read in an item's value, it goes here */
 46     int    rlbytes;
 47 
 48     /* data for the nread state */
 49 
 50     /**
 51      * item is used to hold an item structure created after reading the command
 52      * line of set/add/replace commands, but before we finished reading the actual
 53      * data. The data is read into ITEM_data(item) to avoid extra copying.
 54      */
 55 
 56     // 指向当下需要完成的任务
 57     void   *item;     /* for commands set/add/replace  */
 58 
 59     /* data for the swallow state */
 60     int    sbytes;    /* how many bytes to swallow */
 61 
 62     /* data for the mwrite state */
 63     struct iovec *iov;
 64     int    iovsize;   /* number of elements allocated in iov[] */
 65     int    iovused;   /* number of elements used in iov[] */
 66 
 67     // msghdr 链表, 一个连接可能有多个 msghdr
 68     // 如果是 UDP, 需要为每一个 msghdr 填写一个 UDP 头部
 69     struct msghdr *msglist;
 70     int    msgsize;   /* number of elements allocated in msglist[] */
 71     int    msgused;   /* number of elements used in msglist[] */
 72     int    msgcurr;   /* element in msglist[] being transmitted now */
 73     int    msgbytes;  /* number of bytes in current msg */
 74 
 75     item   **ilist;   /* list of items to write out */
 76     int    isize;
 77     item   **icurr;
 78 
 79     // 记录任务数量
 80     int    ileft;
 81 
 82     char   **suffixlist;
 83     int    suffixsize;
 84     char   **suffixcurr;
 85     int    suffixleft;
 86 
 87     enum protocol protocol;   /* which protocol this connection speaks */
 88     enum network_transport transport; /* what transport is used by this connection */
 89 
 90     /* data for UDP clients */
 91     int    request_id; /* Incoming UDP request ID, if this is a UDP "connection" */
 92     struct sockaddr request_addr; /* Who sent the most recent request */
 93     socklen_t request_addr_size;
 94 
 95     unsigned char *hdrbuf; /* udp packet headers */
 96     int    hdrsize;   /* number of headers' worth of space is allocated */
 97 
 98     bool   noreply;   /* True if the reply should not be sent. */
 99     /* current stats command */
100     struct {
101         char *buffer;
102         size_t size;
103         size_t offset;
104     } stats;
105 
106     /* Binary protocol stuff */
107     /* This is where the binary header goes */
108     protocol_binary_request_header binary_header;
109     uint64_t cas; /* the cas to return */
110     short cmd; /* current command being processed */
111 
112     // ? 不透明
113     int opaque;
114     int keylen;
115 
116     // 可见是一个链表
117     conn   *next;     /* Used for generating a list of conn structures */
118 
119     // 指向服务于此连接的线程
120     LIBEVENT_THREAD *thread; /* Pointer to the thread object serving this connection */
121 };
View Code

相关文章:

  • 2022-12-23
  • 2021-04-01
  • 2021-07-14
  • 2021-06-03
  • 2021-12-24
  • 2021-12-03
  • 2022-01-17
猜你喜欢
  • 2022-12-23
  • 2021-12-02
  • 2022-01-28
  • 2021-09-23
  • 2021-12-04
相关资源
相似解决方案