博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《hadoop进阶》基于hadoop和hive的微博热词跟踪系统
阅读量:6719 次
发布时间:2019-06-25

本文共 6344 字,大约阅读时间需要 21 分钟。

打开微信扫一扫,关注微信公众号【数据与算法联盟】

转载请注明出处: 
博主微博: 
Github:

代码下载地址:

--------------------------------------------------------------------------------------------------------------------------------------------------

写在前边的话

          这篇文章应该是有史以来写的时间最长的一篇文章,我记得是今年暑假之前开始的,后来因为种种原因吧(找工作,开始工作,电脑重装,换工作等等),导致现在才写完,算是一篇迟到了二个月的文章,实在是不好意思,曾经也想过不写了,但是后来还是坚持了下来,只想分享给大家

        整片博客分为这几个部分 :       

                 1:微博热词跟踪系统概述

                 2:需求分析

                 3:算法模型

                 4:设计

                 5:程序实现

                 6:结果可视化

        另外需要注意的是本文所有数据均为测试数据,只是为了验证代码的可用性和整个流程是否能够走通

一:微博热词跟踪系统概述

   

            微博是当今社会消息传播的主要途径,汇集了社会各层人士,能充分代表人们的呼声和社会发展的趋势,其具备了新闻的时效性和广泛性,那么对于微博内容,传播的分析在一定程度上能得到更大价值,比如看些图展示的是“老九门”这个此最近一个月出现的频率,即hot程度

          那么接下来我们将要实现的就是类似于上图这样的一个功能

二:需求分析

          现假设我们的数据源是这样的,一天的微博信息在一个文件夹下,每个小时内的微博内容在一个文件内,如图:

           最终我们要得到的数据要存入Hive数据库,处于方便我们这里选用分区表,以天和小时作为分区依据,表每行有四个字段,分别是day,hour,word,num(时间点精确到小时),类似于以下的,非真实数据(最后一列为分区字段):

                          

           表的 描述如下:

                          

三:算法模型

          采用的是hadoop作为计算模型,计算结果保存在hive数据库中,中间所有的任务作为串行流在mainJob中执行。

          当运行代码的时候,会提示输入你想查看的关键词走势:eg,佳能

                         

          然后运行程序,显示出折线图

四:架构设计

          整个代码函数的目录为:

                          

         mainJob作为主函数,首先调用JobWorker作为计算,在JobWorker中会调用hdfsGYT(这是我封装的一个java操作hdfs的库,感兴趣的朋友可以看下之前关于他的文章:),然后调用inHive函数将计算结果保存在hive中,最后调用lineCharts从hive数据仓库中读取数据,画出折线图

          PS:读到这里,许多朋友可能会想,你这样做岂不是太麻烦了,完全可以直接将计算结果传给LineCharts进行可视化,加了一个inHive岂不是多此一举,的确是那样,但是换一个角度想,本篇博客只是为了学习,搞明白这样的一个流程,而并不是这些代码就可以用在真实的生产环境中,所以,当我们抱着学习的态度去理解整个代码,我们对整个项目便有了清楚的了解。

五:程序实现

1:hadoop词频统计和过滤实现

        main函数:更多代码点击

