第90讲:基于Scala的Actor之上的分布式并发消息驱动框架Akka初体验

akka在业界使用非常广泛

spark背后就是由akka驱动的

要写消息驱动的编程模型都首推akka

下面将用30讲讲解akka

本讲主要讲两部分内容:

1.akka的重大意义

2.akka与scala的actor

Spark源码中使用akka使用鉴赏:

在spark中有200行左右代码封装了akka的使用

spark是分布式的计算框架,有master和slave主从节点通信时都是使用akka。

客户端提交程序时也是使用akka。所以如果要掌握spark必须要理解和掌握akka。

第91讲:Akka第一个案例动手实战架构设计

The quick brown fox tried to jump over the lazy dog and fell on the dog
A dog is a man's best friend

Map Task -> Reduce Task --|
                                            |-> Aggregate Task
Map Task -> Reduce Task --|

Master Actor
|
--------------------|---------------------
|                              |                    |
Map Actor Reduce Actor Aggregate Actor

Master Actor给MapActor发一个字符串
Map Actor根据规则对单词计数,计数完成后把结果传递给MasterActor
MasterActor把MapData以消息发给reduceActor,
reduceActor会reduceByKey,把相同单词(key相同)计数相加。
计算完后再把数据传回给MasterActor。
如果有多条字符串就会有多组reduce结果。
MasterActor再把结果发给AggregateActor,进行最后统计
MasterActor要获得结果需要给AggregateActor发一个空消息,
AggregateActor收到消息就会把所有统计结果发给MasterActor
这就是mapReduce计算模型。
与hadoop的mapreduce不同的是这是基于actor的。
MapActor对map产生的结果进行本地化统计,
AggregateActor才相当于hadoop的reducer。
后面先通过java使用akka。

第92讲:Akka第一个案例动手实战开发环境的搭建

第93讲:Akka第一个案例动手实战开发消息实体类

MapData:

package akka.dt.app.java.messages;

import java.util.List;

/**
* sunrunzhi
* 2018/11/12 9:46
* 用来让MapActor处理数据后存储在MapData实体中
* 然后方便将结果交给ReduceActor
*/
public class MapData {
private List<WordCount> dataList;
public List<WordCount> getDataList(){return dataList;}
public MapData(List<WordCount> dataList){
this.dataList=dataList;
} }

ReduceData:

package akka.dt.app.java.messages;

import java.util.HashMap;

/**
* sunrunzhi
* 2018/11/12 13:35
*/
public class ReduceData {
private HashMap<String,Integer> reduceDataList;
public HashMap<String,Integer> getReduceDataList(){
return reduceDataList;
}
public ReduceData(HashMap<String,Integer> reduceDataList){
this.reduceDataList=reduceDataList;
}
}

Result:

package akka.dt.app.java.messages;

/**
* sunrunzhi
* 2018/11/12 9:58
*/
public class Result {
/*传入的字符串先交给MapActor进行切分,然后交给ReduceActor进行本地统计,
最后交给AggregateActor进行全局的统计,
想要获得这个结果,通过MasterActor发一个消息Result,Result本身为空,不需要有任何内容。
这个消息交给MasterActor,MasterActor收到消息时,如果消息是result类型的话转过来会告诉AggregateActor,
再转发给AggregateActor。*/
}

WordCount:

package akka.dt.app.java.messages;

/**
* sunrunzhi
* 2018/11/12 9:52
* WordCount-javaBean
*/
public class WordCount {
private String word;
private Integer count;
public WordCount(String inWord,Integer inCount){
word=inWord;
count=inCount;
} public String getWord(){return word;}
public Integer getCount(){return count;} }

HelloAkka:

package akka.dt.app.java.messages;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.dt.app.java.actors.MasterActor; /**
* sunrunzhi
* 2018/11/9 20:14
*/
public class HelloAkka { public static void main(String[] args)throws Exception{
ActorSystem _system=ActorSystem.create("HelloAkka");
ActorRef master=_system.actorOf(new Props(MasterActor.class),"master");
master.tell("Hi,My name is Rocky. I'm so so so so happy to me here.");
master.tell("Today,I'm going to read a news article for so you.");
master.tell("I hope I hope you'll like it."); Thread.sleep(500);
master.tell(new Result());
Thread.sleep(500);
_system.shutdown(); }
}

第94讲:Akka第一个案例动手实战MapActor、ReduceActor、AggregateActor代码详解

AggregateActor:

package akka.dt.app.java.actors;

import akka.actor.UntypedActor;
import akka.dt.app.java.messages.ReduceData;
import akka.dt.app.java.messages.Result; import java.util.HashMap;
import java.util.Map; /**
* sunrunzhi
* 2018/11/9 20:18
*/
public class AggregateActor extends UntypedActor{
private Map<String,Integer> finalReducedMap=new HashMap<String, Integer>();
@Override
public void onReceive(Object message)throws Exception{
//AggregateActor收到消息有两种,一种是ReduceData类型,一种是Result类型
if(message instanceof ReduceData){
ReduceData reduceData=(ReduceData)message;
aggregateInMemoryReduce(reduceData.getReduceDataList());
}else if(message instanceof Result){
System.out.println(finalReducedMap.toString());
}else{
unhandled(message);
}
} private void aggregateInMemoryReduce(Map<String,Integer> reduceList){
Integer count=null;
for (String key:reduceList.keySet()){
if(finalReducedMap.containsKey(key)){
count=reduceList.get(key)+finalReducedMap.get(key);
finalReducedMap.put(key,count);
}else{
finalReducedMap.put(key,reduceList.get(key));
}
}
} }

