Storm之——Storm+Kafka+Flume+Zookeeper+MySQL实现数据实时分析(程序案例篇)

改文章为转载,出处为http://blog.csdn.net/l1028386804/article/details/79441007,本文已按照作者要求转载







转载请注明出处:http://blog.csdn.net/l1028386804/article/details/79441007

一、前言

本博文是基于《Storm之——Storm+Kafka+Flume+Zookeeper+MySQL实现数据实时分析(环境搭建篇)》,请先阅读《Storm之——Storm+Kafka+Flume+Zookeeper+MySQL实现数据实时分析(环境搭建篇)

首先我们启动服务器上的Storm、Kafka、Flume、Zookeeper和MySQL,具体参见博文《Storm之——Storm+Kafka+Flume+Zookeeper+MySQL实现数据实时分析(环境搭建篇)》。

二、简单介绍

为了方便,这里我们只是简单的向/home/flume/log.log中追加单词,每行一个单词,利用Storm接收每个单词,将单词计数更新到数据库,具体的逻辑为,如果数据库中没有相关单词,则将数据插入数据库,如果存在相关单词,则更新数据库中的计数。具体SQL逻辑参见博文《MySQL之——实现无数据插入,有数据更新

三、程序实现

1、创建项目

创建Maven项目结构如下:


2、配置pom.xml

    
    
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <modelVersion>4.0.0 </modelVersion>
  3. <groupId>com.lyz </groupId>
  4. <artifactId>storm-kafka-mysql </artifactId>
  5. <version>1.0-SNAPSHOT </version>
  6. <dependencies>
  7. <dependency>
  8. <groupId>org.apache.storm </groupId>
  9. <artifactId>storm-core </artifactId>
  10. <version>1.1.0 </version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.apache.storm </groupId>
  14. <artifactId>storm-kafka </artifactId>
  15. <version>1.1.0 </version>
  16. </dependency>
  17. <dependency>
  18. <groupId>redis.clients </groupId>
  19. <artifactId>jedis </artifactId>
  20. <version>2.7.3 </version>
  21. </dependency>
  22. <dependency>
  23. <groupId>mysql </groupId>
  24. <artifactId>mysql-connector-java </artifactId>
  25. <version>5.1.28 </version>
  26. </dependency>
  27. <dependency>
  28. <groupId>c3p0 </groupId>
  29. <artifactId>c3p0 </artifactId>
  30. <version>0.9.1.2 </version>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.apache.kafka </groupId>
  34. <artifactId>kafka_2.12 </artifactId>
  35. <version>1.0.0 </version>
  36. <exclusions>
  37. <exclusion>
  38. <groupId>org.apache.zookeeper </groupId>
  39. <artifactId>zookeeper </artifactId>
  40. </exclusion>
  41. <exclusion>
  42. <groupId>log4j </groupId>
  43. <artifactId>log4j </artifactId>
  44. </exclusion>
  45. <exclusion>
  46. <groupId>org.slf4j </groupId>
  47. <artifactId>slf4j-log4j12 </artifactId>
  48. </exclusion>
  49. </exclusions>
  50. </dependency>
  51. <dependency>
  52. <groupId>org.apache.kafka </groupId>
  53. <artifactId>kafka-clients </artifactId>
  54. <version>1.0.0 </version>
  55. </dependency>
  56. </dependencies>
  57. <build>
  58. <plugins>
  59. <plugin>
  60. <artifactId>maven-assembly-plugin </artifactId>
  61. <configuration>
  62. <descriptorRefs>
  63. <descriptorRef>jar-with-dependencies </descriptorRef>
  64. </descriptorRefs>
  65. <archive>
  66. <manifest>
  67. <!--告诉运行的主类是哪个,注意根据自己的情况,下面的包名做相应的修改-->
  68. <mainClass>com.lyz.storm.StormTopologyDriver </mainClass>
  69. </manifest>
  70. </archive>
  71. </configuration>
  72. <executions>
  73. <execution>
  74. <id>make-assembly </id>
  75. <phase>package </phase>
  76. <goals>
  77. <goal>single </goal>
  78. </goals>
  79. </execution>
  80. </executions>
  81. </plugin>
  82. <plugin>
  83. <groupId>org.apache.maven.plugins </groupId>
  84. <artifactId>maven-compiler-plugin </artifactId>
  85. <configuration>
  86. <source>1.8 </source>
  87. <target>1.8 </target>
  88. </configuration>
  89. </plugin>
  90. </plugins>
  91. </build>
  92. </project>
