大家好,我是勾叔,今天勾叔来跟大家聊一下Apache Druid的架构。
Apache Druid 架构中涉及5种角色,大家也可以理解为它启动运行之后会有5种进程,如下:
Overlord
MiddleManager
Coordinator
Historical
Broker
往往,我们把运行了某个进程的机器称为某节点,比如运行了Broker进程的机器就是Broker节点。
以下是这几个节点的主要功能:
Overlord、MiddleManager
负责处理索引任务
Overlord是MiddleManager的master节点
Coordinator、Historical
负责管理分发Segment
Coordinator是Historical的master节点
Broker
负责接收Client查询请求
拆分子查询给MiddleManager和Historical节点
合并查询结果返回给Client
上面,我们认识了Druid中的5类角色,接下来我们从Druid数据存储及索引服务这两个维度进一步认识它的架构。
1. Druid数据存储
Druid能提供对大数据集的实时摄入和高效复杂查询的主要原因:基于Datasource与Segment的数据存储结构。
1.1 数据存储
Druid中的数据存储在被称为DataSource中,DataSource类似RDMS中的table
每个DataSource按照时间划分,每个时间范围称为一个chunk((比如按天分区,则一个chunk为一天))
在chunk中数据被分为一个或多个segment
segment是数据实际存储结构,Datasource、Chunk只是一个逻辑概念
每个segment都是一个单独的文件,通常包含几百万行数据
segment是按照时间组织成的chunk,所以在按照时间查询数据时,效率非常高
1.2 数据分区
Druid处理的是事件数据,每条数据都会带有一个时间戳,可以使用时间进行分区
上图指定了分区粒度为为天,那么每天的数据都会被单独存储和查询
1.3 Segment内部存储结构
Druid采用列式存储,每列数据都是在独立的结构中存储
Segment中的数据类型主要分为三种
时间戳
维度列
指标列
2. 索引服务
索引服务是数据摄入创建和销毁Segment的重要方式
Druid提供一组支持索引服务(Indexing Service)的组件,即Overlord和MiddleManager节点
索引服务采用的是主从架构,Overlord为主节点,MiddleManager是从节点
索引服务架构图如下图所示:
索引服务由三部分组件组成:
Overlord组件
分配任务给MiddleManager
MiddleManager组件
用于管理Peon的
Peon(劳工)组件
用于执行任务
索引服务架构和Yarn的架构很像:
Overlaod => ResourceManager,负责集群资源管理和任务分配
MiddleManager => NodeManager,负责接受任务和管理本节点的资源
Peon => Container,执行节点上具体的任务
2.1 Overlord节点
Overlord是索引服务的主节点,对外负责接受索引任务,对内负责将任务分解并下发给MiddleManager
Overlord有两种运行模式:
Overlord提供了一个UI客户端,可以用于查看任务、运行任务和终止任务等
Overlord提供了RESETful的访问形式,所以客户端可以通过HTTP POST形式向请求节点提交任务
2.2 MiddleManager节点
MiddleManager是执行任务的工作节点
MiddleManager会将任务单独发给每个单独JVM运行的Peon
每个Peon一次只能运行一个任务
2.3 摄取Kafka数据构建索引
需求:实时摄取Kafka中 metrics topic的数据到 Druid中
在Overlord中可以看到
1、在Kafka集群上开启一个控制台producer
nohup bin/kafka-server-start.sh config/server.properties &bin/kafka-console-producer.sh --broker-list linux123:9092 --topic metrics1
2、在Kafka producer控制台中粘贴如下数据
{"time":"2020-07-23T17:57:58Z","url":"/foo/bar","user":"alice","latencyMs":32}{"time":"2020-07-23T17:57:59Z","url":"/","user":"bob","latencyMs":11}{"time":"2020-07-23T17:58:00Z","url": "/foo/bar","user":"bob","latencyMs":45}
3、打开postman提交索引任务
将 index-metrics-kafka.json 文件中的内容拷贝到 postman 中
发送post请求到http://linux121:8090/druid/indexer/v1/supervisor
4、在 Druid Console中执行以下SQL查询
SELECT *from "metrics-kafka1"LIMIT 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": {...} }}
数据解析模式
数据解析模式,主要为针对数据文件,定义了一系列规则:
获取时间戳属性
维度属性
度量属性
定义如何进行指标计算
配置粒度规则
// ② 数据摄取模式"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 指定维度列名 "dimensionsSpec": { "dimensions": [ "city", "platform" ] }, // 2.2.1.3 指定时间戳的列,以及时间戳格式化方式 "timestampSpec": { "format": "auto", "column": "timestamp" } } }, // 2.3 指标计算规则 "metricsSpec": [ { "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": [ "2018-12-01/2018-12-03" ] } }
数据源配置
数据源配置主要指定:
要加载数据的类型
从哪儿加载数据
优化配置
通常在优化配置中可以指定一些优化选项,涉及分区类型,分区目标行数
2.4 Coordinator节点
Coordinator是Historical的mater节点,主要负责管理和分发Segment
具体工作就是
告知Historical加载或删除Segment
管理Segment副本以及负载Segment在Historical上的均衡
Coordinator是定期运行的,通过Zookeeper获取当前集群状态,通过评估集群状态来进行均衡负载Segment
Coordinator连接数据库(MetaStore),获取Segment信息和规则(Rule),Coordinator根据数据库中表的数据来进行集群 segment 管理
2.5 Historical节点
Historical节点负责管理历史Segment
Historical节点通过Zookeeper监听指定的路径来发现是否有新的Segment需要加载
Historical节点收到有新的Segment时候,就会检测本地cache和磁盘,查看是否有该Segment信息。如果没有Historical节点会从Zookeeper中拉取该Segment相关的信息,然后进行下载
2.6 Broker节点
Broker节点负责转发Client查询请求的
Broker通过zookeeper能够知道哪个Segment在哪些节点上,将查询转发给相应节点
所有节点返回数据后,Broker会将所有节点的数据进行合并,然后返回给Client
从架构上看,勾叔认为还是蛮清晰的,并不难理解,所以不要惧怕大数据,接近它认识它,你OK的。
好了,下一篇分享,勾叔来详细解读支撑Apache Druid高效查询的索引以及压缩机制 。
推荐阅读:
# 谈Druid实时多维聚合分析技术 (1)
数据挖掘,到底在解决什么问题?
连载预告: