使用Storm进行词频统计
词频统计
1.需求:读取指定目录的数据,并且实现单词计数功能
2.实现方案:
Spout用于读取指定文件夹(目录),读取文件,将文件的每一行发射到Bolt
SplitBolt用于接收Spout发射过来的数据,并拆分,发射到CountBolt
CountBolt接收SplitBolt发送的每一个单词,进行单词计数操作
3.拓扑设计:
DataSourceSpout + SplitBolt + CountBolt
代码如下:
package com.csylh;
import org.apache.commons.io.FileUtils;
import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.topology.base.BaseRichSpout;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* Description:使用Storm完成词频统计功能
*
* @author: 留歌36
* Date:2018/9/4 9:28
*/
public class LocalWordCountStormTopology {
/**
* 读取数据并发送到Bolt上去
*/
public static class DataSourceSpout extends BaseRichSpout{
//定义一个发射器
private SpoutOutputCollector collector;
/**
* 初始化方法 只是会被调用一次
* @param conf 配置参数
* @param context 上下文
* @param collector 数据发射器
*/
@Override
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
//对上面定义的的发射器进行赋初值
this.collector = collector;
}
/**
* 用于数据的产生
* 业务:
* 1.读取指定目录的文件夹下的数据
* 2.把每一行数据发射出去
*/
@Override
public void nextTuple() {
// 获取所有文件,这里指定文件的后缀
Collection<File> files = FileUtils.listFiles(new File("E:\\StormText"),new String[]{"txt"},true);
// 循环遍历每一个文件 ==> 由于这里指定的是文件夹下面的目录 所以就是需要进行循环遍历
for( File file : files){
try {
// 获取每一个文件的每一行
List<String> lines = FileUtils.readLines(file);
for(String line : lines){
// 把每一行数据发射出去
this.collector.emit(new Values(line));
}
//TODO 数据处理完毕之后 改名 否则的话 会一直执行的
FileUtils.moveFile(file,new File(file.getAbsolutePath()+System.currentTimeMillis()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 声明输出字段名称
* @param declarer
*/
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("line"));
}
}
/**
* 对Spout发送过来的数据进行分割
*/
public static class SplitBolt extends BaseRichBolt{
private OutputCollector collector;
/**
* 初始化方法 只是会被执行一次
* @param stormConf
* @param context
* @param collector Bolt的发射器,指定下一个Bolt的地址
*/
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector;
}
/**
* 用于获取Spout发送过来的数据
* 业务逻辑
* spout发送过来的数据是一行一行的line
* 这里是需要line进行分割
*
* @param input
*/
@Override
public void execute(Tuple input) {
String line = input.getStringByField("line");
String[] words = line.split(",");
for(String word : words){
// 这里把每一个单词发射出去
this.collector.emit(new Values(word));
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
}
}
/**
* 词频汇总的Bolt
*/
public static class CountBolt extends BaseRichBolt{
/**
* 由于这里是不需要向外部发射 所以就不需要定义Collector
* @param stormConf
* @param context
* @param collector
*/
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
}
Map<String,Integer> map = new HashMap<String, Integer>();
/**
* 业务逻辑
* 1.获取每一个单词
* 2.对每一个单词进行汇总
* 3.输出结果
* @param input
*/
@Override
public void execute(Tuple input) {
// 获取每一个单词
String word = input.getStringByField("word");
Integer count = map.get(word);
if (count == null){
count = 0;
}
count++;
// 对单词进行汇总
map.put(word,count);
// 输出
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~");
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
for(Map.Entry<String,Integer> entry :entrySet){
System.out.println(entry);
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
}
}
/**
* 主函数
* @param args
*/
public static void main(String[] args) {
// 使用TopologyBuilder根据Spout和Bolt构建Topology
TopologyBuilder builder = new TopologyBuilder();
// 设置Bolt和Spout 设置Spout和Bolt的关联关系
builder.setSpout("DataSourceSpout",new DataSourceSpout());
builder.setBolt("SplitBolt",new SplitBolt()).shuffleGrouping("DataSourceSpout");
builder.setBolt("CountBolt",new CountBolt()).shuffleGrouping("SplitBolt");
// 创建一个本地的集群
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("LocalWordCountStormTopology",new Config(),builder.createTopology());
}
}
小结:开发Storm程序的步骤就是:
根据需求 设计实现方案 规划拓扑
一般是先写Spout数据产生器 发射数据到Bolt
接着,就是Bolt进行数据处理,如果有多个Bolt,非最后一个Bolt也要写发射器Collector
最后一个Bolt直接输出结果或者 输出到HDFS或者关系型数据库中
最终需要将Spout和Bolt进行组装起来(借助TopologyBuilder)
使用Storm进行词频统计的更多相关文章
- Storm- 使用Storm实现词频汇总
需求:读取指定目录的数据,并实现单词计数的功能 实现方案: Spout来读取指定目录的数据,作为后续Bolt处理的input 使用一个Bolt把input 的数据,切割分开,我们按照逗号进分割 使用一 ...
- 使用storm分别进行计数和词频统计
计数 直接上代码 public class LocalStormSumTopology { public static void main(String[] agrs) { //Topology是通过 ...
- python瓦登尔湖词频统计
#瓦登尔湖词频统计: import string path = 'D:/python3/Walden.txt' with open(path,'r',encoding= 'utf-8') as tex ...
- 作业3-个人项目<词频统计>
上了一天的课,现在终于可以静下来更新我的博客了. 越来越发现,写博客是一种享受.来看看这次小林老师的“作战任务”. 词频统计 单词: 包含有4个或4个以上的字 ...
- C语言实现词频统计——第二版
原需求 1.读取文件,文件内包可含英文字符,及常见标点,空格级换行符. 2.统计英文单词在本文件的出现次数 3.将统计结果排序 4.显示排序结果 新需求: 1.小文件输入. 为表明程序能跑 2.支持命 ...
- c语言实现词频统计
需求: 1.设计一个词频统计软件,统计给定英文文章的单词频率. 2.文章中包含的标点不计入统计. 3.将统计结果以从大到小的排序方式输出. 设计: 1.因为是跨专业0.0···并不会c++和java, ...
- 软件工程第一次个人项目——词频统计by11061153柴泽华
一.预计工程设计时间 明确要求: 15min: 查阅资料: 1h: 学习C++基础知识与特性: 4-5h: 主函数编写及输入输出部分: 0.5h: 文件的遍历: 1h: 编写两种模式的词频统计函数: ...
- Hadoop上的中文分词与词频统计实践 (有待学习 http://www.cnblogs.com/jiejue/archive/2012/12/16/2820788.html)
解决问题的方案 Hadoop上的中文分词与词频统计实践 首先来推荐相关材料:http://xiaoxia.org/2011/12/18/map-reduce-program-of-rmm-word-c ...
- pyspark进行词频统计并返回topN
Part I:词频统计并返回topN 统计的文本数据: what do you do how do you do how do you do how are you from operator imp ...
随机推荐
- 玩转 SpringBoot 2 快速搭建 | Spring Tool Suite篇
Spring Tool Suite (STS) 工具介绍 我个人比较推荐使用 Spring Tool Suite(STS),之所以推荐使用 Spring Tool Suite(STS) ,是因为它是 ...
- RabbitMQ消息丢失问题和保证消息可靠性-消费端不丢消息和HA(二)
继续上篇文章解决RabbitMQ消息丢失问题和保证消息可靠性(一) 未完成部分,我们聊聊MQ Server端的高可用和消费端如何保证消息不丢的问题? 回归上篇的内容,我们知道消息从生产端到服务端,为了 ...
- java web基础 js、JSP、servlet之间的传递
@ JS 与 JSP :JSP无法直接获取JS的值,只能通过隐藏表单或者dom节点设置. JSP中设置隐藏表单input,或者设置任意一个隐藏或者不隐藏的节点比如div, 而JS就通过document ...
- Spring依赖注入浅析
1. 概念理解 依赖注入 谁注入谁? 依赖对象注入IoC容器. 控制反转 谁控制谁?控制什么? IoC容器控制对象,控制依赖对象的创建与注入. 为什么称为反转?创建.注入对象的控制权由程序员的主观意愿 ...
- ModelAndViewContainer、ModelMap、Model详细介绍【享学Spring MVC】
每篇一句 一个开源的技术产品做得好不好,主要是看你能解决多少非功能性问题(因为功能性问题是所有产品都能够想到的) 前言 写这篇文章非我本意,因为我觉得对如题的这个几个类的了解还是比较基础且简单的一块内 ...
- 迁移桌面程序到MS Store(10)——在Windows S Mode运行
首先简单介绍Windows 10 S Mode,Windows在该模式下,只能跑MS Store里的软件,不能通过其他方式安装.好处是安全有保障,杜绝一切国产流氓软件.就像iOS一样,APP进商店都需 ...
- 关于C语言\b \t \n及转义序列的理解
转义序列 说明 \b 后退一格(Backspace) \t 水平制表(Tab=4个空格) \v 垂直制表 \r 回车(Enter) \f 换页 \a 发出鸣响 \n 换行 \" 输出/输入双 ...
- SQL数据同步到ELK(二)- Elastic Search 安装
开篇废话 没错,前面扯了一堆SQL SERVER,其实我连Elastic Search根本没动手玩过(是不是与时代有点脱节了?),那今天我就准备尝试安装一个ELK的简单集群出来(这个集群是使用我的小米 ...
- Python 单元测试框架系列:聊聊 Python 的单元测试框架(一):unittest
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- SpringMVC的工作原理图
SpringMVC的工作原理图: SpringMVC流程 1. 用户发送请求至前端控制器DispatcherServlet. 2. DispatcherServlet收到请求调用HandlerMa ...