趣味集算:wordcount

WordCount
WordCount 差很少是最经常使用的分布式系统练习程序了,Hadoop 就常常用这个当例子。咱们来看用集算器怎么作 wordcount。程序员

先从单线程开始。

例如,D:\files\novel 目录中,有一些小说文档,如今,须要统计这些小说中哪些单词最为经常使用:服务器

wordcount-1

在集算器中,若是不嫌写得长,只要一句代码就能够搞定了:多线程

A
1 =directory@p(“D:/files/novel”).(file().read().words().groups(lower():Word;count(~):Count)).merge(Word).groups@o(Word;sum(Count):Count).sort@z(Count)

怎么样,是否是超级简单?计算后,A1 中获得的结果以下:分布式

wordcount-2

不过,这句确实有点长,为了便于理解,咱们能够把它拆成多步来执行:oop

A B C
1 =directory@p(“D:/files/novel”) [] =now()
2 for A1 =file(A2).read().words()
3 =B2.groups(lower():Word;count():Count)
4 >B1=B1 [B3]
5 =B1.merge(Word) =A5.groups@o(Word;sum(Count):Count).sort@z(Count) =interval@ms(C1,now())

在 A1 中,列出目录中的各个文件:性能

wordcount-3

第 2~4 行循环统计每一个文件中的单词。B2 中读取文件中的文本并拆分红单词:spa

wordcount-4

B3 中统计出当前文档中每一个单词出现的次数,统计时将单词转换为小写字母,以免大小写变化的影响。结果将按照单词的字典顺序排列:线程

wordcount-5

在每一个文档统计完成后,在 B4 中将结果记录到 B1 中,全部文档统计后,B1 中结果以下:进程

wordcount-6

在 A5 中,将这些结果按照每一个单词归并起来,结果以下:ip

wordcount-7

B5 中,将归并后的统计结果按每一个单词聚合计算,再将结果按 Count 降序排列,能够获得和前面单条语句时相同的结果:

wordcount-8

在 C1 和 C5 中,经过记录执行开始先后的时刻,估算出计算所需的毫秒数以下:

wordcount-9

可见,执行效率仍是很是高的。

搞完单线程,咱们再来试试多线程的搞法。

并行计算会不会麻烦不少啊?看看代码吧:

A B C
1 =directory@p(“D:/files/novel”) =now()
2 fork A1 =file(A2).read().words()
3 =B2.groups(lower(~):Word;count(~):Count)
4 =A2.merge(Word) =A4.groups@o(Word;sum(Count):Count).sort@z(Count) =interval@ms(C1,now())

嗯,好象差很少嘛,就是把 A2 的那个 for 换成了 fork,其它代码基本没什么变化。看看 C4 中的计时状况

wordcount-10

果真快了,并行真地起了做用(俺的笔记本只有双核,有这个性能提升也就差很少了)。

这个 fork 语句就会自动把原本单线程串行执行的 for 循环变成多线程并行循环计算,程序员彻底不用操心线程管理的事,是否是很简单?

搞完多线程,现来搞集群

懒得真搞多个服务器来,就用一台机器启动多个进程模拟一下吧。在集算器安装目录的 esProc\bin 路径下,能够找到 esprocs.exe 文件,能够直接运行它来启动或配置服务器:

wordcount-11

在首次用 Start 按键启动服务器以前,能够先点击 Config 配置并行服务器的相关信息,如在 Unit 页面中配置本机中所要启动的服务器 ip 及端口:

wordcount-12

配置完成后,就能够回到服务器主窗口启动服务器。重复执行 esprocs.exe 能够再启动两个服务器,这 3 个服务器将依次使用配置中设置的 ip 和端口。这样单机上的服务器集群就准备完毕了。

下面准备统计 4 个路径中全部文档的单词,因为这里使用单机模拟服务器集群的,因此每一个服务器都是共用相同路径的,若是是远程服务器,设定时路径可能也会有所差别。

A B C
1 [192.168.10.229:4001,192.168.10.229:4004,192.168.10.229:4007] [D:/files/novel1,D:/files/novel2, D:/files/novel3,D:/files/novel4]
2 fork B1;A1 =directory@p(A2)
3 fork B2 =file(B3).read().words()
4 =C3.groups(lower():Word;count():Count)
5 return B3.merge(Word)
6 =A2.merge(Word) =A6.groups@o(Word;sum(Count):Count).sort@z(Count)

在计算时,用 4 个文件路径做为参数,须要执行 4 个子任务分别计算某个路径中文件的单词数。只须要在 fork 后面加上各个服务器节点的地址,这些子任务就能够由集算器自动分派给服务器节点去计算并将结果汇总,程序员根本不用操心这些小问题。最后在 B6 中计算出结果以下:

wordcount-13

从各个服务器窗口中,能够看到集群计算任务的分配执行状况:

wordcount-14

wordcount-15

wordcount-16

怎么样?很简单吧,Hadoop 还没搭建起来的时间,咱已经把活干完了。