import java.util

import kafka.common.TopicAndPartition
import kafka.message.MessageAndMetadata
import kafka.serializer.StringDecoder
import org.apache.spark.SparkConf
import org.apache.spark.rdd.RDD
import org.apache.spark.streaming.dstream.InputDStream
import org.apache.spark.streaming.kafka.{HasOffsetRanges, KafkaUtils, OffsetRange}
import org.apache.spark.streaming.{Duration, StreamingContext}
import redis.clients.jedis.{Jedis, JedisPool, JedisPoolConfig} object KafkaDricteRedis {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("redis").setMaster("local[*]")
val ssc = new StreamingContext(conf,new Duration(5000)) val groupid = "GB01" //组名
val topic = "topic_bc"//topic 名
//在redis中以 groupid/topic作为唯一标识 ,存储分区偏移量
//在Reids 使用的时hash类型来存储
val gtKey = groupid+"/"+topic
//topic
val topics = Set(topic)
//zk地址
val zkQuorum = "hadoop01:2181,hadoop02:2181,hadoop03:2181"
//brokerList
val brokerList = "hadoop04:9092,hadoop05:9092,hadoop06:9092" val kafkaParams = Map(
// metadata.broker.list
"metadata.broker.list"->brokerList,
"group.id"->groupid,
"auto.offset.reset"->kafka.api.OffsetRequest.SmallestTimeString
//从头开始消费
)
//记录topic 、分区对应的偏移量偏移量,在创建InputDStream时作为参数传如
//从这个偏移量开始读取
var fromOffset = Map[TopicAndPartition,Long]()
var kafkaDStream :InputDStream[(String,String)] = null
// 获取一个jedis连接
val conn = getConnection()
// conn.flushDB()
//jd.hget(groupid+topic,"")
//获取全部的keys
val values: util.Set[String] = conn.keys("*")
//println(values)
// [GB01/wordcount3] 分区数 偏移量
//如果keys中包含 GB01/wordcount3这样的key,则表示以前读取过
if(values.contains(gtKey)){
//获取key 为GB01/wordcount3 下面所对应的(k,v) /** conn.hgetAll(gtKey) GB01/wordcount3:
* 1 888
* 2 888
* 3 888
* 4 888
*/
var allKey: util.Map[String, String] = conn.hgetAll(gtKey)
//导入后,可以把Java中的集合转换为Scala中的集合
import scala.collection.JavaConversions._
var list: List[(String, String)] = allKey.toList
//循环得到的(k,v)
//这里面的 k 对应的是分区, v对应的是偏移量
for (key <- list){ //这里的key是一个tuple类型
//new一个TopicAndPartition 把 topic 和分区数传入
val tp = new TopicAndPartition(topic,key._1.toInt)
//把每个topic 分区 对应的偏移量传入
fromOffset += tp -> key._2.toLong
println("分区"+key._1+"偏移量为"+key._2)
}
//这里的是把数据(key ,value)是kafka 的key默认是null,
//value 是kafka中的value
val messageHandler =(mmd:MessageAndMetadata[String,String])=>{
( mmd.key(),mmd.message())
}
//创建一个InputDStream
kafkaDStream= KafkaUtils.createDirectStream[String,String,StringDecoder,StringDecoder,(String,String)](ssc,
kafkaParams,fromOffset,messageHandler)
}else{
//如果以前没有读取过,创建一个新的InputDStream
kafkaDStream= KafkaUtils.createDirectStream[String,String,StringDecoder,StringDecoder](
ssc,kafkaParams,topics
) }
//用来更新偏移量,OffsetRange中可以获取分区及偏移量
var OffsetRangs = Array[OffsetRange]()
//
kafkaDStream.foreachRDD(kafkaRDD=> {
//这里面的RDD是kafkaRDD ,可以转换为HasOffsetRange
val ranges = kafkaRDD.asInstanceOf[HasOffsetRanges]
// 获取分区信息的集合
OffsetRangs = ranges.offsetRanges
//获取value,(key 默认是null,没有用)
val map: RDD[String] = kafkaRDD.map(_._2)
map.foreach(x=>print("")) //更新偏移量
for (o <- OffsetRangs){
//取出偏移量
val offset = o.untilOffset
//取出分区
val partition = o.partition
println("partition: "+partition)
println("offset: "+offset)
//把通过hset,把对应的partition和offset写入到redis中
conn.hset(gtKey,partition.toString,offset.toString)
}
}) ssc.start()
ssc.awaitTermination() }
//Jedis连接池
def getConnection(): Jedis ={
//new 一个JedisPoolConfig,用来设定参数
val conf = new JedisPoolConfig()
val pool = new JedisPool(conf,"192.168.121.12",6379)
//最大连接数
conf.setMaxTotal(20)
//最大空闲数
conf.setMaxIdle(20) val jedis = pool.getResource()
//密码
jedis.auth("test123")
jedis }

