2007-05-20
half-sync/half-async,SEDA 和 生产者/消费者
关键字: 半同步半异步 SEDA
在这里看到关于 Mina based SMTP handler 的讨论,里面提到 mina 是 SEDA 的一个实现。
mina and SEDA
看到之后,忽然想到,half-sync/half-async 模式其实也可以看成是 SEDA 的一个实现。SEDA 是一个更抽象、更全面的描述,而 half-sync/half-async 模式可以看成是 SEDA 的一个具体的,更有针对性的实现。
SEDA 的论文里有以下这样的描述,这个正是典型的 half-sync/half-async 要解决的问题。
First, the use of threads relaxes the constraint that all event-processing code be non-blocking, allowing an event handler to block or be preempted if necessary. In a traditional event-driven system, all blocking operations must explicitly capture the state of the computation and restore it when the operation completes. In SEDA, threads act as implicit continuations, automatically capturing the execution state across blocking operations.
half-sync/half-async 模式中的层就相当于 SEDA 中的 stag。在 half-sync/half-async 模式中,有一个异步层和同步层;而在 SEDA 中,可以有任意多的 stage,每个 stage 可以是同步的,也可以是异步的。所以可以认为 half-sync/half-async 是 SEDA 的一种简化后的实现。
half-sync/half-async 模式也可以从 生产者/消费者 的角度来描述。
在 spserver 中,同步层和异步层轮流扮演这两个角色。
异步层从 socket 读入数据,然后放到同步层的队列中,这个时候异步层是生产者,同步层是消费者。同步层处理完之后,把输出数据放到异步层的队列中,这个时候同步层是生产者,异步层是消费者。
mina and SEDA
It uses non-blocking IO and is an implementation of the staged event driven architecture (SEDA). SEDA makes it possible to have thousands of concurrent network connections.
看到之后,忽然想到,half-sync/half-async 模式其实也可以看成是 SEDA 的一个实现。SEDA 是一个更抽象、更全面的描述,而 half-sync/half-async 模式可以看成是 SEDA 的一个具体的,更有针对性的实现。
SEDA 的论文里有以下这样的描述,这个正是典型的 half-sync/half-async 要解决的问题。
First, the use of threads relaxes the constraint that all event-processing code be non-blocking, allowing an event handler to block or be preempted if necessary. In a traditional event-driven system, all blocking operations must explicitly capture the state of the computation and restore it when the operation completes. In SEDA, threads act as implicit continuations, automatically capturing the execution state across blocking operations.
half-sync/half-async 模式中的层就相当于 SEDA 中的 stag。在 half-sync/half-async 模式中,有一个异步层和同步层;而在 SEDA 中,可以有任意多的 stage,每个 stage 可以是同步的,也可以是异步的。所以可以认为 half-sync/half-async 是 SEDA 的一种简化后的实现。
half-sync/half-async 模式也可以从 生产者/消费者 的角度来描述。
在 spserver 中,同步层和异步层轮流扮演这两个角色。
异步层从 socket 读入数据,然后放到同步层的队列中,这个时候异步层是生产者,同步层是消费者。同步层处理完之后,把输出数据放到异步层的队列中,这个时候同步层是生产者,异步层是消费者。
评论
iunknown
2007-05-21
引用
将要阻塞的接口调用,封装到一个Task里面,然后扔到线程池执行. 在接口调用后,会执行一个callback来继续之前的流程.
这种做法本质上和 SEDA 并没有不同,不同的只是 SEDA 或者 half-sync/half-async 把这种做法做了一个规范化的设计,规定了不同的层之间是怎么通信的,并且做了一部分的封装,以方便使用。a
Arbow
2007-05-21
受教了:)
在我的Server开发项目里面,我是将要阻塞的接口调用,封装到一个Task里面,然后扔到线程池执行. 在接口调用后,会执行一个callback来继续之前的流程.
这样做,现在感觉更为复杂,相比seda并不直观。
在我的Server开发项目里面,我是将要阻塞的接口调用,封装到一个Task里面,然后扔到线程池执行. 在接口调用后,会执行一个callback来继续之前的流程.
这样做,现在感觉更为复杂,相比seda并不直观。
iunknown
2007-05-21
用“应用为主”和“性能为主”来分类并不合理。“应用”和“性能”在这里并没有明确地定义。
对于 memcached,haproxy 这类应用程序,除了在 SocketIO 之外,其他的处理逻辑一般都是纯计算的(在 memcached 中主要是内存池的分配,hash 表的维护)。即从理论上来说,只有在 SocketIO 这一个点上会造成阻塞。因此只要针对 SocketIO 使用 non-blocking 的选项就可以使用 single-thread event-driven 这种实现方式了。
但是并不是所有的要求高性能的应用程序都只在 SocketIO 这一个点上会造成阻塞。比如在一个典型的 MTA (Mail Transfer Agent) 中,通常需要支持 SMTP AUTH 命令。SMTP AUTH 的时候需要做数据库的查询。这个时候就比较难把这个操作转化为 non-blocking 的形式。一是因为几乎所有的数据库提供的 client api 都是 block 形式的;其次,即使有 non-blocking 形式的数据库 api ,也可以想像到这种 api 将会难于使用。
因此对于是否使用多线程,关键点在于是否有一些操作是 block 的,并且难于把这些 block 的操作转化为 non-blocking 的操作。如果是,那么就可以使用多线程来降低编程的难度。
对于 memcached,haproxy 这类应用程序,除了在 SocketIO 之外,其他的处理逻辑一般都是纯计算的(在 memcached 中主要是内存池的分配,hash 表的维护)。即从理论上来说,只有在 SocketIO 这一个点上会造成阻塞。因此只要针对 SocketIO 使用 non-blocking 的选项就可以使用 single-thread event-driven 这种实现方式了。
引用
In a traditional event-driven system, all blocking operations must explicitly capture the state of the computation and restore it when the operation completes.
但是并不是所有的要求高性能的应用程序都只在 SocketIO 这一个点上会造成阻塞。比如在一个典型的 MTA (Mail Transfer Agent) 中,通常需要支持 SMTP AUTH 命令。SMTP AUTH 的时候需要做数据库的查询。这个时候就比较难把这个操作转化为 non-blocking 的形式。一是因为几乎所有的数据库提供的 client api 都是 block 形式的;其次,即使有 non-blocking 形式的数据库 api ,也可以想像到这种 api 将会难于使用。
因此对于是否使用多线程,关键点在于是否有一些操作是 block 的,并且难于把这些 block 的操作转化为 non-blocking 的操作。如果是,那么就可以使用多线程来降低编程的难度。
Arbow
2007-05-21
对于SEDA这种模型,从性能上,会存在着大量线程切换开销,以及队列读写的锁开销。一些号称高性能的程序,比如memached,haproxy,都是使用单线程的event driven,在一个循环中处理网络分发和定时器事件等。
是否只应该在一些以应用为主的server上使用seda,充分发挥多线程多核的优势,而性能为主的应用,比如proxy,还应该使用单线程事件取得模型呢?
是否只应该在一些以应用为主的server上使用seda,充分发挥多线程多核的优势,而性能为主的应用,比如proxy,还应该使用单线程事件取得模型呢?
发表评论
- 浏览: 79327 次

- 详细资料
搜索本博客
我的相册
vim
共 2 张
共 2 张
最近加入圈子
最新评论
-
集成 IOCP 到 Libevent
去找了 memcached for win32 的源代码,结果可以顺利编译,并且 ...
-- by iunknown -
集成 IOCP 到 Libevent
qiezi 写道GetQueuedCompletionStatusEx也支持超时 ...
-- by iunknown -
集成 IOCP 到 Libevent
GetQueuedCompletionStatusEx也支持超时,用它代替sel ...
-- by qiezi -
集成 IOCP 到 Libevent
linux/solaris上的aio有多种回调/通知方式,可能和libevent ...
-- by qiezi -
集成 IOCP 到 Libevent
SPServer是一个很不错的框架,受到启发,我用boost::asio实现了一 ...
-- by wow






评论排行榜