Why AsyncFP 引起的一场争论

11-12-28 banq
基于Scala的函数式编程高性能Actor开源框架AsyncFP发布后,在Scala领域引起了一场争论,争论关键还是如何更好地利用底层硬件或操作系统机制,以及如何更好地切合JVM。

争论文章地址:Why AsyncFP? Does Scala really need another type of actor? 我们是否真的还需要另外一种Actor呢?

在Why AsyncFP这个PDF中,作者谈到:

● Computers are getting fatter, not faster. An i9 chip has

12 hardware threads. A Spark T4 has 64 hardware

threads.

计算机越来越胖,而不是越来越快。i9有12个硬件线程,而Spark T4有64个硬件线程。

● Code that can use all that hardware is very difficult to

write. Often it is better to use that extra hardware for

something like EJB when its performance is good

enough

试图使用所有的硬件线程的编程代码是难以编写的,较好的办法使用额外硬件(水平扩展Scalable)。(banq注:这也是为什么我经常提出进行一些宏观解决方案的原因。)

● Even when multi-threaded code is correct, it often runs

slower than single-threaded code.

即使多线程代码编写正确了,它也经常会比单线程代码运行慢(banq注:共享锁可能带来的)

● Single-threaded servers written using Node.js are

popular because they are fast and easy to write. But

then what do we do with really fat computers?

这也就是为什么使用Node.js编写的单线程服务器受到如此欢迎的原因,因为他们快而且易于编写,但是我们为什么又需要这些有很多线程的胖计算机呢?

待续...

                   

9
banq
2011-12-28 10:10
2011年12月28日 09:48 "@banq"的内容
但是我们为什么又需要这些有很多线程的胖计算机呢? ...

需要这么多硬件线程的原因是:在基于流的编程范式中Flow-Based Programming,线程之间需要交换大量数据,而只有当存在很多线程的情况下,才具有很好的扩展性,也就是性能线性增长,比如两个线程忙于交换数据,这时就无法腾出手来处理业务逻辑,而多线程有几十个线程,这样其他空闲的线程可以继续处理从客户端请求过来的业务。

But high throughput is achieved by passing large blocks of data, not by passing one message at a time.

这是指Scala中现有的Actor模型问题,要获得高吞吐量,必须在线程之间通过传递大块的数据才能获得,而不是一次只传递一个消息,这样就无法获得很高的数据吞吐量。

所以,Passing data between threads is slow! 在Scala中线程之间传递数据是慢的,实际上,如果软件线程和硬件线程共享一个VM操作系统进程时传递数据是快的,很显然Scala的Actor模型没有很好地利用这些操作系统和硬件特性,所以,Scala需要一种全新的Actor模型。

banq
2011-12-28 10:20
现在,我们面对这样的现实:提供很多硬件线程的胖计算机(双核直至多核);这时你的系统访问量要求很高,比如需要并发1万或更多;而应用非常复杂,是中大型项目;数据库采取的无容量限制的NoSQL。

在这样条件下,我们有三种架构选择,Why AsyncFP一文提出的第一种选择如下图,也就是我们通常的水平扩展Scalable架构,通过增加额外计算机方式实现分布式直至云计算架构,回避内部多线程问题,每个应用服务器甚至都可以是使用Node.js这样单线程服务器,这样的架构部署容易,技术方案成熟,但是开销很大。

[该贴被banq于2011-12-28 10:23修改过]


banq
2011-12-28 10:30
2011年12月28日 10:20 "@banq"的内容
我们有三种架构选择 ...

第二种解决方案是:每次客户端Http请求分配一个线程为指服务,直至其完成响应,典型的如JavaEE服务器如tomcat等等,每个线程都有自己的堆栈,但是问题是扩展性难。

多线程情况下,存在共享内存资源争夺的情况,比如Java每个线程有自己堆栈,通过共享Heap实现状态共享,引入同步锁机制避免资源争夺,造成了性能扩展性差。


banq
2011-12-28 10:36
2011年12月28日 10:30 "@banq"的内容
引入同步锁机制避免资源争夺,造成了性能扩展性差 ...

Scala的Actor模型克服了第二种资源争夺的问题,但是Scala的Actor也存在以下问题:

Actors虽然很scalable. 但是对用于服务一个用户http请求的消息数量是有限制的,因为这涉及到线程的切换和非批量化处理。

Actors模型相对来说是重量的对象,当需要服务一个用户请求时,Actors有初始化数量上的限制。

随着Actor增加,其代码容易变成意大利面条,搅拌在一起。

[该贴被banq于2011-12-28 10:37修改过]


猜你喜欢
2Go 1 2 下一页