memcached线程模型
直接上图:
memcached使用多线程模型,一个master线程,多个worker线程,master和worker通过管道实现通信。
每个worker线程有一个队列,队列元素为CQ_ITEM。
typedef struct {
pthread_t thread_id; /* unique ID of this thread */
struct event_base *base; /* libevent handle this thread uses */
struct event notify_event; /* listen event for notify pipe */
int notify_receive_fd; /* receiving end of notify pipe */
int notify_send_fd; /* sending end of notify pipe */
struct thread_stats stats; /* Stats generated by this thread */
struct conn_queue *new_conn_queue; /* queue of new connections to handle */
cache_t *suffix_cache; /* suffix cache */
logger *l; /* logger buffer */
void *lru_bump_buf; /* async LRU bump buffer */
} LIBEVENT_THREAD; /* An item in the connection queue. */
typedef struct conn_queue_item CQ_ITEM;
struct conn_queue_item {
int sfd;
enum conn_states init_state;
int event_flags;
int read_buffer_size;
enum network_transport transport;
conn *c;
CQ_ITEM *next;
}; /* A connection queue. */
typedef struct conn_queue CQ;
struct conn_queue {
CQ_ITEM *head;
CQ_ITEM *tail;
pthread_mutex_t lock;
};
memcached使用libevent实现事件监听,master和worker各有一个event_base。
起初,master负责监听连接的到来,worker线程负责监听管道的读事件。
当有一个连接到来,master线程accept该连接,并将conn_fd封装成一个CQ_ITEM对象放入一个worker线程的队列中,同时向管道写入数据触发管道读事件。
对应worker线程执行管道读事件的回调函数thread_libevent_process:
/*
* Processes an incoming "handle a new connection" item. This is called when
* input arrives on the libevent wakeup pipe.
*/
static void thread_libevent_process(int fd, short which, void *arg) {
LIBEVENT_THREAD *me = arg;
CQ_ITEM *item;
char buf[];
unsigned int timeout_fd; if (read(fd, buf, ) != ) {
if (settings.verbose > )
fprintf(stderr, "Can't read from libevent pipe\n");
return;
} switch (buf[]) {
case 'c':
item = cq_pop(me->new_conn_queue); if (NULL != item) {
conn *c = conn_new(item->sfd, item->init_state, item->event_flags,
item->read_buffer_size, item->transport,
me->base);
if (c == NULL) {
if (IS_UDP(item->transport)) {
fprintf(stderr, "Can't listen for events on UDP socket\n");
exit();
} else {
if (settings.verbose > ) {
fprintf(stderr, "Can't listen for events on fd %d\n",
item->sfd);
}
close(item->sfd);
}
} else {
c->thread = me;
}
cqi_free(item);
}
break;
case 'r':
item = cq_pop(me->new_conn_queue); if (NULL != item) {
conn_worker_readd(item->c);
cqi_free(item);
}
break;
/* we were told to pause and report in */
case 'p':
register_thread_initialized();
break;
/* a client socket timed out */
case 't':
if (read(fd, &timeout_fd, sizeof(timeout_fd)) != sizeof(timeout_fd)) {
if (settings.verbose > )
fprintf(stderr, "Can't read timeout fd from libevent pipe\n");
return;
}
conn_close_idle(conns[timeout_fd]);
break;
}
}
在conn_new中,将conn_fd的读事件添加进自己的event_base中。
至此,worker线程开始监听连接上的I/O事件。
参考资料:
Memcached源码分析之线程模型
memcached线程模型的更多相关文章
- Memcached源码分析之线程模型
作者:Calix 一)模型分析 memcached到底是如何处理我们的网络连接的? memcached通过epoll(使用libevent,下面具体再讲)实现异步的服务器,但仍然使用多线程,主要有两种 ...
- 2.redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?
作者:中华石杉 面试题 redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 面试官心理分析 这个是问 redis 的时候,最基本的 ...
- redis和memcached有什么区别?redis的线程模型是什么?为什么单线程的redis比多线程的memcached效率要高得多(为什么redis是单线程的但是还可以支撑高并发)?
1.redis和memcached有什么区别? 这个事儿吧,你可以比较出N多个区别来,但是我还是采取redis作者给出的几个比较吧 1)Redis支持服务器端的数据操作:Redis相比Memcache ...
- redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?
redis 和 memcached 有啥区别? redis 支持复杂的数据结构 redis 相比 memcached 来说,拥有更多的数据结构,能支持更丰富的数据操作.如果需要缓存能够支持更复杂的结构 ...
- Redis 和 Memcached 有什么区别?Redis 的线程模型是什么?为什么单线程的 Redis 比多线程的 Memcached 效率要高得多?
面试题 redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 面试官心理分析 这个是问 redis 的时候,最基本的问题吧,redi ...
- redis的线程模型是什么?
1.面试题 redis和memcached有什么区别? redis的线程模型是什么? 为什么单线程的redis比多线程的memcached效率要高得多(为什么redis是单线程的但是还可以支撑高并发) ...
- Java NIO学习与记录(六): NIO线程模型
NIO线程模型 上一篇说的是基于操作系统的IO处理模型,那么这一篇来介绍下服务器端基于IO模型和自身线程的处理方式. 一.传统阻塞IO模型下的线程处理模式 这种处理模型是基于阻塞IO进行的,上一篇讲过 ...
- 关于redis的几件小事(二)redis线程模型
1.memcached和redis有什么区别? (1)Redis支持服务器端的数据操作 redis和memcached相比,redis拥有更多的 数据结构并且支持更丰富的数据操作 ,通常在memcac ...
- 《【面试突击】— Redis篇》-- Redis的线程模型了解吗?为啥单线程效率还这么高?
能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>-- Redis的线程模型了解吗?为啥单线程效率还这 ...
随机推荐
- Python Requests-学习笔记(3)-处理json
JSON响应内容 Requests中也有一个内置的JSON解码器,助你处理JSON数据: r = requests.get('https://github.com/timeline.json') pr ...
- 经常使用到的vim命令
常用的vim命令 总结了我经常用到的vim命令,虽然不是很全,但是日常的开发足够了 启动vim vim 直接启动vim vim filename 打开vim并创建名为filename的文件 插入命令 ...
- conda命令详解
显示已有环境信息 conda info --envs 创建环境 conda create --name [环境名] python=[版本号] 删除环境 conda remove --name [环境名 ...
- 国外的一个代码 仓库 github --- 里面类似一个svn 的代码仓库
https://github.com/wzhanke/shell 用户:wzh.e 邮箱:wzh.e@x.com 登陆密码:*wzh.e8*9
- jpa是什么,和hibernate 有什么关系
JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.JPA 的目标之一是制定一个可以由很多供应商实现的API,并且开发人员可以编码来实现该API,而不 ...
- 数据结构和算法(Golang实现)(17)常见数据结构-树
树 树是一种比较高级的基础数据结构,由n个有限节点组成的具有层次关系的集合. 树的定义: 有节点间的层次关系,分为父节点和子节点. 有唯一一个根节点,该根节点没有父节点. 除了根节点,每个节点有且只有 ...
- Levenshtein算法-比较两个字符串之间的相似度
package com.sinoup.util;/** * Created by Administrator on 2020-4-18. */ /** * @Title: * @ProjectName ...
- AJ学IOS(43)之网易彩票底部自定义TabBar实现切换
AJ分享,必须精品 效果: 代码: NYTabBarController // // NYTabBarController.m // 彩票lottery // // Created by apple ...
- 使用Docker快速搭建PHP开发环境
最近有个同事找过来,希望我对在很早之前写的一个PHP网站上增加一些功能,当时开发使用xampp构建的本地开发环境,但是现在我的笔记本电脑已经更新,没有当时的开发环境.本着尽量不往电脑上装无用软件的原则 ...
- 解决同层hover事件重叠闪烁问题
完整代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...