使用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 ...
随机推荐
- js中的数据类型,以及如何检测数据类型
基本数据类型:string,number,boolean,null,undefined,symbol 引用数据类型:object(array,function...) 常用的检测数据类型的方法一般有以 ...
- Java Server Page
Java Server Page 一.JSP起源 在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变. 如果使用Servlet程序来输出只有局部内容需要动态改变的网页,其中所 ...
- Condition控制线程通信
Condition控制线程通信 一.前言 java.util.concurrent.locks.Condition 接口描述了可能会与锁有关联的条件变量.这些变量在用法上与使用Object.wait ...
- Leetcode之广度优先搜索(BFS)专题-详解429. N叉树的层序遍历(N-ary Tree Level Order Traversal)
Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree Level Order Traversal) 给定一个 N 叉树,返回其节点值的层序遍历. (即从左到右 ...
- rocketmq 部署启动指南-Docker 版
最近学习使用 rocketmq,需要搭建 rocketmq 服务端,本文主要记录 rocketmq 搭建过程以及这个过程踩到的一些坑. 准备工作 在搭建之前,我们需要做一些准备工作,这里我们需要使用 ...
- office web apps server安装
1.准备服务器 准备一台windows server 2012 R2服务器,修改计算机名称加入域,如果是通过虚拟机复制导致sid冲突,可以先运行 c:\windows\system32\sysprep ...
- 2019 Multi-University Training Contest 3
B.Blow up the city solved by F0_0H 210min 题意 给一个DAG,每次询问给定u,v,求使得u或v不能与中心点联通的关键点个数 做法 按照拓扑序建树 新加节点的父 ...
- hdu 5969 最大的位或(贪心)
Problem Description B君和G君聊天的时候想到了如下的问题.给定自然数l和r ,选取2个整数x,y满足l <= x <= y <= r ,使得x|y最大.其中|表示 ...
- python实现去掉空行
# coding = utf-8def clearBlankLine(): file1 = open('text1.txt', 'r', encoding='utf-8') # 要去掉空行的文件 fi ...
- Kubernetes master无法加入etcd 集群解决方法
背景:一台master磁盘爆了导致k8s服务故障,重启之后死活kubelet起不来,于是老哥就想把它给reset掉重新join,接着出现如下报错提示是说etcd集群健康检查未通过: error exe ...