放翁(文初)的一亩三分地

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  112 随笔 :: 1 文章 :: 320 评论 :: 0 Trackbacks

    在大型网站中常常会遇到大流量的数据输出问题,过于频繁的输出到DB、文件、第三方系统都会带来不稳定性和低效率。因此需要采用一定的方式来解决这个问题,其实这部分内容的简单处理框架早就用在实际项目中,不过今天正好有外部的朋友问起我,我就整理了一下作为google的开源代码放上去了,这里也简单介绍一下,有兴趣的朋友可以去看看,最好是能够给一些建议。

  

场景:

         应用频繁访问接口服务器,需要控制每个应用在可配置时间段内(例如一分钟)对于某一服务的访问次数,同时需要记录每一次访问内容到数据库中。

几个点:

1. 高并发情况下,集群服务器需要全局计数。(需要将更新和判断作为原子操作,而非两阶段操作,保证高并发事务)

2. 异步日志批量输出。防止高频率访问第三方系统(DB,本地IO),提高性能。

3. 采用黑名单简化计数器判断。

1,3通过memcache就可以实现,如果需要使用客户端可以看看google code上的:http://code.google.com/p/memcache-client-forjava/

这里主要在说一下2,在很多场景中都会有这样的需求,一些需要输出到DB或者文件的内容需要缓存起来异步批量操作,提高性能也降低对于第三方系统的压力。大致设计结构图如下:

 

 自上而下来看,ThreadA,B,C都是程序中其他模块的线程,他们需要输出记录到数据库或者DB中。当有数据到达需要输出时,仅仅只是将数据放入阻塞队列中,而有一个消费者线程池中的线程发现队列中有数据就将数据写入其中某一个线程的数据分页中(每一个线程维护一个自己的内存分页,当页满或者到达了配置的输出间隔时间以后就将页内数据交给输出线程池中的输出线程完成批量数据输出)。


        

下面是三个类图,囊括了这个小工具框架的所有类:

 

         上图是对外提供的异步输出模板,其他模块可以直接使用模板来输出数据。

上图是异步输出器包,是异步输出模板的内置逻辑实现,其他线程直接使用异步输出模板来输出记录。

         上图是消费者和输出线程的接口和默认实现类,可以替换及扩展。

整个框架基本都可以通过配置文件扩展每一个角色(异步输出类,消费者,写出者),扩展方式就是通过在classpath下增加目录META-INF/services/然后将需要扩展的接口作为文件名称,内容就是接口的实现类,这样既可扩展和替换任何一个角色的具体实现。

具体的代码和测试用例可以去http://code.google.com/p/asynwriter/ 下载。

posted on 2009-02-12 21:09 岑文初 阅读(2304) 评论(5)  编辑  收藏

评论

# re: 大流量数据异步输出 2009-02-13 03:53 GhostDog
请问这和直接写到内存数据库比有多少性能差别? 感觉都放内存,应该差不多,线程还要多耗点资源。  回复  更多评论
  

# re: 大流量数据异步输出 2009-02-13 05:17 岑文初
如果使用内存数据库,的却写出的频度可以比普通的数据库要快,但是就算是内存数据库,它的连接资源还是有限的,就算使用连接池,其实在每天几十亿的数据量下还是撑不住的.这里虽然用了线程,但是采用的是比较单一的使用方式,线程切换代价不大.不过这个可以测试一下看看,采用mysql内存数据库,然后每来一条数据就写,与批量异步写看看对于系统压力以及性能来说是否有变化。  回复  更多评论
  

# re: 大流量数据异步输出 2009-02-15 23:33 micstart
请问你的类图用什么工具画的?挺不错的  回复  更多评论
  

# re: 大流量数据异步输出[未登录] 2009-03-23 21:52 Patrick He
@GhostDog
采用异步 IO 的好处是服务程序可以不需要等待 IO 操作执行结束即可返回,这样可以大大提高服务层的吞吐量。  回复  更多评论
  

# re: 大流量数据异步输出 2009-04-07 23:18 srboyzj
你的类图是用EA画的吗?  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: