SEDA论文笔记

 SEDA的全称是staged event-driven architecture,可译为分阶段的事件驱动架构,它具有高并发,能够在高负载下自适应,保持系统稳定的特点。

传统的服务器架构,一般都是一个请求分配一个线程,在一个线程中处理完整个请求。

这种方式的缺点在于,当并发的用户数多的时候,会产生大量的线程。每个线程都要消耗一定的内存,过多的线程也会导致上下文切换带来过多的cpu开销。当请求数量超过服务器处理能力时,系统容易发生雪崩效应,宕机,如下图。

SEDA则是采用分而治之的思想,不再是一个请求在一个线程中完成完整处理,而是把一个请求分为多个阶段,粒度精细化。另外它是事件驱动的,一个请求过来,先构造event_a,然后放到stage_a的请求队列里,stage_a从请求队列里拿到event_a进行处理,处理结束后,构造event_b放到stage_b的请求队列里。Stage之间通过队列来衔接,每个stage单独治理,以此达到解耦,模块化、分治的效果。

上图表示一个stage,其中event handlerstage的处理逻辑,stageevent队列中,取出一个或者多个event放到线程池里执行event handler的逻辑。Stage还会包括一些负载自适应组件,包括profile用于监控stage当前负载,还有controller用来动态调整资源或者对请求进行拒绝和降级操作。

 

SEDA的架构如上图,上面是一个web服务器处理请求的例子。每一个方格里都是一个单独的stage,一个请求可以分为多个stage,形成一个有限状态机,状态迁移由事件触发。从上图可以看出,之所以划分成多个stage,是因为每个stage处理过程使用的资源不同,有的是cpu类型,有的是io类型。例如read header stage采用了nio机制,当读就绪的时候,解析http请求头,基本上是纯cpu的处理,因此这个stage只需要并发N个线程就能达到最高吞吐量(Ncpu核数)。如果是动态页面,那么请求进入下一个stage—dynamic,在这里一般会去查询db或者搜索引擎,拿到动态数据,这个过程会有较大的(IO时间/CPU时间),因此这边需要并发更多线程以达最高吞吐量,最优并发数为((IO时间/CPU时间)+1* N。采用SEDA的好处除了通过stage分治,以达到最高吞吐量之外,还有一个更重要的优势就是在高负载情况下的自适应,自我保护能力。SEDA通过队列来衔接stage,很便于监控每个stage的队列长度,event入队速率,和event处理速率,可以清楚的知道每个stage的负载情况。当一个stage的资源利用率达到上限时,就可以对之后进入队列的event进行拒绝、降级等操作。

由于SEDA具有如上优势,越来越多的服务器架构采用这种方式,例如网络通讯框架MINA、消息框架Mule、还有我们淘宝的Notify

   大部分的web应用基本上都是采用传统的request per thread的方式,如果能够改造成SEDA架构想必性能上面会有较大的提升。目前我们线上使用的是tomcat  AJP协议的BIO连接器,而应用要改造成SEDA,需要异步IO的支持,才能让线程和连接解绑,实现多路复用。虽然最近tomcat 7提供了AJPNIO连接器,但是目前还处于实验阶段,等这个技术成熟后,也许可以考虑把web应用改造成SEDA架构。

 

参考:http://www.eecs.harvard.edu/~mdw/papers/mdw-phdthesis.pdf

 

 

猜你喜欢

转载自hill007299.iteye.com/blog/1914477