一、实时业务指标分析

  1.业务

  业务:
    订单系统---->MQ---->Kakfa--->Storm
    数据:订单编号、订单时间、支付编号、支付时间、商品编号、商家名称、商品价格、优惠价格、支付金额

    统计双十一当前的订单金额,订单数量,订单人数
    订单金额(整个网站,各个业务线,各个品类,各个店铺,各个品牌,每个商品

  架构

支付系统+kafka+storm/Jstorm集群+redis集群
1、支付系统发送mq到kafka集群中,编写storm程序消费kafka的数据并计算实时的订单数量、订单数量
2、将计算的实时结果保存在redis中
3、外部程序访问redis进群中的数据实时展示结果

  流程

1、Spout获取外部数据源,数据源是订单的mq,mq有固定的格式,比如json串。
2、对订单mq进行解析,得到一个对象->JavaBean
订单编号、订单时间、支付编号、支付时间、商品编号、商家名称、商品价格、优惠价格、支付金额
3、对指标进行计数
//业务中一个订单包含多个商品,需要对每个商品进行指标计算
//创建订单和取消订单两种类型,在计算总数据的是考虑将取消订单的金额减掉
//订单中有拆单的逻辑,该如何计算
4、保存指标数据到Redis

  2.整合flume思路

   flume官网也是对应的kafka的sink配置与讲解http://flume.apache.org/FlumeUserGuide.html#kafka-sink

    (网上的一些例如brokelist等配置已经被标记为deprecated,请参照官网的最新属性配置)

 将采集的日志文件保存到kafka中
  (source) 输入:tail -F xxxx.log
  (channel)存储:内存
  (sink) 输出:kafka

config
  al.source = s1
  a1.channel = c1
  al.sink = k1   source ==> exec tail -F xxxx.log
  channel ==> RAM
  sink ====> xxx.xxxx.xxxx.KafkaSink //该类必须存放lib目录
  sink.topic = orderMq
  sink.itcast = itcast

  // 实例参照下文

二、整合flume

  1.编写flume配置文件

a1.sources = s1
a1.channels = c1
a1.sinks = k1 a1.sources.s1.type=exec
a1.sources.s1.command=tail -F /home/hadoop/kafka.log
a1.sources.s1.channels=c1
a1.channels.c1.type=memory
a1.channels.c1.capacity=
a1.channels.c1.transactionCapacity= #设置Kafka接收器
a1.sinks.k1.type= org.apache.flume.sink.kafka.KafkaSink
#设置Kafka的broker地址和端口号
a1.sinks.k1.brokerList=mini1:
#设置Kafka的Topic
a1.sinks.k1.topic=topic_1
#设置序列化方式
a1.sinks.k1.serializer.class=kafka.serializer.StringEncoder
a1.sinks.k1.channel=c1

  2.开启需要的zk以及kafka服务

[hadoop@mini1 conf]$ start-zk.sh 
[hadoop@mini1 conf]$ start-kafka.sh 

  // 以上两个均以编写一键启动脚本,详情参考相关篇章随笔

  启动flume:

bin/flume-ng agent -c conf -f conf/tail-kafka.conf -n a1  -Dflume.root.logger=INFO,console

  启动消费者查看效果:

bin/kafka-console-consumer.sh --zookeeper mini1: --from-beginning --topic topic_1

  之前都是直接复制命令而不关心参数,通过官网查看可以发现查看完整参数的方法为:(网上找的基本都是这个常用参数的格式)

All of the command line tools have additional options; running the command with no arguments will display usage information documenting them in more detail.

  这样就说明sink到了kafka了!

三、整合storm

  1.maven依赖

    storm整合kafka需要一个中间的依赖Jar

<!-- https://mvnrepository.com/artifact/org.apache.storm/storm-kafka -->
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-kafka</artifactId>
<version>0.9.5</version>
</dependency>

    这里指出,storm入门中使用的storm的包,应当替换为阿里的更加强大的JStorm:

<!-- https://mvnrepository.com/artifact/com.alibaba.jstorm/jstorm-core -->
<dependency>
<groupId>com.alibaba.jstorm</groupId>
<artifactId>jstorm-core</artifactId>
<version>2.1.1</version>
<!--<scope>provided</scope>-->
</dependency>

    其他相关依赖如下:

 <dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.36</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>

  这样,将数据提前导入redis以后,就可以写出一个demo版本的代码了:(注意MyBolt#exector()方法中需要手动调用collection.ack()进行应答)

package kafkaAndStorm;

import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.StormSubmitter;
import backtype.storm.topology.TopologyBuilder;
import storm.kafka.KafkaSpout;
import storm.kafka.SpoutConfig;
import storm.kafka.ZkHosts; public class KafkaAndStormTopologyMain {
public static void main(String[] args) throws Exception{
TopologyBuilder topologyBuilder = new TopologyBuilder();
topologyBuilder.setSpout("kafkaSpout",
new KafkaSpout(new SpoutConfig(
new ZkHosts("zk01:2181,zk02:2181,zk03:2181"),
"orderMq",
"/myKafka",
"kafkaSpout")),1);
topologyBuilder.setBolt("mybolt1",new ParserOrderMqBolt(),1).shuffleGrouping("kafkaSpout"); Config config = new Config();
config.setNumWorkers(1); //3、提交任务 -----两种模式 本地模式和集群模式
if (args.length>0) {
StormSubmitter.submitTopology(args[0], config, topologyBuilder.createTopology());
}else {
LocalCluster localCluster = new LocalCluster();
localCluster.submitTopology("storm2kafka", config, topologyBuilder.createTopology());
}
}
}

KafkaAndStormTopologyMain

package kafkaAndStorm;

import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Tuple;
import com.google.gson.Gson;
import order.OrderInfo;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import java.util.HashMap;
import java.util.Map; /**
* Created by maoxiangyi on 2016/5/4.
*/
public class ParserOrderMqBolt extends BaseRichBolt {
private JedisPool pool;
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
//change "maxActive" -> "maxTotal" and "maxWait" -> "maxWaitMillis" in all examples
JedisPoolConfig config = new JedisPoolConfig();
//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
config.setMaxIdle(5);
//控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;
//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
//在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
config.setMaxTotal(1000 * 100);
//表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
config.setMaxWaitMillis(30);
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
/**
*如果你遇到 java.net.SocketTimeoutException: Read timed out exception的异常信息
*请尝试在构造JedisPool的时候设置自己的超时值. JedisPool默认的超时时间是2秒(单位毫秒)
*/
pool = new JedisPool(config, "127.0.0.1", 6379);
} @Override
public void execute(Tuple input) {
Jedis jedis = pool.getResource();
//获取kafkaSpout发送过来的数据,是一个json
String string = new String((byte[]) input.getValue(0));
//解析json
OrderInfo orderInfo = (OrderInfo) new Gson().fromJson(string, OrderInfo.class);
//整个网站,各个业务线,各个品类,各个店铺,各个品牌,每个商品
//获取整个网站的金额统计指标
// String totalAmount = jedis.get("totalAmount");
jedis.incrBy("totalAmount",orderInfo.getProductPrice());
//获取商品所属业务线的指标信息
String bid = getBubyProductId(orderInfo.getProductId(),"b");
// String bAmout = jedis.get(bid+"Amout");
jedis.incrBy(bid+"Amount",orderInfo.getProductPrice());
jedis.close();
} private String getBubyProductId(String productId,String type) {
// key:value
//index:productID:info---->Map
// productId-----<各个业务线,各个品类,各个店铺,各个品牌,每个商品>
Map<String,String> map = new HashMap<>();
map.put("b","3c");
map.put("c","phone");
map.put("s","121");
map.put("p","iphone");
return map.get(type);
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) { }
}

ParserOrderMqBolt

  有关redis的章节,参考redis随笔http://www.cnblogs.com/jiangbei/p/7255994.html

大数据入门第十八天——kafka整合flume、storm的更多相关文章

  1. 大数据入门第十七天——storm上游数据源 之kafka详解(三)其他问题

    一.kafka文件存储机制 1.topic存储 在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序 ...

  2. 大数据入门第十七天——storm上游数据源 之kafka详解(一)入门与集群安装

    一.概述 1.kafka是什么 根据标题可以有个概念:kafka是storm的上游数据源之一,也是一对经典的组合,就像郭德纲和于谦 根据官网:http://kafka.apache.org/intro ...

  3. 大数据入门第十六天——流式计算之storm详解(一)入门与集群安装

    一.概述 今天起就正式进入了流式计算.这里先解释一下流式计算的概念 离线计算 离线计算:批量获取数据.批量传输数据.周期性批量计算数据.数据展示 代表技术:Sqoop批量导入数据.HDFS批量存储数据 ...

  4. 大数据入门第三天——基础补充与ActiveMQ

    一.多线程基础回顾 先导知识在基础随笔篇:http://www.cnblogs.com/jiangbei/p/6664555.html 以下此部分以补充为主 1.概念 进程:进行中的程序,内存中有独立 ...

  5. 大数据入门第五天——离线计算之hadoop(上)概述与集群安装

    一.概述 根据之前的凡技术必登其官网的原则,我们当然先得找到它的官网:http://hadoop.apache.org/ 1.什么是hadoop 先看官网介绍: The Apache™ Hadoop® ...

  6. 大数据入门第二十天——scala入门(一)入门与配置

    一.概述 1.什么是scala  Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性.Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序. ...

  7. 大数据入门第十九天——推荐系统与mahout(一)入门与概述

    一.推荐系统概述 为了解决信息过载和用户无明确需求的问题,找到用户感兴趣的物品,才有了个性化推荐系统.其实,解决信息过载的问题,代表性的解决方案是分类目录和搜索引擎,如hao123,电商首页的分类目录 ...

  8. 大数据入门第十七天——storm上游数据源 之kafka详解(二)常用命令

    一.kafka常用命令 1.创建topic bin/kafka-topics. --replication-factor --zookeeper mini1: // 如果配置了PATH可以省略相关命令 ...

  9. 大数据入门第十二天——flume入门

    一.概述 1.什么是flume 官网的介绍:http://flume.apache.org/ Flume is a distributed, reliable, and available servi ...

随机推荐

  1. Linux 多个vi、vim进程编辑同一文件时的临时文件问题

    多个vi.vim进程编辑同一文件时的临时文件问题 by:授客 QQ:1033553122   使用vi.vim编辑文件,实际是先copy一份临时文件并映射到内存里进行编辑,所以你编辑的是临时文件,不是 ...

  2. Http 缓存机制

    HTTP 缓存体系 首先我将 Http 缓存体系分为以下三个部分: HTTP/ OK Cache-Control: no-cache Content-Type: image/png Last-Modi ...

  3. [Android] 布局优化技巧

    看了一些关于优化布局的资料,了解了很多平时不怎么注意的问题,于是把资料整理了一下,一部分内容是翻译来的,一部分是自己理解加上的.每部分内容都有demo,有些资料里的demo比较好的,我就直接拿来用了: ...

  4. Python Word2Vec使用训练好的模型生成词向量

    # 文本文件必须是utf-8无bom格式 from gensim.models.deprecated.word2vec import Word2Vec model = Word2Vec.load( ' ...

  5. python实现简单的负载均衡

    提到分发请求,相信大多数人首先会想到Nginx,Nginx作为一种多功能服务器,不仅提供了反向代理隐藏主机ip的能力,还拥有简单的缓存加速功能.当然Nginx最强大的功能还是分发请求,不仅提供了哈希, ...

  6. [CentOS7] [VMWARE] 增加磁盘空间后扩大逻辑分区

    Learn to rescan disk in Linux VM when its backed vdisk in vmware is extended. This method does not r ...

  7. Oracle中,时间的相关操作方法

    无论是DATE还是timestamp都可以进行加减操作.可以对当前日期加年.月.日.时.分.秒,操作不同的时间类型,有三种方法: 1 使用内置函数numtodsinterval增加小时,分钟和秒2 加 ...

  8. 【转载】Please configure Android Sdk(android studio)解决办法

    https://blog.csdn.net/u011622280/article/details/79005453 studio就报Please configure Android Sdk,重启and ...

  9. Linux内核参数基础优化

    web 服务负载均衡器常规网站服务器优化的基本配置: net.ipv4.tcp_fin_timeout =2 net.ipv4.tcp_tw_reuse =1 net.ipv4.tcp_tw_recy ...

  10. .net core 入坑经验 - 2、MVC Core之获取网站运行路径

    这次是建立了asp.net mvc core项目,在controller中想获取网站在硬盘中的路径,找了一圈Server.MapPath() 已不存在,HttpContent也一样,经过查阅资料发现是 ...