package org.apache.mr.hotword;/** * Created by thinkgamer on 16-9-22. */import java.io.IOException;import java.net.URISyntaxException;import java.util.HashMap;import java.util.Map;public class mainJob {    public static final String  HDFS = "hdfs://127.0.0.1:9000";    // public static final Pattern DELIMITER = Pattern.compile("[\t,]");    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException, URISyntaxException {        // TODO Auto-generated constructor stub        Map
path = new HashMap
(); //创建一个Map对象 path.put("input", HDFS+"/file/weibo"); path.put("output", HDFS+"/file/weibo/output"); JobWorker.run(path); //针对输入的key_word进行统计 inHive.run(path); //调用inHive的run方法,将运行的结果写入hive表 LineCharts.run(); //将计算的结果以折线的形式画出 }}

2:创建hive表,并将数据导入

       创建表语句:

create table hot_world_table(     time int,     word string,     num int)comment 'this hot words table'Partitioned by (day string, hour string)row format delimited fields terminated by "\t";

       将数据导入数据库

#从本地加载load data local inpath "/home/thinkgamer/桌面/20160221-r-00000" into table hot_word_table partition(timeday='20160221');#从hdfs加载load data inpath "/mr/hot_word/output/20160221-r-00000" into table hot_word_table partition(timeday="20160221")

六:结果可视化

           可视化部分有LineCharts控制,主要利用的是java的jfreechart进行画图

package org.apache.mr.hotword;/** * Created by thinkgamer on 16-9-22. */import javax.swing.JPanel;import org.jfree.chart.ChartFactory;import org.jfree.chart.ChartPanel;import org.jfree.chart.JFreeChart;import org.jfree.chart.axis.NumberAxis;import org.jfree.chart.plot.CategoryPlot;import org.jfree.chart.plot.PlotOrientation;import org.jfree.data.category.DefaultCategoryDataset;import org.jfree.ui.ApplicationFrame;import org.jfree.ui.RefineryUtilities;import java.util.Map;import java.util.TreeMap;public class LineCharts extends ApplicationFrame {    public LineCharts(String s) {        super(s);        setContentPane(createDemoLine());    }    public static void run() {        LineCharts fjc = new LineCharts("热词走势图");        fjc.pack();        RefineryUtilities.centerFrameOnScreen(fjc);        fjc.setVisible(true);    }    // 生成显示图表的面板    public static JPanel createDemoLine() {        JFreeChart jfreechart = createChart(createDataset());        return new ChartPanel(jfreechart);    }    // 生成图表主对象JFreeChart    public static JFreeChart createChart(DefaultCategoryDataset linedataset) {        //定义图表对象        JFreeChart chart = ChartFactory.createLineChart("热词走势图", // chart title                "时间", // domain axis label                "数量", // range axis label                linedataset, // data                PlotOrientation.VERTICAL, // orientation                true, // include legend                true, // tooltips                false // urls        );        CategoryPlot plot = chart.getCategoryPlot();        // customise the range axis...        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());        rangeAxis.setAutoRangeIncludesZero(true);        rangeAxis.setUpperMargin(0.20);        rangeAxis.setLabelAngle(Math.PI / 2.0);        return chart;    }    //生成数据    public static DefaultCategoryDataset createDataset() {        //从Hive中读取数据        Map
map = new TreeMap
(); map = inHive.getResult(); for(int i=1;i<13;i++){ if(map.get(Integer.toString(i))==null){ map.put(Integer.toString(i),"0"); } } DefaultCategoryDataset linedataset = new DefaultCategoryDataset(); // 各曲线名称 String series1 = "热词"; // 横轴名称(列名称) String type1 = "1:00"; String type2 = "2:00"; String type3 = "3:00"; String type4 = "4:00"; String type5 = "5:00"; String type6 = "6:00"; String type7 = "7:00"; String type8 = "8:00"; String type9 = "9:00"; String type10 = "10:00"; String type11 = "11:00"; String type12 = "12:00"; linedataset.addValue(Integer.parseInt(map.get("1")), series1, type1); linedataset.addValue(Integer.parseInt(map.get("2")), series1, type2); linedataset.addValue(Integer.parseInt(map.get("3")), series1, type3); linedataset.addValue(Integer.parseInt(map.get("4")), series1, type4); linedataset.addValue(Integer.parseInt(map.get("5")), series1, type5); linedataset.addValue(Integer.parseInt(map.get("6")), series1, type6); linedataset.addValue(Integer.parseInt(map.get("7")), series1, type7); linedataset.addValue(Integer.parseInt(map.get("8")), series1, type8); linedataset.addValue(Integer.parseInt(map.get("9")), series1, type9); linedataset.addValue(Integer.parseInt(map.get("10")), series1, type10); linedataset.addValue(Integer.parseInt(map.get("11")), series1, type11); linedataset.addValue(Integer.parseInt(map.get("12")), series1, type12); return linedataset; }}

      结果是这样的:

你可能感兴趣的文章
洛谷P4151 [WC2011]最大XOR和路径(线性基)
查看>>
[bzoj 2456]mode
查看>>
jQuery页面元素操作之遍历元素
查看>>
CodeFile与CodeBehind的区别
查看>>
UOJ#428. 【集训队作业2018】普通的计数题
查看>>
[HNOI2015]菜肴制作
查看>>
使用百分比固定的table大小中td内容自动换行问题
查看>>
如何给系统升级
查看>>
《Red Dog》——流浪、阳光和那些让人缅怀的画面
查看>>
jquey动画效果
查看>>
计算 $s=1+(1+2)+(1+2+3)+\cdots+(1+2+3+\cdots+n)$
查看>>
《解析几何》吕林根,徐子道第四版 习题 1.4.7,1.4.8,1.4.9
查看>>
ruby Logger日志
查看>>
【应用】浮点数四则运算器 Part3:运算模块的编写
查看>>
puppet使用 apache passsenger 作为前端 (debian)
查看>>
IDA*
查看>>
双机调试和windbg的命令
查看>>
20155229《网络对抗技术》Exp8:Web基础
查看>>
MVC中用js写入的button按钮单击事件失效问题
查看>>
POJO与javabean的区别
查看>>