阅读memcached时对工作模式非常惊奇,有点类似于nginx中对于主进程和工作进程的处理,memcached对于工作模式,分出了主线程和工作线程池, 线程池中的每一个工作线程都有一个任务队列,当有新的连接请求到到时,按顺序从线程池中找出一个线程,将新的连接封装成任务,将新的任务插入到顺序选出的线程的任务队列里。每个线程中都创建了管道,和libevent结合用于和主线程交互通知。
可以看出,memcached对于工作线程池的使用,是平均性的,对线程池中的各个线程的负载并没有处理,线程池像一个无状态的调度资源一样供食用,每一个线程的任务队列都包含了N个socket连接。memcached顾名思义是基于内存,所有的容器数据都存放在内存中,容器中数据的组织使用了LRU调度,按照访问的时间和频率分成了四个队列,每次都插入队列的头部,优先从HOT队列的HASH中寻找,按照使用频率调动四个队列的数据。
作为内存缓存,memcached的IPC通信方式使用了UNIX本地域,socket函数中第一个参数是AF_UNIX,这种类型的socket限定本地使用,数据发送时,直接由内核的发送缓冲区复制到读缓冲区,然后发送SIGIO信号给相应的进程或线程进行处理。与AF_INET类型的socket区别在于AF_UNIX的数据并不进入链路层,也不对传递到内核的数据进行封包和解包,就是说不存在包头,根据socketaddr地址进行拷贝数据,直接从一个进程拷贝到另一个进程。由此可以看出,不用利用外设网卡驱动发送数据,也不占用CPU来对数据包进行包头的添加和处理,速度快于TCP/UDP的方式。