MapActor:

package akka.dt.app.java.actors;

import akka.actor.ActorRef;
import akka.actor.UntypedActor;
import akka.dt.app.java.messages.MapData;
import akka.dt.app.java.messages.WordCount; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer; /**
* sunrunzhi
* 2018/11/9 20:17
*/
public class MapActor extends UntypedActor {
String[] STOP_WORDS = {"a", "is"};
private ActorRef reduceActor = null;
private List<String> STOP_WORDS_LIST = Arrays.asList(STOP_WORDS); public MapActor(ActorRef inReduceActor) {
reduceActor = inReduceActor;
} @Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
String work = (String) message;
//map the words in the sentence
MapData data = evaluateExpression(work);//产生MapData实体
// send the result to ReduceActor
reduceActor.tell(data);
} else {
unhandled(message);
}
} private MapData evaluateExpression(String line) {
List<WordCount> dataList = new ArrayList<WordCount>();
StringTokenizer parser = new StringTokenizer(line);
while (parser.hasMoreTokens()){
String word =parser.nextToken().toLowerCase();
if (!STOP_WORDS_LIST.contains(word)) {
dataList.add(new WordCount(word, Integer.valueOf(1)));
}
}
return new MapData(dataList);
}
}

  

ReduceActor:

package akka.dt.app.java.actors;

import akka.actor.ActorRef;
import akka.actor.UntypedActor;
import akka.dt.app.java.messages.MapData;
import akka.dt.app.java.messages.ReduceData;
import akka.dt.app.java.messages.WordCount;
import com.sun.javafx.collections.MappingChange; import java.util.HashMap;
import java.util.List; /**
* sunrunzhi
* 2018/11/9 20:17
*/
public class ReduceActor extends UntypedActor{
private ActorRef aggregateActor =null;
public ReduceActor(ActorRef inAggregateActor) {
aggregateActor=inAggregateActor;
} @Override
public void onReceive(Object message) throws Exception{
//AggregateActor收到的消息有两种,一种是ReduceData类型,一种是Result类型
if(message instanceof MapData){
MapData mapData =(MapData)message;
//reduce the incoming data
ReduceData reduceData=reduce(mapData.getDataList());
//forward the result to aggregate actor
aggregateActor.tell(reduceData);
}else {
unhandled(message);
}
} private ReduceData reduce(List<WordCount> dataList){
HashMap<String,Integer> reducedMap=new HashMap<String, Integer>();
for(WordCount wordCount:dataList){
if(reducedMap.containsKey(wordCount.getWord())){
Integer value=(Integer)reducedMap.get(wordCount.getWord());
value++;
reducedMap.put(wordCount.getWord(),value);
}else{
reducedMap.put(wordCount.getWord(),Integer.valueOf(1));
}
}
return new ReduceData(reducedMap);
}
}
MasterActor:
package akka.dt.app.java.actors;

import akka.actor.*;
import akka.dt.app.java.messages.Result; import java.util.Arrays;
import java.util.List; /**
* sunrunzhi
* 2018/11/9 20:18
*/
public class MasterActor extends UntypedActor {
private ActorRef aggregaterActor = getContext().actorOf(
new Props(AggregateActor.class), "aggregate"); private ActorRef reduceActor=getContext().actorOf(
new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new ReduceActor(aggregaterActor);
}
}),"reduce"); private ActorRef mapActor=getContext().actorOf(
new Props(new UntypedActorFactory(){
public UntypedActor create(){
return new MapActor(reduceActor);
}
}),"map"); @Override
public void onReceive(Object message) throws Exception{
if (message instanceof String) {
mapActor.tell(message);
} else if (message instanceof Result) {
aggregaterActor.tell(message);
} else{
unhandled(message);
}
} }

第95讲:Akka第一个案例动手实战MasterActor代码详解 

第96讲:Akka第一个案例动手实战main方法实现中ActorSystem等代码详解

第97讲:使用SBT开发Akka第一个案例环境搭建详解

SBT import失败:

一步一个坑。凑人~~~

之前调整的项目有报莫名其妙的BUG。

第一个BUG。

解决方案:标识红色处打上对号。

 总有些奇奇怪怪的BUG,莫名其妙的又没有了........

第98讲:使用SBT开发时动手解决rt.jar中CharSequence is broken等问题

第99讲:手动Artifacts打包并运行SBT开发Akka第一个案例

第100讲:使用SBT开发Akka第一个案例源码解析消息、main入口、MasterActor

