词频统计

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进行词频统计的更多相关文章

  1. Storm- 使用Storm实现词频汇总

    需求:读取指定目录的数据,并实现单词计数的功能 实现方案: Spout来读取指定目录的数据,作为后续Bolt处理的input 使用一个Bolt把input 的数据,切割分开,我们按照逗号进分割 使用一 ...

  2. 使用storm分别进行计数和词频统计

    计数 直接上代码 public class LocalStormSumTopology { public static void main(String[] agrs) { //Topology是通过 ...

  3. python瓦登尔湖词频统计

    #瓦登尔湖词频统计: import string path = 'D:/python3/Walden.txt' with open(path,'r',encoding= 'utf-8') as tex ...

  4. 作业3-个人项目<词频统计>

    上了一天的课,现在终于可以静下来更新我的博客了.       越来越发现,写博客是一种享受.来看看这次小林老师的“作战任务”.                词频统计 单词: 包含有4个或4个以上的字 ...

  5. C语言实现词频统计——第二版

    原需求 1.读取文件,文件内包可含英文字符,及常见标点,空格级换行符. 2.统计英文单词在本文件的出现次数 3.将统计结果排序 4.显示排序结果 新需求: 1.小文件输入. 为表明程序能跑 2.支持命 ...

  6. c语言实现词频统计

    需求: 1.设计一个词频统计软件,统计给定英文文章的单词频率. 2.文章中包含的标点不计入统计. 3.将统计结果以从大到小的排序方式输出. 设计: 1.因为是跨专业0.0···并不会c++和java, ...

  7. 软件工程第一次个人项目——词频统计by11061153柴泽华

    一.预计工程设计时间 明确要求: 15min: 查阅资料: 1h: 学习C++基础知识与特性: 4-5h: 主函数编写及输入输出部分: 0.5h: 文件的遍历: 1h: 编写两种模式的词频统计函数: ...

  8. 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 ...

  9. pyspark进行词频统计并返回topN

    Part I:词频统计并返回topN 统计的文本数据: what do you do how do you do how do you do how are you from operator imp ...

随机推荐

  1. vscode 代码补全工具之aiXcoder

    突然发现了一个好用的代码补全工具,与人工智能相关,具有自学习能力,据说用的越久补全效果越好,可以帮助我们节省掉好多敲代码的时间,所以这么好的工具当然要分享给大家了.废话不多说,直接上vscode的安装 ...

  2. Java虚拟机详解(八)------虚拟机监控和分析工具(2)——可视化

    上篇博客我们介绍了虚拟机监控和分析命令行工具,由于其不够直观,不是很容易排查问题,那么本篇博客我们就来介绍几个可视化工具. 1.JConsole JConsole(Java Monitoring an ...

  3. Leetcode之回溯法专题-39. 组合总数(Combination Sum)

    Leetcode之回溯法专题-39. 组合总数(Combination Sum) 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使 ...

  4. fiddler的安装于使用(一)安装fiddler

    Fiddler的简介 Fiddler是位于客户端和服务器端之间的代理,也是目前最常用的抓包工具之一 .它能够记录客户端和服务器之间的所有 请求,可以针对特定的请求,分析请求数据.设置断点.调试web应 ...

  5. 共价大爷游长沙 lct 维护子树信息

    这个题目的关键就是判断 大爷所有可能会走的路 会不会经过询问的边. 某一条路径经过其中的一条边, 那么2个端点是在这条边的2测的. 现在我们要判断所有的路径是不是都经过 u -> v 我们以u为 ...

  6. 【转】Android CTS 测试

    http://blog.csdn.net/zxm317122667/article/details/8508013 Android-CTS 4.0.3测试基本配置 1. Download CTS CT ...

  7. zabbix监控PHP脚本

    scripts]# cat php_fpm_status.sh #!/bin/bash ############################################ #$name: ngi ...

  8. 使用Nginx实现负载均衡(tomcat集群之后实现交叉访问)

    tomcat集群(多一台服务器),使用nginx实现负载均衡(upstream sina中配置即可):使用上次博客中的sina案例 1.首先再加一个tomcat服务: 2.修改server.xml配置 ...

  9. [淘宝客技术篇008](无需登录)淘宝天猫优惠券JSON接口1

    今天,小星给大家分享的是一个非常重要,非常有意义的接口:获取淘宝天猫优惠券的JSON接口. 先上个链接: http://uland.taobao.com/cp/coupon_list?pid=mm_2 ...

  10. 内部类实例化Serializable

    昨天在做一个java项目的时候,发现下面代码中红色字体那行总是报NotSerializableException,查错误,MyRectangle这个类也明明实现了Serializable接口. 花了大 ...