flume+spark streaming+redis完整篇

一.前言

本篇是用flume作为数据源,spark streaming来实时处理,然后把结果存在redis供查询.

本篇介绍的是一个实时统计网站访问的pv的例子.

本篇采用的各种版本如下 scala-2.10.4   spark-1.6.1  flume-1.6.0

本篇采用的spark集群为sdandalone模式



二.数据源flume配置

flume的详细说明请自行百度.这里的flume source采用http,并且使用json handler来处理.

source 配置:

a1.sources.r2.type = http
a1.sources.r2.bind=10.8.23.58
a1.sources.r2.port = 5140
a1.sources.r2.channels = c3
a1.sources.r2.handler = org.apache.flume.source.http.JSONHandler


channel因为测试,所以选择的是内存方式,实际根据情况,建议使用flie模式,并且配置checkpoint防止数据丢失.

channel配置:

a1.channels.c3.type = memory
a1.channels.c3.capacity = 100
a1.channels.c3.transactionCapacity = 100



sink有两种,如下

flume=>spark streaming有两种方式

1.推模式:这种模式比较简单,直接连接上对应的avro端口即可,但是有个最大的问题,你必须先启动spark streaming任务,然后观察这个端口开在哪台spark节点上,并且每次启动都会随机到某一个节点,然后再去改flume的配置,往那台机器上发数据,这就比较蛋疼,如果你有100台flume,那会让人疯狂的.因此这个模式,只有你的flume数量比较少的情况下适用.

推模式的sink配置:

a1.sinks.k3.type = avro
a1.sinks.k3.channel = c3
a1.sinks.k3.hostname = 10.8.23.32
a1.sinks.k3.port = 4545


2.拉模式:

这里建议先使用推模式,等推模式跑通了,再切换到拉模式. 拉模式相比推模式稍微复杂点,主要复杂在flume的配置,官网有很详细的说明,我这里会把用到的都描述出来.

首先需要把3个jar放到flume/lib下.(分别是:spark-streaming-flume-sink_2.10-1.6.1.jar ,scala-library-2.10.5.jar,  commons-lang3-3.3.2.jar,在最后的网盘地址里面有) 

拉模式的sink配置

a1.sinks = spark
a1.sinks.spark.type = org.apache.spark.streaming.flume.sink.SparkSink
a1.sinks.spark.hostname = 10.2.23.58
a1.sinks.spark.port = 4545
a1.sinks.spark.channel = c3


至此 flume配置完成.可以启动观察一下.


三.代码开发


object  PvStatistic{

  def main(args: Array[String]): Unit = {


    val masterUrl = "spark://10.8.23.112:7077"

    val conf = new SparkConf().setMaster(masterUrl).setAppName("PvStatistic")


    val ssc = new StreamingContext(conf, Seconds(15))

//    推模式
//    val flumeStream = FlumeUtils.createStream(ssc, "10.8.23.58", 4545, StorageLevel.MEMORY_ONLY_SER_2)
//    拉模式
    val flumeStream = FlumeUtils.createPollingStream(ssc, "10.8.23.58", 4545, StorageLevel.MEMORY_ONLY_SER_2)

        flumeStream.foreachRDD(rdd => {
          rdd.foreachPartition(it=>{
            val jedis = RedisClient.pool.getResource
            it.foreach(event=>{
              val sensorInfo = new String(event.event.getBody.array()) //单行记录
//              println(sensorInfo)
              val json = JSONObject.fromObject(sensorInfo);
             val url=json.getString("url")
              jedis.hincrBy("Spark:PV", url, 1);
            })
            RedisClient.pool.returnResource(jedis)
          })
        })

    ssc.start()
    ssc.awaitTermination()
  }



两种模式对于数据源的获取只是方法不一样,处理逻辑都一样.


需要的jar包 我直接贴pom文件


  <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-core_2.10</artifactId>
      <version>1.6.1</version>
      <scope>provided</scope>
  </dependency>
<dependency>
  <groupId>org.apache.spark</groupId>
  <artifactId>spark-streaming_2.10</artifactId>
  <version>1.6.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-streaming-flume_2.10 -->
<dependency>
  <groupId>org.apache.spark</groupId>
  <artifactId>spark-streaming-flume_2.10</artifactId>
  <version>1.6.1</version>
</dependency>


  <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.8.1</version>
  </dependency>


<dependency>
  <groupId>net.sf.json-lib</groupId>
  <artifactId>json-lib</artifactId>
  <version>2.4</version>
  <classifier>jdk15</classifier>
</dependency>

完成以后就是打包上传到spark主节点了,这里提一下,因为需要很多依赖包,所以建议直接打成一个包含所有依赖的jar.

推荐一个maven插件来做这个事.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.3</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <filters>
          <filter>
            <artifact>*:*</artifact>
            <excludes>
              <exclude>META-INF/*.SF</exclude>
              <exclude>META-INF/*.DSA</exclude>
              <exclude>META-INF/*.RSA</exclude>
            </excludes>
          </filter>
        </filters>
        <transformers>
          <transformer
                  implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>com.defonds.RsaEncryptor</mainClass>
          </transformer>
          <transformer
                  implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/spring.handlers</resource>
          </transformer>
          <transformer
                  implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/spring.schemas</resource>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

有了这个插件,直接maven clean package打包就行了,打出来的包包含所有依赖文件.


然后把这个包上传到spark主节点,在spark/bin下执行

spark-submit --master spark://cdh112:7077 --class com.dome.PvStatistic  /opt/spark/job/analyseSys-1.0-SNAPSHOT.jar


然后可以向之前配置的flume的接收端口发送http请求测试了

发送内容:

[
    {
        "body":"{\"url\": \"http://20160926 16:02\"}",
        "headers":{"v1":"log"}
        }
 ]


在redis里面可以看到 SparkPv开头的key下面 每个访问地址的访问次数.


上面提到的jar包

链接:http://pan.baidu.com/s/1kUEJJJx 密码:9fxv



最后感谢一下群内的各位兄弟以及群主aDog~ 有兴趣交流的可以加入QQ群:459898801

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值