sparkStreaming 与fafka直接方式 进行消费者偏移量的保存如redis 里面 避免代码改变与节点重启后的数据丢失与序列化问题的更多相关文章

  1. UserView--第二种方式(避免第一种方式Set饱和),基于Spark算子的java代码实现

      UserView--第二种方式(避免第一种方式Set饱和),基于Spark算子的java代码实现   测试数据 java代码 package com.hzf.spark.study; import ...

  2. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  3. Linux服务器重启后IP变掉的处理方式

    工作中有一台服务器为物理机,重启后IP就变掉了,影响到了使用,于是将服务器上的IP配置为静态方式,问题得以解决,具体如下: 1.登陆Linux服务器,cd /etc/sysconfig/network ...

  4. sparkStreaming消费kafka-0.8方式:direct方式(存储offset到zookeeper)

    生产中,为了保证kafka的offset的安全性,并且防止丢失数据现象,会手动维护偏移量(offset) 版本:kafka:0.8 其中需要注意的点: 1:获取zookeeper记录的分区偏移量 2: ...

  5. Kafka连接SparkStreaming的两种方式

    第一种方式代码: import org.apache.spark.storage.StorageLevel import org.apache.spark.{HashPartitioner, Spar ...

  6. rocketmq 以广播方式实现消费者消费消息

    package com.bfxy.rocketmq.model; import java.util.List; import org.apache.rocketmq.client.consumer.D ...

  7. 利用反射快速给Model实体赋值 使用 Task 简化异步编程 Guid ToString 格式知多少?(GUID 格式) Parallel Programming-实现并行操作的流水线(生产者、消费者) c# 无损高质量压缩图片代码 8种主要排序算法的C#实现 (一) 8种主要排序算法的C#实现 (二)

    试想这样一个业务需求:有一张合同表,由于合同涉及内容比较多所以此表比较庞大,大概有120多个字段.现在合同每一次变更时都需要对合同原始信息进行归档一次,版本号依次递增.那么我们就要新建一张合同历史表, ...

  8. session 加入redis的实现代码方式

    session,中文经常翻译为会话,其本来的含义是 指有始有终的一系列动作/消息,比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session.有时候我们可以看到这样的话&quo ...

  9. 初探内联方式的 onload="doSomething()"为何要加"()"?而js代码的 onload="doSomething" 和 addEventListener 为何不加"()"?

    问题引入:在看<Jquery基础教程>第四版的时,P34页有这样一段话 引用函数与调用函数 这里在将函数指定为处理程序时,省略了后面的圆括号,只使用了函数名.如果带着圆括号,函数会被立即调 ...

随机推荐

  1. 【2019年04月03日】A股最便宜的股票

    太钢不锈(SZ000825) - 当前便宜指数:161.66 - 滚动扣非市盈率PE:4.62 - 滚动市净率PB:1.03 - 动态年化股息收益率:4.53% - 太钢不锈(SZ000825)的历史 ...

  2. unity3D内嵌android项目

    1.从u3d中导出android工程  工程名为 HS5 2.as(AndroidStudio简写)中新建android工程 MyAndroid 3.HS5 以module方式导入到MyAndroid ...

  3. 【Dubbo 源码解析】03_Dubbo Protocol&Filter

    Protocol & Filter Dubbo 服务暴露和服务引用都是通过的 com.alibaba.dubbo.rpc.Protocol 来实现的.它是一个 SPI 扩展. @SPI(&qu ...

  4. Servlet开发 中使用 log4jdbc 记录 hibernate 的 SQL信息

    一.前言 使用log4jdbc在不改变原有代码的情况下,就可以收集执行的SQL文和JDBC执行情况. 平时开发使用的ibatis,hibernate,spring jdbc的sql日志信息,有一点个缺 ...

  5. Thinkpad L440 无线驱动突然无法使用,无法搜索到无线上网

    问题描述: 环境:Thinkpad L440,不知道是什么版本的,找朋友买的,买的时候连系统都没有,自己装的Win7系统,驱动均为官方网站下载安装.电脑在使用过程中一直带着电池,连接电源使用. 问题: ...

  6. 零拷贝sendfile解析

    传统方式read/write send/recv 在传统的文件传输里面(read/write方式),在实现上事实上是比較复杂的,须要经过多次上下文的切换.我们看一下例如以下两行代码: 1. read( ...

  7. mysql中的事物处理

    首先,事物的概念,保证一组sql语句操作的完整性,在这个过程中要充分考虑到多用户同时访问数据库数据的情况. 关键词有COMMIT,ROLLBACK,,START TRANSACTION

  8. linux 之挂载和解压

    第3天 磁盘管理 存储设备:硬盘.U盘.移动硬盘.光盘.软盘. 攒电脑.(组装一台电脑) 无法被修改. 矿长.欧阳大神. 分区.->格式化ntfs df -h  #查看磁盘分区情况,可用的. 查 ...

  9. weblogic反序列化漏洞CVE-2018-2628-批量检测脚本

    #coding=utf-8 import socket import time import re,os,sys,codecs type = 'utf-8' reload(sys) sys.setde ...

  10. 使用Bitsadmin 命令下载文件

    如果你碰到一个 Sa权限的注入点,你可以执行dos命令,但是你发现站库分离,数据库和web不在一个服务器上,而且悲剧的是数据库服务器又是个内网,这个时候你该怎么办? 这里就需要用到Bitsadmin来 ...