词频统计

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. 装饰器修复技术@wraps

    @wrap修复技术 首先我先说一下wrap的效果 如果没使用@wraps,当A调用了装饰器B的话,即使A.name,返回的会是装饰器B的函数名称,而不是A的函数名称如果使用了@wraps,当A调用了装 ...

  2. unity shader 入门

    1.一个简单的顶点/片元着色器基本结构 Shader "Unity Shaders Book/Chapter 5/Simple Shader" { } SubShader { Pa ...

  3. HDU 6059

    题意略. 思路:我们要想令 A[i] ^ A[j] < A[j] ^ A[k](i < j < k),由于A[i]和A[k]都要 ^ A[j],所以我们只需研究一下i,k这两个数之间 ...

  4. Servlet 常用API学习(二)

    Servlet常用API学习 一.HTTP简介 WEB浏览器与WEB服务器之间的一问一答的交互过程必须遵循一定的规则,这个规则就是HTTP协议. HTTP是 hypertext transfer pr ...

  5. HashMap原理。图文并茂式解读。这些注意点你一定还不了解

    目录 概述 属性详解 table entrySet size modCount threshold.loadFactor 源码知识点必备 getGenericInterfaces和getInterfa ...

  6. 洛谷 P2055 【假期的宿舍】

    题库 :洛谷 题号 :2055 题目 :假期的宿舍 link :https://www.luogu.org/problem/P2055 首先明确一下:校内的每个学生都有一张床(只是校内的有) 思路 : ...

  7. CodeForces 340E Iahub and Permutations 错排dp

    Iahub and Permutations 题解: 令 cnt1 为可以没有限制位的填充数字个数. 令 cnt2 为有限制位的填充数字个数. 那么:对于cnt1来说, 他的值是cnt1! 然后我们对 ...

  8. 牛客小白月赛6 I 公交线路 最短路 模板题

    链接:https://www.nowcoder.com/acm/contest/136/I来源:牛客网 题目描述 P市有n个公交站,之间连接着m条道路.P市计划新开设一条公交线路,该线路从城市的东站( ...

  9. HDU5461 Largest Point 思维 2015沈阳icpc

    Largest Point Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  10. H5 的 sessionStorage和localStorage

    1) H5 新增的 sessionStorage 和 localStorage 的区别 sessionStorage 和 java 的 session 差不多,可以短时间存储信息,电脑浏览器常用ses ...