第101讲:使用SBT开发Akka第一个案例源码解析MapActor、ReduceActor、AggregateActor

Scala零基础教学【90-101】Akka 实战-代码实现的更多相关文章

  1. Scala零基础教学【1-20】

    基于王家林老师的Spark教程——共计111讲的<Scala零基础教学> 计划在9月24日内完成(中秋节假期之内) 目前18号初步学习到25讲,平均每天大约完成15讲,望各位监督. 初步计 ...

  2. Scala零基础教学【102-111】Akka 实战-深入解析

    第102讲:通过案例解析Akka中的Actor运行机制以及Actor的生命周期 Actor是构建akka程序的核心基石,akka中actor提供了构建可伸缩的,容错的,分布式的应用程序的基本抽象, a ...

  3. Scala零基础教学【81-89】

    第81讲:Scala中List的构造是的类型约束逆变.协变.下界详解 首先复习四个概念——协变.逆变.上界.下界 对于一个带类型参数的类型,比如 List[T]: 如果对A及其子类型B,满足 List ...

  4. Scala零基础教学【61-80】

    第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析 第62讲:Scala中上下文界定内幕中的隐式参数与隐式参数的实战详解及其在Spark中的应用源码解析 /** ...

  5. Scala零基础教学【41-60】

    第41讲:List继承体系实现内幕和方法操作源码揭秘 def main(args: Array[String]) { /** * List继承体系实现内幕和方法操作源码揭秘 * * List本身是一个 ...

  6. Scala零基础教学【21-40】

    第24讲:Scala中SAM转换实战详解 SAM:single abstract method 单个抽象方法   我们想传入一个函数来指明另一个函数具体化的工作细节,但是重复的样板代码很多. 我们不关 ...

  7. [转]小D课堂 - 零基础入门SpringBoot2.X到实战_汇总

    原文地址:https://www.cnblogs.com/wangjunwei/p/11392825.html 第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBo ...

  8. 小D课堂 - 零基础入门SpringBoot2.X到实战_汇总

    第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBoot2.X到实战_第1节零基础快速入门SpringBoot2.0_1.SpringBoot2.x课程介绍和高手系 ...

  9. [易学易懂系列|rustlang语言|零基础|快速入门|(16)|代码组织与模块化]

    [易学易懂系列|rustlang语言|零基础|快速入门|(16)|代码组织与模块化] 实用知识 代码组织与模块化 我们知道,在现代软件开发的过程中,代码组织和模块化是应对复杂性的一种方式. 今天我们来 ...

随机推荐

  1. 团队代码中Bug太多怎么办?怎样稳步提高团队的代码质量

    最近负责的Android APP项目,由于团队成员变动.界面改版导致代码大幅修改等原因,产品发布后屡屡出现BUG导致的程序崩溃. 经过对异常统计和代码走读,BUG主要集中在空指针引起的NullPoin ...

  2. rsync安装使用详解

    rsync是类unix系统下的数据镜像备份工具,从软件的命名上就可以看出来了——remote sync.它的特性如下: 可以镜像保存整个目录树和文件系统. 可以很容易做到保持原来文件的权限.时间.软硬 ...

  3. CSS样式实现溢出超出DIV边框宽度高度的内容自动隐藏方法

    CSS样式实现溢出超出DIV边框宽度高度的内容自动隐藏方法 平时我们布局时候,有的文字内容多了会超过溢出我们限制的高度,有的图片会撑破DIV,让网页错位变乱. 这样我们就需要解决如何使用CSS来超出设 ...

  4. 转:极小极大搜索方法、负值最大算法和Alpha-Beta搜索方法

    转自:极小极大搜索方法.负值最大算法和Alpha-Beta搜索方法 1. 极小极大搜索方法    一般应用在博弈搜索中,比如:围棋,五子棋,象棋等.结果有三种可能:胜利.失败和平局.暴力搜索,如果想通 ...

  5. 【BZOJ2253】纸箱堆叠 [CDQ分治]

    纸箱堆叠 Time Limit: 30 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description P 工厂是一个生产纸箱的工厂. 纸 ...

  6. 汕头市队赛 C KMP codeforces B. Image Preview

    汕头市队赛题目传送门 codeforces题目传送门 这道题我的做法是 尝试先往左走然后往右走 或者先往右走然后往左走 然后注意一下枚举顺序就okay啦 #include<cstdio> ...

  7. Linux curl命令【curl】

    命令:curl 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具 ...

  8. MySQL 之 foreign key

    前段回顾 create table 表名( 字段名1 类型[(宽度) 约束条件], 字段名2 类型[(宽度) 约束条件], 字段名3 类型[(宽度) 约束条件] ); #解释: 类型:使用限制字段必须 ...

  9. measure time program

    #include <time.h> int delay(int time) { int i,j; for(i =0;i<time;i++) for(j=0;j<10000;j+ ...

  10. 表单文件上传,ajax文件上传

    原创链接:http://www.cnblogs.com/yanqin/p/5345562.html html代码  index.jsp(表单文件上传) <form action="sh ...