`

Memcached的服务设计与启动过程——C10K系列

阅读更多
C10k要解决的问题,是10K个连接。
LINUX下,使用EPOLL可实现异步非阻塞(注:阻塞的一定是同步的,阻塞是调用方自己阻塞自己(等待事件))
非阻塞:是指调用方不会阻塞自己,如被调用方有数据就返回,无数据就返回EAGAIN,调用方根据EAGAIN决定自己的策略。因此非阻塞,和异步没有任何关联。
异步:是相对于同步的。异步是指:调用的时机和返回的时机不是同一时刻。异步说的是一个处理流程,而并不一定是具体的某个函数。

举例如下:
你在电子商城买了一本书,你已经下单;但是,这时候商城并没有立即给你发单,而是有合适时候时,主动通知你,我已经发单了。
因此,下单,和发单不是同一时刻。
一般来说,异步需要通过回调函数来实现。即先需要注册一个异步处理流程,如必须先将你的手机号告诉给商城。
当然,也有异步服务。比如用网银买火车票。火车票网站转到网银,网银付账是一个同步的过程。但是火车票网站与网银的处理是异步的。火车票网站,不知道网银交易何时完成;网银交易完成后,再发个消息给火车票网站交易完成。

---------------------------------------------------------------------------------
Memcached,版本1.4.20:基于libevent的多线程实现
采用的是一个主线程(dispatcher_thread),多个工作线程worker(LIBEVENT_THREAD),
(1)主线程dispatcher_thread负责接收外部请求事件,然后派发给工作线程处理。
(2)主线程dispatcher_thread和工作线程的通过管道传递消息。(实际上,是工作线程添加了一个与主线程关联的管道的事件 (libevent 的event))

对于TCP连接来说,主线程(dispatcher_thread)是一个监听线程,即监听外部的服务请求。
主线程(dispatcher_thread)的定义:
typedef struct {
pthread_t thread_id;

/* unique ID of this thread */
struct event_base *base;
/* libevent handle this thread uses */
} LIBEVENT_DISPATCHER_THREAD;

工作线程Worker的定义:
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 conn_queue *new_conn_queue; /* queue of new connections to handle */
} LIBEVENT_THREAD;

Libevent 的main函数比较长,但与网络请求相关的是serversocket的创建和thread_init函数。

第一步:多线程服务初始化thread_init()
服务的初始化是在thread_init()完成的,主要完成主线程(dispatcher_thread),多个工作线程worker(LIBEVENT_THREAD)事件注册,管道通知等:
(1)初始化主线程dispatcher_thread的event base,event;
(2)初始化管道,将主线程dispatcher_thread与工作线程worker,通过管道关联。
for (i = 0; i notify_event, me->notify_receive_fd,
EV_READ | EV_PERSIST, thread_libevent_process, me);
event_base_set(me->base, &me->notify_event);

if (event_add(&me->notify_event, 0) == -1) {
fprintf(stderr, "Can't monitor libevent notify pipe\n");
exit(1);
}
§ thread_libevent_process:这个函数,是接收到数据的具体处理过程,其参数是线程句柄
§ 初始化工作线程自己的请求队列。
LIBEVENT_THREAD中的struct conn_queue *new_conn_queue;这个是请求队列。
(4)启动工作线程
创建Worker线程(LIBEVENT_THREAD),其函数入口是:
static void *worker_libevent(void *arg)
里面是一个event_base_loop()的消息循环。
(5)到这里,工作线程已经完成初始化和启动(即工作线程已经可以工作了)。主线程只要等待工作线程启动完毕。

第二步,serversocket创建:和所有网络服务一样:create the listening socket, bind it, and init
server_sockets(settings.port, tcp_transport,
portnumber_file)

new_socket:
获取socket的设置:fcntl(sfd, F_GETFL, 0))
将其设置为非阻塞:fcntl(sfd, F_SETFL, flags | O_NONBLOCK) 

socket设置:根据配置文件
SO_REUSEADDR,//地址重用
SO_KEEPALIVE,//是否保持连接,这是TCP层的控制
SO_LINGER,//延时断开连接。ngingx默认也启用
TCP_NODELAY,//不启用Neagle算法(本科书中的滑动窗口拥塞控制协议),一般内网访问,常设置为true
bind:
listen:
listen_conn_add = conn_new(sfd, conn_listening,
EV_READ | EV_PERSIST, 1,
transport, main_base);//main_base要和创建的server socket关联
这里的
conn_new函数:
初始化conn(一个超级复杂的结构体)
设置事件与socket 的fd,与main_base关联,设置事件响应的具体处理函数,event_handler
添加事件
到这里,才把main_base(event_base* 类型)与监听事件关联完成。

第三步:
主消息循环;整个服务启动过程结束。

备注:主线程dispatcher_thread未必是程序启动的main thread,可以是一个独立的thread。
分享到:
评论

相关推荐

    memcached启动错误解决

    在使用memcached服务时,可能会遇到启动失败的问题,这通常是由于多种原因引起的。memcached是一款轻量级、高性能的分布式内存对象缓存系统,广泛应用于Web应用中,用于减轻数据库负载。本文将探讨如何解决memcached...

    在Linux上安装Memcached服务

    本指南将详细介绍如何在Linux上下载、安装和启动Memcached服务。 首先,你需要下载Memcached的源代码包。在撰写本文时,可用的版本是memcached-1.2.2,但建议访问官方网站(http://memcached.org/downloads)获取...

    java中连接memcached服务器

    Java连接Memcached服务器是开发过程中常见的一环,尤其是在构建分布式系统时,利用Memcached作为缓存服务可以显著提升数据访问速度。Memcached是一款高性能、分布式内存对象缓存系统,能够临时存储键值对数据,减轻...

    搭建Memcached缓存服务器1

    * 启动Memcached缓存服务器需要使用service命令启动服务。 * 设置Memcached缓存服务器开机启动需要使用chkconfig命令设置服务。 * 连接Memcached缓存服务器需要使用memcached-tool命令连接服务。 * 使用Telnet客户端...

    基于内存的K-V数据平台(Memcached)

    **基于内存的K-V数据平台——Memcached** Memcached是一款高性能、分布式内存对象缓存系统,主要用于加速动态Web应用,通过将数据存储在内存中,减少数据库的访问次数,从而提高应用性能。它是一个轻量级的服务,...

    Memcached实例与文档

    3. 启动:启动Memcached服务,使其开始监听并接受客户端请求。 4. 连接:使用支持Memcached的客户端库(如Python的pylibmc,Java的spymemcached)连接到服务器实例。 5. 存储与检索:将数据存储到Memcached中,使用...

    linux下memcached的启动/结束的方式

    本文将详细介绍如何在Linux环境下启动和停止Memcached服务。 首先,确保你的系统已经安装了Memcached。如果没有,可以通过包管理器进行安装。对于基于Debian的系统(如Ubuntu),可以使用`apt-get`命令: ```bash ...

    Memcached服务器(windows版本和Windows server版本)

    可以直接运行这个文件启动服务,或者通过命令行参数配置服务器端口、最大内存等参数。 - **Windows Server版本**: `memcached windows server.zip` 是针对Windows Server操作系统的版本。安装过程与Windows类似,但...

    windows下的memcached服务组件

    - **编辑配置文件**: Windows用户还可以创建一个名为`memcached.ini`的配置文件,将命令行参数写入其中,然后通过`memcached.exe -c memcached.ini`启动服务。 **4. 使用Memcached** - **客户端连接**: 为了与运行...

    java连接memcached服务的jar

    java连接memcached服务的jar

    linux下编译安装memcached服务.pdf

    - 启动服务:`./memcached -d -m 1024 -u root -l 127.0.0.1 -p 11211 -P /tmp/memcached.pid` - 关闭服务:`kill `cat /tmp/memcached.pid``,这会根据`/tmp/memcached.pid`文件中的进程ID结束Memcached服务。 ...

    memcached 64位 window

    3. **启动**:通过命令行工具启动Memcached服务。 4. **客户端库**:选择合适的编程语言(如PHP、Python、Java等)的客户端库,连接到Memcached服务器。 5. **测试和优化**:通过测试确保缓存工作正常,监控内存使用...

    Linux(Cent OS7.2)下启动停止memcached方法及ps命令使用讲解.docx

    本文档主要讲解了在 Linux(Cent OS7.2) 环境下安装、启动和停止 Memcached 服务的方法,并对 ps 命令的使用进行了详细讲解。 一、Memcached 服务安装 在 Linux(Cent OS7.2) 环境下,可以使用 yum 源安装 Memcached...

    缓存服务器memcached下载

    安装完成后,需要配置启动参数,如监听端口、最大内存大小等,然后启动服务。 **四、Memcached的客户端库** Memcached支持多种编程语言的客户端库,包括PHP、Python、Java、Ruby、C++等,这些库提供了与Memcached...

    windows下memcached+memcached.dll 5.3.8

    4. **启动服务**: 使用创建的服务脚本或通过服务管理器启动Memcached服务。 5. **PHP扩展安装**: 描述中的`php_memcache.dll`是PHP的Memcache扩展,用于在PHP中与Memcached服务器通信。将其添加到PHP的`ext`目录下...

    linux下memcached安装以及启动

    ### Linux 下 Memcached 的安装与启动...以上就是 Linux 环境下 Memcached 的安装与启动全过程。通过这些步骤,你可以成功地在 Linux 系统上部署并使用 Memcached,为你的应用程序提供高速缓存服务,显著提升应用性能。

    memcached windows稳定版

    NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。 4.下载php_memcache.dll,请自己查找对应的php版本的文件 5. 在C:\winnt\php.ini 加入一行 ‘extension=...

    2021Java字节跳动面试题——面向字节_Memcached.pdf

    当客户端需要检索数据时,只需要重复上述过程,即可直接从相应的Memcached服务器获取数据。 #### 三、Memcached的水平扩展能力 Memcached的最大优势之一是其出色的水平扩展能力。这是因为客户端负责计算哈希值并...

Global site tag (gtag.js) - Google Analytics