kafka + spark Streaming + Tranquility Server发送数据到druid
花了很长时间尝试druid官网上说的Tranquility嵌入代码进行实时发送数据到druid,结果失败了,各种各样的原因造成了失败,现在还没有找到原因,在IDEA中可以跑起,放到线上就死活不行,有成功了的同仁希望贴个链接供我来学习学习;后来又尝试了从kafka实时发送到druid,还是有些错误(现在已经解决, 后面再记录一下);最后没办法呀,使用Tranquility Server呗 _ _!
Tranquility Server的配置和启动请移步:https://github.com/druid-io/tranquility/blob/master/docs/server.md
(一)、在启动了自己定制的server之后可以利用druid bin目录下的generate-example-metrics生成测试数据 (定制的server.json如下)
server.json的配置
{
"dataSources" : {
"reynold_metrics" : {
"spec" : {
"dataSchema" : {
"dataSource" : "reynold_metrics",
"parser" : {
"type" : "string",
"parseSpec" : {
"timestampSpec" : {
"column" : "timestamp",
"format" : "auto"
},
"dimensionsSpec" : {
"dimensions" : [],
"dimensionExclusions" : [
"timestamp",
"value"
]
},
"format" : "json"
}
},
"granularitySpec" : {
"type" : "uniform",
"segmentGranularity" : "hour",
"queryGranularity" : "none"
},
"metricsSpec" : [
{
"type" : "count",
"name" : "count"
},
{
"name" : "value_sum",
"type" : "doubleSum",
"fieldName" : "value"
},
{
"fieldName" : "value",
"name" : "value_min",
"type" : "doubleMin"
},
{
"type" : "doubleMax",
"name" : "value_max",
"fieldName" : "value"
}
]
},
"tuningConfig" : {
"type" : "realtime",
"maxRowsInMemory" : "",
"intermediatePersistPeriod" : "PT10M",
"windowPeriod" : "PT10M"
}
},
"properties" : {
"task.partitions" : "",
"task.replicants" : ""
}
}
},
"properties" : {
"zookeeper.connect" : "reynold-master:2181,reynold-slave02:2181,reynold-slave03:2181",
"druid.discovery.curator.path" : "/druid/discovery",
"druid.selectors.indexing.serviceName" : "druid/overlord",
"http.port" : "",
"http.threads" : ""
}
}
(二)、创建kafka的topic并往里面发送数据
删除topic:kafka-topics --delete --topic reynold --zookeeper localhost:
创建topic:kafka-topics --create --topic reynold --zookeeper localhost: --partitions --replication-factor
消费数据:kafka-console-consumer --topic reynold --zookeeper localhost: --from-beginning
生产数据:kafka-console-producer --broker-list reynold-master: --topic reynold
{"count": 1, "value_min": 74.0, "timestamp": "2017-03-09T02:34:24.000Z", "value_max": 74.0, "metricType": "request/latency", "server": "www5.example.com", "http_method": "GET", "value_sum": 74.0, "http_code": "200", "unit": "milliseconds", "page": "/"}
{"count": 1, "value_min": 75.0, "timestamp": "2017-03-09T02:34:24.000Z", "value_max": 75.0, "metricType": "request/latency", "server": "www5.example.com", "http_method": "GET", "value_sum": 75.0, "http_code": "200", "unit": "milliseconds", "page": "/list"}
{"count": 1, "value_min": 143.0, "timestamp": "2017-03-09T02:38:06.000Z", "value_max": 143.0, "metricType": "request/latency", "server": "www2.example.com", "http_method": "GET", "value_sum": 143.0, "http_code": "200", "unit": "milliseconds", "page": "/"}
(三)、使用spark streaming消费kafka中的数据并通过http发送到druid
object SparkDruid { val kafkaParam = Map[String, String](
"metadata.broker.list" -> "reynold-master:9092,reynold-slave01:9092,reynold-slave02:9092,reynold-slave03:9092",
"auto.offset.reset" -> "smallest"
) def main(args: Array[String]): Unit = {
val sparkContext = new SparkContext(new SparkConf().setMaster("local[4]").setAppName("SparkDruid"))
val ssc = new StreamingContext(sparkContext, Seconds(3))
val topic: String = "reynold" //消费的 topic 名字
val topics: Set[String] = Set(topic) //创建 stream 时使用的 topic 名字集合 var kafkaStream: InputDStream[(String, String)] = null kafkaStream = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParam, topics) kafkaStream.map(msg => msg._2).foreachRDD { rdd =>
rdd.foreach(strJson => Https.post("http://reynold-master:8200/v1/post/zcx_metrics", strJson))
} ssc.start()
ssc.awaitTermination()
}
}
Https类如下:
import java.io.InputStreamReader import com.google.common.io.CharStreams
import org.apache.http.client.methods.{HttpGet, HttpPost}
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.HttpClients /** * 通过http请求的方式,可以
* 1. 向druid里面发送数据
* 2. 提供一些查询的druid的方法
* 3. 顺带查询hbase数据的方法
*/
object Https {
private val httpClient = HttpClients.createDefault() def get(url: String): String = {
val _get = new HttpGet(url)
val resp = httpClient.execute(_get)
try {
if (resp.getStatusLine.getStatusCode != 200) {
throw new RuntimeException("error: " + resp.getStatusLine)
}
CharStreams.toString(new InputStreamReader(resp.getEntity.getContent))
} finally {
resp.close()
}
} //既可以发送数据,也可以请求数据(以结果的形式返回)
def post(url: String, content: String): String = {
val _post = new HttpPost(url)
_post.setHeader("Content-Type", "application/json")
_post.setEntity(new StringEntity(content,"utf-8"))
val resp = httpClient.execute(_post)
try {
CharStreams.toString(new InputStreamReader(resp.getEntity.getContent))
} finally {
resp.close()
} } object MapTypeRef extends com.fasterxml.jackson.core.`type`.TypeReference[Map[String, Any]] object ListMapTypeRef extends com.fasterxml.jackson.core.`type`.TypeReference[List[Map[String, Any]]] def queryHBase(sql: String): List[Map[String, Any]] = {
//将request为json格式
val request = new String(Mapper.mapper.writeValueAsBytes(Map(
"action" -> "query",
"sql" -> sql
)))
//发送json格式的请求
val resp = post("http://reynold-master:8209/api", request)
val rs = Mapper.mapper.readValue[Map[String, Any]](resp, MapTypeRef)
//val rs = Mapper.mapper.readValue[Map[String, Any]](resp, classOf[Map[String, Any]]) 这种方式也可以
rs("result").asInstanceOf[List[Map[String, Any]]]
} def queryDruid(json: String): String = {
post("http://reynold-master:18082/druid/v2", json)
} private def getDruid(path: String): String = {
get("http://reynold-master:18082/druid/v2" + path)
} def druidDataSources(): List[String] = {
Mapper.mapper.readValue[List[String]](getDruid("/datasources"), ListMapTypeRef)
} def druidDimension(datasource: String): String = {
getDruid(s"/datasources/$datasource/dimensions")
} def druidMetrics(datasource: String): String = {
getDruid(s"/datasources/$datasource/metrics")
} def main(args: Array[String]): Unit = {
println(queryHBase("select * from user_tags limit 2"))
} }
Mapper.scala
package com.donews.util import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule /**
* Created by reynold
*/ object Mapper {
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
}
注意在pom文件中添加下面的依赖:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-scala_2.11</artifactId>
<version>2.4.5</version>
</dependency>
kafka + spark Streaming + Tranquility Server发送数据到druid的更多相关文章
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十一)定制一个arvo格式文件发送到kafka的topic,通过Structured Streaming读取kafka的数据
将arvo格式数据发送到kafka的topic 第一步:定制avro schema: { "type": "record", "name": ...
- Spark Streaming的容错和数据无丢失机制
spark是迭代式的内存计算框架,具有很好的高可用性.sparkStreaming作为其模块之一,常被用于进行实时的流式计算.实时的流式处理系统必须是7*24运行的,同时可以从各种各样的系统错误中恢复 ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十)安装hadoop2.9.0搭建HA
如何搭建配置centos虚拟机请参考<Kafka:ZK+Kafka+Spark Streaming集群环境搭建(一)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网.& ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(九)安装kafka_2.11-1.1.0
如何搭建配置centos虚拟机请参考<Kafka:ZK+Kafka+Spark Streaming集群环境搭建(一)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网.& ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二)安装hadoop2.9.0
如何搭建配置centos虚拟机请参考<Kafka:ZK+Kafka+Spark Streaming集群环境搭建(一)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网.& ...
- demo2 Kafka+Spark Streaming+Redis实时计算整合实践 foreachRDD输出到redis
基于Spark通用计算平台,可以很好地扩展各种计算类型的应用,尤其是Spark提供了内建的计算库支持,像Spark Streaming.Spark SQL.MLlib.GraphX,这些内建库都提供了 ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十三)kafka+spark streaming打包好的程序提交时提示虚拟内存不足(Container is running beyond virtual memory limits. Current usage: 119.5 MB of 1 GB physical memory used; 2.2 GB of 2.1 G)
异常问题:Container is running beyond virtual memory limits. Current usage: 119.5 MB of 1 GB physical mem ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(八)安装zookeeper-3.4.12
如何搭建配置centos虚拟机请参考<Kafka:ZK+Kafka+Spark Streaming集群环境搭建(一)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网.& ...
- Apache Kafka + Spark Streaming Integration
1.目标 为了构建实时应用程序,Apache Kafka - Spark Streaming Integration是最佳组合.因此,在本文中,我们将详细了解Kafka中Spark Streamin ...
随机推荐
- 72)MFC测试动态共享库
动态共享库: 首先我建立一个新的动态库: 然后不选择空项目了,因为我们普通的cpp文件 入口是main win32入口是winmain 那么这个动态库的入口在哪里 我们就是为了看一看: 出来这样 ...
- 201771010123汪慧和《面向对象程序设计JAVA》第六周实验总结
一.理论部分: 1.继承 用已有类来构建新类的一种机制.当定义了一个新类继承了一个类时,这个新类就继承了这个类的方法和域,同时在新类中添加新的方法和域以适应新的情况. 2.类.超类.子类 (1)类继承 ...
- Jetson TX2入门学习之Ubuntu默认密码
在使用TX2开发板时进行软件更新时需要身份验证,TX2默认有两个登录身份,一个是ubuntu 一个是nvidia 登录其中的哪一个都可以更新 两个身份的密码和登录名是一样的用户:ubuntu 密码 ...
- Java 知识点(二)
接<Java 知识点(一)> java的输入输出与 c 语言不同,下面介绍Java的格式: 16.因为Java的输入类Scanner,定义在java.util包中,所以Java需要输入时要 ...
- Hexo博客NexT主题美化之评论系统
前言 更多效果展示,请访问我的博客 https://kangmingxian.github.io/ 效果图: image Valine 诞生于2017年8月7日,是一款基于Leancloud的快速 ...
- dfs--汉诺塔
在研究汉诺塔问题时,我们可以先分析俩个盘子的方法: 1.把第一个盘子放到辅助柱子上 2.把第二个盘子放大目标柱子上 3.把第一个盘子从辅助柱子移到目标柱子上 由此我们可以通过整体思想推导出一共有n个盘 ...
- jq监控滑动
$(window).scroll(function () { if ($(window).scrollTop() == $(document).height() - $(window).height( ...
- //使用PDO连接mysql数据库
<?php //使用PDO连接mysql数据库 class pdo_con{ var $dsn = 'mysql:dbname=test; host:127.0.0.1'; va ...
- \_\_slots\_\_
__slots__ 一.什么是__slots__ __slots__是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性) 使用点来访问属性本质就是 ...
- codeforce 1189C Candies! ----前缀和
题目大意:给你一个数组每个数不大于9,然后给你m个区间,每个区间的长度都是2的k次方(k=0 1 2.....) 有一种操作是把奇数位和偶数位相加 用和来代替之前的两个数,如果和大于等于10就要膜 ...