[随笔] Scala Actor在某些大并发场景下的局限性

coollzh 2011-09-30
Scala以支持多核,多线程,并发为大家所乐道。特别是Actor体系,使用非常方便。我看完了Scala程序设计-Java虚拟机多核编程实战 这本书,该书对Actor进行大篇幅的介绍。Actor确实不错,但最近我的项目出现一个这样的场景,我对大量的请求进行发并发处理,每秒可能上1000个请求,请求是异步处理的,就说我不需要立即返回处理解过,我可以把请求放入队列后用线程池慢慢处理。
   按说,这个场景非常适合Scala Actor来处理:
   一开始,我创建了一个actor,把所有的消息都发送到这个actor进行处理,但发现这个actor不能并发处理,只有一个活动线程,处理完一个才能处理下一个,显然不能满足我的需求。
  
  没办法,我只能每次来一个请求就创建一个actor,这样每个请求都在自己独立的线程里处理,现实了并发。但是这样做可能有几个潜在的问题:
  1. 每次创建一个actor,不清楚scala是复用线程池里的线程,还是每次都创建新的线程,如果每次都创建新的话,系统开销相当大。
  2.如果请求量比较大,而处理又慢的情况下,系统很快会因为创建过多的线程而变得很慢,很容易崩溃。

  为了防止第二种危险的情况发生,我只能维护一个Actor的Pool,轮流向Actor里发消息,为了最优化系统开销,我可能每次需要poll 那个actor空闲;
  如果请求比较小的情况,我还要shutdown那些空闲的actor,压力上来了,我再创建一批新的actor. 这样是解决问题了,但是带来了新的复杂度。与其这样,我还不如使用java 5的ExecuteService的FixedThreadExecutor呢,我只要传递任务给executor,它内部会自动排队,实现用线程池。代码简单的很多。

  我看了Scala的concurrency包,发现scala确实只对java5的executorService做了一层薄薄的简单包装。由此可见java在多线程编程方便确实做得不错,scala在这方便的优势越来越小了。
 
   不知道twitter的那个著名的内存队列是怎么实现的,据说只有1000左右的代码,非常自然地使用actor来实现的,10.1有空研究下。
jilen 2011-09-30
可以创建大量的actor,但注意最好不要用receive,创建大量actor一般来说不会产生问题(除非实在太多导致outOfMemory),并不会创建大量新的线程。而是采用一个fork/jion thread pool做统一调度
coollzh 2011-09-30
jilen 写道
可以创建大量的actor,但注意最好不要用receive,创建大量actor一般来说不会产生问题(除非实在太多导致outOfMemory),并不会创建大量新的线程。而是采用一个fork/jion thread pool做统一调度


但是如果请求队列处理比较慢,怎么销平"锋","谷"呢,即量大的时候可以Queued,不至于系统因为突然的请求高峰,造成严重的性能问题
coollzh 2011-09-30
另外,如果创建大量的actor,似乎就失去了actor的mailbox作用了.
jilen 2011-09-30
fork/jion thread pool似乎是更适合并行executorservice。你可以查看相关的jsr和jdk7或scala实现,看看有没有queued
coollzh 2011-10-03
jilen 写道
fork/jion thread pool似乎是更适合并行executorservice。你可以查看相关的jsr和jdk7或scala实现,看看有没有queued


既然是线程池,我相信肯定是有个默认限度的,不可能无限制创建的,可是似乎没有地方可以控制线程池的大小
alang 2011-10-08
请认真考虑 Akka,Scala上的分布式计算的库。
coollzh 2011-10-08
alang 写道
请认真考虑 Akka,Scala上的分布式计算的库。


Akka好像也有java的版本,应该不是scala特有的
jilen 2011-10-28
相对多一些数量的actor并不会带来性能问题。单个actor显然是单线操作的。甚至,每个请求创建一个actor,执行完任务后立即关闭。这样的话,如果你的服务器cpu性能提升,系统的性能也会急剧上升。甚至你可以认为actor只是一个runnable。
jilen 2011-10-31
jilen 写道
相对多一些数量的actor并不会带来性能问题。单个actor显然是单线操作的。甚至,每个请求创建一个actor,执行完任务后立即关闭。这样的话,如果你的服务器cpu性能提升,系统的性能也会急剧上升。甚至你可以认为actor只是一个runnable。

我的说法有些问题,actor确实如runnable那样轻量级,但它居然是不会被回收的,akka貌似没有这个问题
Global site tag (gtag.js) - Google Analytics