3、实现单词分割计数的MySplitBolt类

    
    
  1. package com.lyz.storm.bolt;
  2. import org.apache.storm.topology.BasicOutputCollector;
  3. import org.apache.storm.topology.OutputFieldsDeclarer;
  4. import org.apache.storm.topology.base.BaseBasicBolt;
  5. import org.apache.storm.tuple.Fields;
  6. import org.apache.storm.tuple.Tuple;
  7. import org.apache.storm.tuple.Values;
  8. /
  9. * 这个Bolt模拟从kafkaSpout接收数据,并把数据信息发送给MyWordCountAndPrintBolt的过程。
  10. * @author liuyazhuang
  11. /
  12. public class MySplitBolt extends BaseBasicBolt {
  13. private static final long serialVersionUID = 4482101012916443908L;
  14. @Override
  15. public void execute(Tuple input, BasicOutputCollector collector) {
  16. //1、数据如何获取
  17. //如果StormTopologyDriver中的spout配置的是MyLocalFileSpout,则用的是declareOutputFields中的juzi这个key
  18. //byte[] juzi = (byte[]) input.getValueByField("juzi");
  19. //2、这里用这个是因为StormTopologyDriver这个里面的spout用的是KafkaSpout,而KafkaSpout中的declareOutputFields返回的是bytes,所以下面用bytes,这个地方主要模拟的是从kafka中获取数据
  20. byte[] juzi = ( byte[]) input.getValueByField( "bytes");
  21. //2、进行切割
  22. String[] strings = new String(juzi).split( " ");
  23. //3、发送数据
  24. for (String word : strings) {
  25. //Values对象帮我们生成一个list
  26. collector.emit( new Values(word, 1));
  27. }
  28. }
  29. @Override
  30. public void declareOutputFields(OutputFieldsDeclarer declarer) {
  31. declarer.declare( new Fields( "word", "num"));
  32. }
  33. }
4、实现入库操作的MyWordCountAndPrintBolt类

    
    
  1. package com.lyz.storm.bolt;
  2. import java.sql.Connection;
  3. import java.sql.SQLException;
  4. import java.sql.Statement;
  5. import java.util.Map;
  6. import org.apache.storm.task.TopologyContext;
  7. import org.apache.storm.topology.BasicOutputCollector;
  8. import org.apache.storm.topology.OutputFieldsDeclarer;
  9. import org.apache.storm.topology.base.BaseBasicBolt;
  10. import org.apache.storm.tuple.Tuple;
  11. import com.lyz.storm.db.DBProvider;
  12. /
  13. * 用于统计分析,并且把统计分析的结果存储到mysql中。
  14. * @author liuyazhuang
  15. /
  16. public class MyWordCountAndPrintBolt extends BaseBasicBolt {
  17. private static final long serialVersionUID = 5564341843792874197L;
  18. private DBProvider provider;
  19. @Override
  20. public void prepare(Map stormConf, TopologyContext context) {
  21. //连接redis---代表可以连接任何事物
  22. provider = new DBProvider();
  23. super.prepare(stormConf,context);
  24. }
  25. @Override
  26. public void execute(Tuple input, BasicOutputCollector collector) {
  27. String word = (String) input.getValueByField( "word");
  28. Integer num = (Integer) input.getValueByField( "num");
  29. Connection conn = null;
  30. Statement stmt = null;
  31. try {
  32. conn = provider.getConnection();
  33. stmt = conn.createStatement() ;
  34. stmt.executeUpdate( "INSERT INTO word_count (word, count) VALUES ('" + word + "', " + num + ") ON DUPLICATE KEY UPDATE count = count + " + num) ;
  35. } catch (SQLException e) {
  36. e.printStackTrace();
  37. } finally{
  38. if(stmt != null){
  39. try {
  40. stmt.close();
  41. stmt = null;
  42. } catch (Exception e2) {
  43. e2.printStackTrace();
  44. }
  45. }
  46. if(conn != null){
  47. try {
  48. conn.close();
  49. conn = null;
  50. } catch (Exception e2) {
  51. e2.printStackTrace();
  52. }
  53. }
  54. }
  55. }
  56. @Override
  57. public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
  58. //todo 不需要定义输出的字段
  59. }
  60. }
