一、Druid 简介
1.1 大数据分析平台架构分类
数据分析的基础架构可以分为以下几类:
- 使用Hadoop/Spark 进行分析
- 将Hadoop/Spark 的结果导入 RDBMS 中提供数据分析;补充说明:RDBMS一般指关系数据库管理系统
- 将结果注入到容量更大的NoSQL中,解决数据分析的存储瓶颈,例如:HBase
- 将数据源进行流式处理,对接流式计算框架,例如:Flink、Spark Streaming,结果保存到RDBMS、NoSQL中
- 将数据源进行流式处理,对接分析数据库,例如:Druid
二、为什么会有Druid?
2.1 基于Hadoop 大数据平台的问题
基于Hadoop 的大数据平台,有如下一些问题:
- 无法保障查询性能
- 对于Hadoop 使用的MapReduce 批处理框架,数据何时能够查询没有性能保证
- 随机IO 问题
- HDFS 以集群硬盘作为存储资源池的分布式文件系统
- 在海量数据的处理过程中,会引起大量的读写操作,随机IO 是高并发场景下的性能瓶颈
- 数据可视化问题
- HDFS 对于数据分析以及数据的即席查询,HDFS 并不是最优的选择
传统的Hadoop 大数据处理架构更倾向于一种 “后台批处理的数据仓库系统”,其作为海量历史数据保存、冷数据分析,确实是一个优秀的通用解决方案,但
- 无法保证高并发环境下海量数据的查询分析性能
- 无法实现海量实时数据的查询分析与可视化
2.2 Druid 的诞生
- Druid 是由一个名为 MetaMarket 的公司开发的
- 2011年,MetaMarket 开始研发自己的“轮子” Druid,将Druid 定义为“开源、分布式、面向列式存储的实时分析数据存储系统”
- 要解决的“痛点”是
- 在高并发环境下,保证海量数据查询分析性能
- 同时提供海量实时数据的查询、分析与可视化功能
2.3 Druid 是什么
官方文档链接:https://docs.imply.io/latest/quickstart/
Druid 是面向海量数据的、用于实时查询与分析的OLAP 存储系统。Druid 的四大关键特性如下:
- 亚秒级的OLAP 查询分析
- 采用了列式存储、倒排索引、位图索引等关键技术
- 在亚秒级别内完成海量数据的过滤、聚合以及多维分析等操作
- 实时流数据分析
- 传统分析型数据库采用的批量导入数据,进行分析的方式
- Druid 提供了实时流数据分析,以及高效实时写入
- 实时数据在亚秒级内的可视化
- 丰富的数据分析功能
- Druid 提供了友好的可视化界面
- SQL 查询语言
- REST 查询接口
- 高可用性与高可拓展性
- Druid 工作节点功能单一,不相互依赖
- Druid 集群在管理、容错、灾备、扩容都很容易
阿里巴巴也曾创建过一个开源项目叫Druid (简称阿里 Druid),它是一个数据库连接池项目。阿里Druid 和我们要讨论的Druid 没有任何关系,它们解决完全不同的问题 。
2.4 Druid 典型应用架构
2.5 国内哪些公司在使用Druid
- 腾讯
- 腾讯企业采用Druid 用于分析大量的用户行为,帮助提升客户价值
- 阿里巴巴
- 阿里搜索组使用Druid 的实时分析功能用于获取用户交互行为
- 新浪微博
- 新浪广告团队使用Druid 构建数据洞察系统的实时分析部分,每天处理数十亿的消息
- 小米
- Druid 用于小米统计的后台数据收集和分析
- 也用于广告平台的数据分析
- 滴滴打车
- Druid 是滴滴实时大数据处理的核心模块,用于滴滴实时监控系统,支持数百个关键业务指标
- 通过Druid,滴滴能够快速得到各种实时的数据洞察
- 优酷土豆
- Druid 用于其广告的数据处理和分析
2.6 Druid 对比其他OLAP
2.6.1 Druid vs. ElasticSearch
- Druid 在导入过程会对原始数据进行Rollup【聚合】,而Es 会保存原始数据
- Druid 专注于OLAP,针对数据导入以及快速聚合操作做了优化
- Druid 不支持全文检索
2.6.2 Druid vs. Key/Value Stores (HBase/Cassandra/OpenTSDB)
- Druid 采用列式存储,使用倒排和 bitmap索引,可以做到快速扫描相应的列
2.6.3 Druid vs. Spark
- Spark SQL 的响应还做不到亚秒
- Druid 可以做到超低的响应时间,例妈亚秒,而且高并发面向用户的应用
2.6.4 Druid vs. SQL-on-Hadoop (Impala/Drill/Spark SQL/Presto)
- Druid 查询速度更快
- 数据导入,Druid 支持实时导入,SQL-on-Hadoop 一般将数据存储在Hdfs上,Hdfs 的写入速度有可能成为瓶颈
- SQL 支持,Druid 也支持SQL,但Druid 不支持Join 操作
2.6.5 Druid vs. Kylin
- Kylin 不支持实时查询,Druid 支持,但是Kylin3.0 已经支持实时查询
- Kylin 支持表连接(Join),Druid 不支持
- Druid 可以进行数据存储,Kylin 只能进行数据的OLAP 分析
三、安装imply
3.1 Imply 介绍
- Imply 也是Druid 的核心团队开发的,它基于Apache Druid 开发了一整套大数据分析解决方案
- Imply 基于Druid 进行了一些组件开发,提供开源社区版本和商业版,简化了部署
3.2 集群规划
由于Druid采用分布式设计,其中不同类的的节点各司其职,故在实际部署中首选需要对各类节点进行统一规划,从功能上可以分为3个部分。
- Master:管理节点,包含协调节点(coordinator)和统治节点(overlord),负责管理数据写入任务和容错相关处理。
- Data:数据节点,包含历史节点和中间管理者,负责数历史数据的加载和查询和据写入处理。
- Query:查询节点,包含查询节点和Pivot Web界面,负责提供数据查询接口和WEB交互式查询。
主机名称 | IP地址 | 角色 | 数据库 |
---|---|---|---|
node-01 | 172.20.10.7 | zk、kafka、druid (overload、coordinator) | MySQL |
node-02 | 172.20.10.8 | zk、kafka、druid (middleManager、historical) | |
node-03 | 172.20.10.9 | zk、kafka、druid (broker、router) |
3.3 下载imply
Imply-3.0.4 基于 apache-druid-0.15.0-Incubating
1、下载imply
下载方式:https://static.imply.io/release/imply-3.0.4.tar.gz
2、直接上传解压
通过浏览器下载好,通过上传工具上传到服务器 node-01中的/usr/local/ 下进行解压:
tar -zxvf imply-3.0.4.tar.gz -C /usr/local/
创建对应的软链接:
ln -s /usr/local/imply-3.0.4 /usr/local/imply
cd imply
3.4 配置 imply-3.0.4
3.4.1 mysql 中创建imply 相关的数据库
CREATE DATABASE `druid` DEFAULT CHARACTER SET utf8;
CREATE DATABASE `pivot` DEFAULT CHARACTER SET utf8;
如果zk 中也有druid,也要进行删除
zkCli.sh
ls /
rmr /druid
注意事项:MySQL 版本必须5.5及以上版本(Druid 和 Pivot 使用utf8 字符集)
这里将个人可用配置进行分享:Apache Druid 3台集群搭建,可用配置 druid_conf.zip
配置概述
Druid集群服务众多,一套完整的Druid集群需要修改很多配置文件。我们对常用配置文件进行了整理。
配置描述 | 文件路径 (Root Dir为 {IMPLY_HOME}) | 修改事项 |
---|---|---|
公共配置 | conf/druid/_common/common.runtime.properties | 1.需要添加一些扩展信息Extensions 2.需要配置Zookeeper集群信息 3.需要修改Metadata storage,建议选用mysql 4.需要修改Deep storage,建议选用HDFS |
coordinator | conf/druid/coordinator/runtime.properties | 添加host(可选) |
overlord | conf/druid/overlord/runtime.properties | 添加host(可选) |
historical | conf/druid/historical/runtime.properties | 添加hosts(可选) |
middleManager | conf/druid/middleManager/runtime.properties | 添加host(可选) |
broker | conf/druid/broker/runtime.properties | 添加host(可选) |
router | conf/druid/router/runtime.properties | 添加host(可选) |
pivot | conf/pivot/config.yaml | 启动mysql存储元数据,记得mysql需要开启远程连接 |
正常情况下,如果我们采用的是真实的服务器,修改以上配置文件即可启动集群。不过如果使用虚拟机,需要修改下每个服务启动的JVM内存参数。主要是由大改小,改成1g即可,默认配置小于1gb的就可以不用修改。
-Xms1g
-Xmx1g
-XX:MaxDirectMemorySize=1g
涉及到的文件列表:
- vi conf/druid/overlord/jvm.config
- vi conf/druid/coordinator/jvm.config
- vi conf/druid/historical/jvm.config
- vi conf/druid/middleManager/jvm.config
- vi conf/druid/broker/jvm.config
- vi conf/druid/router/jvm.config
在druid中,为了提高查询效率,Broker会缓存大量的数据到内存中,可以好不夸张的说Broker内存越大,实时查询的效率越高。对于虚拟机部署的同学来讲,除了以上jvm的配置,还需要修改broker的一些缓存配置。详见配置文件。
3.4.2 修改并上传配置文件
1 修改 vi conf/druid/_common/common.runtime.properties 文件
- 修改zookeeper 的配置
druid.extensions.directory=dist/druid/extensions
druid.extensions.hadoopDependenciesDir=dist/druid/hadoop-dependencies
druid.extensions.loadList=["mysql-metadata-storage","druid-kafka-indexing-service"]
druid.zk.service.host=node-01:2181,node-02:2181,node-03:2181
- 修改MySQL的配置,同时需要注释掉默认的配置
druid.metadata.storage.type=mysql
druid.metadata.storage.connector.connectURI=jdbc:mysql://node-01:3306/druid
druid.metadata.storage.connector.user=root
druid.metadata.storage.connector.password=aa_bb_CC1234
2 vi conf/druid/coordinator/runtime.properties
druid.service=druid/coordinator
druid.host=node-01
druid.port=8081
druid.coordinator.startDelay=PT30S
druid.coordinator.period=PT30S
3 vi conf/druid/overlord/runtime.properties
druid.service=druid/overlord
druid.host=node-01
druid.port=8090
druid.indexer.queue.startDelay=PT30S
druid.indexer.runner.type=remote
druid.indexer.storage.type=metadata
4 vi conf/druid/historical/runtime.properties
druid.service=druid/historical
druid.host=node-02
druid.port=8083
# HTTP server threads
druid.server.http.numThreads=40
# Processing threads and buffers
# druid.processing.buffer.sizeBytes=536870912 1048576
druid.processing.buffer.sizeBytes=1048576
# druid.processing.numMergeBuffers=7
druid.processing.numMergeBuffers=2
druid.processing.numThreads=2
druid.processing.tmpDir=var/druid/processing
# Segment storage
druid.segmentCache.locations=[{"path":"var/druid/segment-cache","maxSize"\:130000000000}]
druid.server.maxSize=130000000000
# Query cache
druid.historical.cache.useCache=true
druid.historical.cache.populateCache=true
druid.cache.type=caffeine
druid.cache.sizeInBytes=2000000000
5 vi conf/druid/middleManager/runtime.properties
druid.service=druid/middlemanager
druid.host=node-02
druid.port=8091
# Number of tasks per middleManager
druid.worker.capacity=3
# Task launch parameters
druid.indexer.runner.javaOpts=-server -Xmx2g -Duser.timezone=UTC -Dfile.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.util.logging.man
ager=org.apache.logging.log4j.jul.LogManager
druid.indexer.task.baseTaskDir=var/druid/task
druid.indexer.task.restoreTasksOnRestart=true
# HTTP server threads
druid.server.http.numThreads=40
# Processing threads and buffers
druid.processing.buffer.sizeBytes=100000000
druid.processing.numMergeBuffers=2
druid.processing.numThreads=2
druid.processing.tmpDir=var/druid/processing
# Hadoop indexing
druid.indexer.task.hadoopWorkingPath=var/druid/hadoop-tmp
druid.indexer.task.defaultHadoopCoordinates=["org.apache.hadoop:hadoop-client:2.8.3", "org.apache.hadoop:hadoop-aws:2.8.3"]
6 vi conf/druid/broker/runtime.properties
druid.service=druid/broker
druid.host=node-03
druid.port=8082
# HTTP server settings
druid.server.http.numThreads=60
# HTTP client settings
druid.broker.http.numConnections=10
druid.broker.http.maxQueuedBytes=50000000
# Processing threads and buffers
druid.processing.buffer.sizeBytes=536870912
druid.processing.numMergeBuffers=2
druid.processing.numThreads=1
druid.processing.tmpDir=var/druid/processing
# Query cache disabled -- push down caching and merging instead
druid.broker.cache.useCache=false
druid.broker.cache.populateCache=false
# SQL
druid.sql.enable=true
7 vi conf/druid/router/runtime.properties
druid.service=druid/router
druid.host=node-03
druid.port=8888
druid.processing.numThreads=1
druid.processing.buffer.sizeBytes=1000000
druid.router.defaultBrokerServiceName=druid/broker
druid.router.coordinatorServiceName=druid/coordinator
druid.router.http.numConnections=50
druid.router.http.readTimeout=PT5M
druid.router.http.numMaxThreads=100
druid.server.http.numThreads=100
druid.router.managementProxy.enabled=true
8 vi conf/pivot/config.yaml
- 修改mysql 的配置,同时需要注释掉默认的配置
# The port on which the Pivot server will listen on.
port: 9095
# runtime directory
varDir: var/pivot
servingMode: clustered
# User management mode
# By default Imply will not show a login screen and anyone accessing it will automatically be treated as an 'admin'
# Uncomment the line below to enable user authentication, for more info see: https://docs.imply.io/on-prem/configure/config-api
#userMode: native-users
# The initial settings that will be loaded in, in this case a connection will be created for a Druid cluster that is running locally.
initialSettings:
connections:
- name: druid
type: druid
title: My Druid
# host: localhost:8888
host: node-03:8888
coordinatorHosts: ["node-01:8081"]
overlordHosts: ["node-01:8090"]
#
# Pivot must have a state store in order to function
# The state (data cubes, dashboards, etc) can be stored in two ways.
# Choose just one option and comment out the other.
#
# 1) Stored in a sqlite file, editable at runtime with Settings View. Not suitable for running in a cluster.
# 2) Stored in a database, editable at runtime with Settings View. Works well with a cluster of Imply servers.
#
#
# 1) File-backed (sqlite) state (not suitable for running in a cluster)
#
# stateStore:
# type: sqlite
# connection: var/pivot/pivot-settings.sqlite
#
# 2) Database-backed state 'mysql' (MySQL) or 'pg' (Postgres)
#
stateStore:
location: mysql
# 这个配置必须得配,不然会报config /usr/local/imply-3.0.4/conf/pivot/config.yaml
# t.type must be defined
type: mysql
connection: 'mysql://root:aa_bb_CC1234@node-01:3306/pivot'
最后进行分发到node-02, node-03
scp -r imply-3.0.4/ node-02:$PWD
scp -r imply-3.0.4/ node-03:$PWD
# 也可以通过分工脚本实现
ync.sh imply-3.0.4
配置环境变量
在每台服务器上配置 DRUID_HOME 环境变量
ln -s /usr/local/imply-3.0.4 /usr/local/imply 【每台都要创建软链接】
vi /etc/profile
# DRUID_HOME
export DRUID_HOME=/usr/local/imply
export PATH=${DRUID_HOME}/bin:$PATH
source /etc/profile 重新加载环境变量
3.5 启动 imply 集群
1、启动zk 集群
/usr/local/zk/bin/zkServer.sh start 【三台都要】
2、node-01 节点(使用外部zk 而不使用 imply 自带zk 启动 overlord 和 coordinator)
# 使用外部zk 而不使用imply 自带zk 启动overload 和 coordinator
/usr/local/imply/bin/supervise -c /usr/local/imply/conf/supervise/master-no-zk.conf
# 后台式启动
/usr/local/imply/bin/supervise -c /usr/local/imply/conf/supervise/master-no-zk.conf -daemon
3、node-02节点
/usr/local/imply/bin/supervise -c /usr/local/imply/conf/supervise/data.conf
# 后台式启动
/usr/local/imply/bin/supervise -c /usr/local/imply/conf/supervise/data.conf -daemon
4、node-03节点(启动broker 和 router)
/usr/local/imply/bin/supervise -c /usr/local/imply/conf/supervise/query.conf
# 后台式启动
/usr/local/imply/bin/supervise -c /usr/local/imply/conf/supervise/query.conf -daemon
注意事项
- 如果希望 imply 运行在后台,在每个执行命令后面加 --daemonize
-
注意:初次启动,需要前台启动,没启动成功的任务会反复重试启动。
-
没有启动成功,可以去看日志。
一键启动
启动脚本
# 路径 /usr/local/imply/bin/start-druid.sh
# 赋权 chmod +x /usr/local/imply/bin/start-druid.sh
# content
nohup ssh node-01 "source /etc/profile; /usr/local/imply/bin/supervise -c /usr/local/imply/conf/supervise/master-no-zk.conf -daemon" &
nohup ssh node-02 "source /etc/profile; /usr/local/imply/bin/supervise -c /usr/local/imply/conf/supervise/data.conf -daemon" &
nohup ssh node-03 "source /etc/profile; /usr/local/imply/bin/supervise -c /usr/local/imply/conf/supervise/query.conf -daemon" &
3.6 访问WebUI
组件名 | 功能 | URL |
---|---|---|
broker | 查询服务 | http://node-03:8888 |
coordinator、overlord | 集群信息管理页 | http://node-01:8081/index.html |
middleManager、historical | 任务管理页 | http://node-01:8090/console.html |
pivot 可视化页 | http://node-03:9095/pivot/home |
Druid Web界面截图:
显示服务器的存储情况
当前正在运行的任务
数据查询、可视化界面
Druid 中所有表、数据源,也是我们操作最多的界面
Apache Druid 项目一:
需求:
使用Druid 分析2020 年 8月8日 按照商口分类、商品区域的产品订单总额,订单笔数
{"timestamp":"2020-08-08T01:03.ooz","category":"手机","areaName":"北京","monye":"1450"}
如果使用SQL 进行数据查询,SQL应该这样写:
select
category,
areaName,
count(1) as total_count,
sum(money) as total_count
from
order
where
timestamp = "2020-08-08"
group by
category,
areaName
数据示例:
{"timestamp":"2020-08-08T01:03.00z","category":"手机","areaName":"北京","monye":"1450"}
{"timestamp":"2020-08-08T01:03.00z","category":"手机","areaName":"北京","monye":"1450"}
{"timestamp":"2020-08-08T01:03.00z","category":"家电","areaName":"北京","monye":"1550"}
{"timestamp":"2020-08-08T01:03.00z","category":"手机","areaName":"深圳","monye":"1000"}
{"timestamp":"2020-08-08T01:03.01z","category":"手机","areaName":"深圳","monye":"2000"}
{"timestamp":"2020-08-08T01:04.01z","category":"手机","areaName":"深圳","monye":"2200"}
要实现该入门案例:
1、上传没测试数据到每个Linux 服务器
- 在一台Druid 服务器中创建 /root/druid/data1/ 目录
- mkdir -p /root/druid/data1
- 将 druid 测试数据源 \ 商品订单数据 \ order.json 到服务器的 /root/druid/data1/ 目录中
- 将 /root/druid/data1 分发到每一台服务器
2、摄取数据到Druid 中
2.1 打开 postman,请求地址设置为 http://node-01:8090/druid/indexer/v1/task
2.2 请求方式选择为 POST
2.3 body -> raw -> JSON (application/json)
2.4 将资料中的 index_ad_event.json 文件粘贴到 postman 中
2.5 发送请求
Apache 项目二:Kafka 流式数据摄取
1. kafka 索引服务方式摄取
需求:
- 实时摄取 Kafka 中 metrics topic 的数据到 Druid 中
操作步骤:
1、启动Kafka 集群
#! /bin/bash
#我们将脚本存入node-01, 因为它有到node-02、node-03的免登录权限
clear
echo "--------------------- 启动kafka集群 ----------------------"
for ip in node-01 node-02 node-03
do
echo "-----------> ssh " + $ip
ssh root@$ip "source /etc/profile; /usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties"
done
2、在Kafka 集群上创建一个名为metrics 的 topic
kafka-topics.sh --create --zookeeper node-01:2181,node-02:2181,node-03:2181 --replication-factor 1 --partitions 1 --topic metrics
3、定义摄取配置文件
- 修改 druid 测试数据源\kafka 实时摄取数据 中的 index-metrics-kafka.json 文件中的kafka 服务器地址
4、打开postman 提交索引任务
- 将 index-metrics-kafka.json 文件中的内容拷贝到 postman 中
- 发送 post 请求到 http://node-01:8090/druid/indexer/v1/supervisor
在 Overlord 中可看到
测试数据格式示例:
{"time":"2020-08-23T17:57:58Z","url":"/foo/bar","user":"alice","latencyMs":32}
{"time":"2020-08-23T17:57:59Z","url":"/","user":"bob","latencyMs":11}
{"time":"2020-08-23T17:58:00Z","url":"/foo/bar","user":"bob","latencyMs":45}
- timestampSpec 时间列,自动适应
- dimensionsSpec 纬度,url + user
- segmentGranularity 小时,一个小时保存一个segmentGranularity文件
- queryGranularity 时间粒度,NONE
- type ,按count 聚合
- topic,指定从kafka读取哪个topic 的数据
- consumerProperties 消费信息
- bootstrap.servers 指下zk 地址: node-01:9092,node-02:9092,node-03:9092
- group.id:kafka_indexing_service
- taskCount 数量:1
- replicas 数量:1
- taskDuration:PT1H,默认即可
继续向Kafka 生产数据
# 创建生产者
kafka-console-producer.sh --broker-list node-01:9092,node-02:9092,node-03:9092 --topic metrics
# 创建消费者
kafka-console-consumer.sh --bootstrap-server node-01:9092,node-02:9092,node-03:9092 --topic metrics --group topic_test1_g1
摄取配置文件结构说明
1 主体结构
摄取配置文件主要由以下几个部分组成:
- type:文件上传方式(index、index_hadoop、kafka)
- spec
- dataSchema:数据解析模式
- ioConfig:数据源
- turningConfig:优化配置(分区规则、分区大小)
{
// 一、文件上传方式
// 1.1 index - 上传本地文件
// 1.2 index_hadoop - 上传HDFS 文件
// 1.3 kafka - 拉取kafka 流数据
"type": "index"
"spec":{
// 二、数据解析模式
"dataSchema": {...},
// 三、摄取数据源
"ioConfig": {...},
// 四、摄取过程优化配置
"tuningConfig": {...}
}
}
2 数据解析模式
数据解析模式,主要为针对数据文件,定义了一系列规则:
- 获取时间戳属性
- 维度属性
- 度量属性
- 定义如何进行指标计算
- 配置粒度规则
// 二、数据解析模式
"dataSchema": {
// 2.1 数据源(表)
"dataSource":"ad_event_local",
// 2.2 解析器
"parser":{
// 2.2.1 解析字符串文本
"type":"String",
"parseSpec":{
// 2.2.1.1 字符串文本格式为JSON
"format": "json",
// 2.2.1.2 指定维度列名,维度与时间一致,导入时聚合
"dimensionSpec": {
"dimensions": [
"city",
"platform"
]
},
// 2.2.1.3 指定时间戳的列,以及时间戳格式化方式
"timestampSpec": {
"format": "auto",
"column": "timestamp"
}
}
},
// 2.3 指标计算规则
"metricsSpec": [
{
// name 表示列名
"name": "count",
"type": "count"
},
{
// 2.3.1 聚合计算后指标的列名
"name": "click"
// 2.3.2 聚合函数: count、longSum、doubleSum、longMin、doubleMin、doubleMax
"type": "longSum",
"fieldName": "click"
}
]
// 2.4 粒度规则
"granularitySpec": {
"type": "uniform",
// 2.4.1 按天来生成 segment (每天生成一个segment)
"segmentGranularity": "day",
// 2.4.2 查询的最小粒度(最小粒度为小时)
"queryGranularity": "hour",
// 2.4.3 加载原始数据的时间范围,批量数据导入需要设置/流式导入无需设置
"intervals": [
"2020-12-01/2020-12-03"
]
}
}
3. 数据源配置
数据源配置主要指定:
- 要加载数据的类型
- 从哪儿加载数据
"ioConfig": {
"type": "index",
"inputSpec": {
// 3.1 本地文件 local / HDFS使用 hadoop
"type": "local",
// 3.2 路径
"baseDir": "/root/data/",
// 3.3 只过滤出来哪个文件
"filter": "ad_event.json"
}
}
4. 优化配置
通常在优化配置中可以指定一些优化选项
"tuningConfig"
"type": "index",
// 4.1 分区类型
"partitionsSpec": {
"type": "hashed",
// 4.2 每个分区的目标行数(这里配置每个分区500W行)
"targetPartitinSize": 5000000
}
}
5. 了解 Druid WebUI 生成 spec
- Bootstrap servers:node-01:9092,node-02:9092,node-03:9092
- Topic:metrics
- Preview:预览一下数据
- Next: Parse data:下一步
- Parser to use:选择数据格式【json / csv / tsv / regex正则匹配】
- Next: Parse time:下一步,选择时间格式
- Column:时间列选择time列
- Format:格式,可以选择自动
- Next: Transform:
- Next: Filter:
- Next: Configure schema:
- Rollup:是否开启预聚合
- Query granularity:按小时、天、分钟
- Add dimension:添加纬度
- Add metric:添加指标列
- Next: Partition:下一步优化
- Next: Tune:优化配置项
- Next: Publish:发布
- Next: Edit JSON spec:这个时候就会生成json 格式文件
- Submit:提交。 当然也可能装饰生成的Json 格式文件,可以通过 postman 发送给Druid 【Post请求、Body->raw/JSON】【另外一种提交方式】
# 查看kafka主题列表
kafka-topics.sh --list --zookeeper node-01:2181,node-02:2181,node-03:2181# 创建topic
kafka-topics.sh --create --zookeeper node-01:2181,node-02:2181,node-03:2181 --replication-factor 3 --partitions 2 --topic metrics# 查看topic
kafka-topics.sh --zookeeper node-01:2181,node-02:2181,node-03:2181 --topic metrics --describe# 创建生产者
kafka-console-producer.sh --broker-list node-01:9092,node-02:9092,node-03:9092 --topic metrics# 创建消费者
kafka-console-consumer.sh --bootstrap-server node-01:9092,node-02:9092,node-03:9092 --topic metrics --group topic_test1_g1 --from-beginning# 删除topic
kafka-topics.sh --delete --zookeeper node-01:2181,node-02:2181,node-03:2181 --topic metrics
Kafka 测试数据:
{"time":"2020-08-23T17:57:58Z","url":"/foo/bar","user":"alice","latencyMs":32}
{"time":"2020-08-23T17:57:59Z","url":"/","user":"bob","latencyMs":11}
{"time":"2020-08-23T17:58:00Z","url":"/foo/bar","user":"bob","latencyMs":45}
Druid 数据查询
下面以【以从kafka 流式数据】为例,演示在Druid 中使用不同方式来进行数据查询、分析。
- JSON API 方式
- SQL 方式【重点】
1、JSON API 方式(了解)
Druid 最早提供JSON API 的方式查询数据,通过JSON 格式来定义各种查询组件实现数据查询。
将JSON 数据提交到:http://node-03:8082/druid/v2?pretty
2、使用JDBC查询Druid 中的数据
Druid 提供了JDBC 接口,Java Web 项目可以直接使用 JDBC 连接Druid 进行实时数据分析。
需求:
- 获取 metrics-kafka 数据源中,不同用户的访问次数
实现步骤:
- 创建 druid_jdbc Maven 模块
- 导入依赖
- 编写JDBC 代码连接Druid 获取数据
- 加载Druid JDBC 驱动
- 获取Druid JDBC 连接
- 构建SQL 语句
- 构建Statement,执行SQL获取结果集
- 关闭Druid 连接
<dependency>
<groupId>org.apache.calcite.avatica</groupId>
<artifactId>avatica</artifactId>
<version>1.13.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.calcite.avatica/avatica-core -->
<dependency>
<groupId>org.apache.calcite.avatica</groupId>
<artifactId>avatica-core</artifactId>
<version>1.13.0</version>
</dependency>
Java 查询示例:
package com.java.druid;
import java.sql.*;
import java.util.Properties;
/**
* @Author:
* @Date: 2020-12-27 22:05
* @Version: 1.0
* @Modified By:
* @Description:
*/
// 使用JDBC 的方法连接Druid
public class DruidJDBCDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1. 加载Druid 的JDBC驱动
Class.forName("org.apache.calcite.avatica.remote.Driver");
// 2. 获取Druid 的JDBC连接方式
Connection connection = DriverManager.getConnection("jdbc:avatica:remote:url=http://node-03:8888/druid/v2/sql/avatica/", new Properties());
// 3. 创建statement
Statement statement = connection.createStatement();
// 4. 执行sql 查询
String sql = "select * from \"metrics\"";
ResultSet resultSet = statement.executeQuery(sql);
// 5. 遍历查询结果
while (resultSet.next()) {
String url = resultSet.getString("url");
String user = resultSet.getString("user");
System.out.println("user:" + user + "\t url:" +url);
}
// 6. 关闭连接
resultSet.close();
statement.close();
connection.close();
}
}
运行结果截图:
文章最后,给大家推荐一些受欢迎的技术博客链接:
- JAVA相关的深度技术博客链接
- Flink 相关技术博客链接
- Spark 核心技术链接
- 设计模式 —— 深度技术博客链接
- 机器学习 —— 深度技术博客链接
- Hadoop相关技术博客链接
- 超全干货--Flink思维导图,花了3周左右编写、校对
- 深入JAVA 的JVM核心原理解决线上各种故障【附案例】
- 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
- 聊聊RPC通信,经常被问到的一道面试题。源码+笔记,包懂
- 深入聊聊Java 垃圾回收机制【附原理图及调优方法】
欢迎扫描下方的二维码或 搜索 公众号“大数据高级架构师”,我们会有更多、且及时的资料推送给您,欢迎多多交流!