5、实现操作数据库的DBProvider类

    
    
  1. package com.lyz.storm.db;
  2. import java.beans.PropertyVetoException;
  3. import java.sql.Connection;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import com.mchange.v2.c3p0.ComboPooledDataSource;
  8. /
  9. * JDBC操作数据库
  10. * @author liuyazhuang
  11. /
  12. public class DBProvider {
  13. private static ComboPooledDataSource source ;
  14. private static final String DB_DRIVER = "com.mysql.jdbc.Driver";
  15. private static final String DB_URL = "jdbc:mysql://127.0.0.1:3306/sharding_0?useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true";
  16. private static final String USER = "root";
  17. private static final String PASSWORD = "root";
  18. private static Connection connection;
  19. static{
  20. try {
  21. source = new ComboPooledDataSource();
  22. source.setDriverClass(DB_DRIVER);
  23. source.setJdbcUrl(DB_URL);
  24. source.setUser(USER);
  25. source.setPassword(PASSWORD);
  26. source.setInitialPoolSize( 10);
  27. source.setMaxPoolSize( 20);
  28. source.setMinPoolSize( 5);
  29. source.setAcquireIncrement( 1);
  30. source.setMaxIdleTime( 3);
  31. source.setMaxStatements( 3000);
  32. source.setCheckoutTimeout( 2000);
  33. } catch (PropertyVetoException e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. /
  38. * 获取数据库连接
  39. @return 数据库连接
  40. /
  41. public Connection getConnection() throws SQLException {
  42. connection = source.getConnection();
  43. return connection;
  44. }
  45. //关闭操作
  46. public static void closeConnection(Connection con){
  47. if(con!= null){
  48. try {
  49. con.close();
  50. } catch (SQLException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. }
  55. public static void closeResultSet(ResultSet rs){
  56. if(rs!= null){
  57. try {
  58. rs.close();
  59. } catch (SQLException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. }
  64. public static void closePreparedStatement(PreparedStatement ps){
  65. if(ps!= null){
  66. try {
  67. ps.close();
  68. } catch (SQLException e) {
  69. e.printStackTrace();
  70. }
  71. }
  72. }
  73. }
6、实现程序的入口类StormTopologyDriver

    
    
  1. package com.lyz.storm;
  2. import org.apache.storm.Config;
  3. import org.apache.storm.LocalCluster;
  4. import org.apache.storm.StormSubmitter;
  5. import org.apache.storm.generated.StormTopology;
  6. import org.apache.storm.kafka.KafkaSpout;
  7. import org.apache.storm.kafka.SpoutConfig;
  8. import org.apache.storm.kafka.ZkHosts;
  9. import org.apache.storm.topology.TopologyBuilder;
  10. import com.lyz.storm.bolt.MySplitBolt;
  11. import com.lyz.storm.bolt.MyWordCountAndPrintBolt;
  12. /*
  13. * 这个Driver使Kafka、strom、mysql进行串联起来。
  14. 这个代码执行前需要创建kafka的topic,创建代码如下:
  15. * [root@liuyazhuang kafka]# bin/kafka-topics.sh --create --zookeeper liuyazhuang1:2181 --replication-factor 1 -partitions 3 --topic wordCount
  16. 接着还要向kafka中传递数据,打开一个shell的producer来模拟生产数据
  17. * [root@liuyazhuang kafka]# bin/kafka-console-producer.sh --broker-list liuyazhuang:9092 --topic wordCount
  18. * 接着输入数据
  19. @author liuyazhuang
  20. */
  21. public class StormTopologyDriver {
  22. public static void main(String[] args) throws Exception {
  23. //1、准备任务信息
  24. TopologyBuilder topologyBuilder = new TopologyBuilder();
  25. SpoutConfig spoutConfig = new SpoutConfig( new ZkHosts( "192.168.209.121:2181"), "wordCount", "/wordCount", "wordCount");
  26. topologyBuilder.setSpout( "KafkaSpout", new KafkaSpout(spoutConfig), 2);
  27. topologyBuilder.setBolt( "bolt1", new MySplitBolt(), 4).shuffleGrouping( "KafkaSpout");
  28. topologyBuilder.setBolt( "bolt2", new MyWordCountAndPrintBolt(), 2).shuffleGrouping( "bolt1");
  29. //2、任务提交
  30. Config config = new Config();
  31. config.setNumWorkers( 2);
  32. StormTopology stormTopology = topologyBuilder.createTopology();
  33. if(args != null && args.length > 0){
  34. StormSubmitter.submitTopology(args[ 0], config, topologyBuilder.createTopology());
  35. } else{
  36. //本地模式
  37. LocalCluster localCluster = new LocalCluster();
  38. localCluster.submitTopology( "wordcount",config,stormTopology);
  39. }
  40. }
  41. }

7、创建数据库

执行如下脚本创建数据库


    
    
  1. create database sharding_0;
  2. CREATE TABLE word_count (
  3. id int( 11) NOT NULL AUTO_INCREMENT,
  4. word varchar( 255) DEFAULT '',
  5. count int( 11) DEFAULT NULL,
  6. PRIMARY KEY ( id),
  7. UNIQUE KEY word ( word) USING BTREE
  8. ) ENGINE= InnoDB AUTO_INCREMENT= 233 DEFAULT CHARSET=utf8;

至此,我们的程序案例编写完成。

四、温馨提示

大家可以到链接http://download.csdn.net/download/l1028386804/10269075下载完整的Storm+Kafka+Flume+Zookeeper+MySQL实现数据实时分析(程序案例篇)源代码





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本教程为授权出品 一、课程简介数据仓库(Data Warehouse,可简写为DW或DWH),是面向分析的集成化数据环境,为企业决策制定过程,提供系统数据支持的战略集合,是国内外各大公司正在重点投入的战略级技术领域。 二、课程内容《大数据电商数仓项目实战》视频教程,从项目架构的搭建,到数据采集模块的设计、数仓架构的设计、实战需求实现、即席查询的实现,我们针对国内目前广泛使用的Apache原生框架和CDH版本框架进行了分别介绍,Apache原生框架介绍中涉及到的技术框架包括FlumeKafka、Sqoop、MySql、HDFS、Hive、Tez、Spark、Presto、Druid等,CDH版本框架讲解包括CM的安装部署、Hadoop、Zookeeper、Hive、FlumeKafka、Oozie、Impala、HUE、Kudu、Spark的安装配置,透彻了解不同版本框架的区别联系,将大数据全生态系统前沿技术一网打尽。在过程中对大数据生态体系进行了系统的讲解,对实际企业数仓项目中可能涉及到的技术点都进行了深入的讲解和探讨。同时穿插了大量数仓基础理论知识,让你在掌握实战经验的同时能够打下坚实的理论基础。 三、课程目标本课程以国内电商巨头实际业务应用场景为依托,对电商数仓的常见实战指标以及难点实战指标进行了详尽讲解,具体指标包括:每日、周、月活跃设备明细,留存用户比例,沉默用户、回流用户、流失用户统计,最近连续3周活跃用户统计,最近7天内连续3天活跃用户统计,GMV成交总额分析,转化率及漏斗分析,品牌复购率分析、订单表拉链表的设计等,让学生拥有更直观全面的实战经验。通过对本课程的学习,对数仓项目可以建立起清晰明确的概念,系统全面的掌握各项数仓项目技术,轻松应对各种数仓难题。 四、课程亮点本课程结合国内多家企业实际项目经验,特别加入了项目架构模块,从集群规模的确定到框架版本选型以及服务器选型,手把手教你从零开始搭建大数据集群。并且总结大量项目实战中会遇到的问题,针对各个技术框架,均有调优实战经验,具体包括:常用Linux运维命令、Hadoop集群调优、Flume组件选型及性能优化、Kafka集群规模确认及关键参数调优。通过这部分学习,助学生迅速成长,获取前沿技术经验,从容解决实战问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值