Apache Druid 的集群设计与工作流程
导读:本文将描述 Apache Druid 的基本集群架构,说明架构中各进程的作用。并从数据写入和数据查询两个角度来说明 Druid 架构的工作流程。
关注公众号 MageByte,设置星标点「在看」是我们创造好文的动力。公众号后台回复 “加群” 进入技术交流群获更多技术成长。
Druid 是多进程架构,每种进程类型都可以独立配置,独立扩展。这样可以为集群提供最大的灵活度。这种设计还提供了强失效容忍:一个失效的组件不会立即影响另外的组件。
下面我们来深入了解 Druid 有哪些进程类型,每种进程又在整个集群中扮演什么角色。
进程和服务(Process and Servers)
Druid 有多种进程类型,如下:
- Coordinator进程在集群中负责管理数据可用。
- Overlord进程控制数据摄入的资源负载分配。
- Broker进程处理外部客户端的查询。
- Router进程是可选的,它可以路由请求到 Brokers,Coordinator,和 Overlord。
- Historical进程存储可查询的数据。
- MiddleManager进程负责数据摄入。
你可以以任何方式来部署上面的进程。但是为了易于运维,官方建议以下面三种服务类型来组织进程:Master、Query 和 Data。
- Master:运行 Coordinator 和 Overlord 进程,管理数据可用和数据写入。
- Query: 运行 Broker 和可选的 Router 进程,负责处理外部查询请求。
- Data:运行 Historical 和 MiddleManager 进程,负责执行数据写入任务并存储可查询的数据。
外部依赖(External dependencies)
除了内置的进程类型,Druid 还有三个外部依赖项。
Deep storage
共享文件存储,只要配置成允许 Druid 访问即可。在集群部署中,通常使用分布式存储(如 S3 或 HDFS)或挂载网络文件系统。在单机部署中,通常使用本地磁盘。Druid 使用 Deep Storage 存储写入集群的数据。
Druid 仅将 Deep Storage 用作数据的备份,并作为 Druid进程间在后台的数据传输方式。要响应查询,Historical 进程并不从 Deep Storage 上读取数据,在任何查询之前,先从本地磁盘查询已经存在的数据。这意味着,Druid 在查询时并不需要访问 Deep Storage,这样就可以得到最优的查询延迟。这也意味着,在 Deep Storage 和 Historical 进程间你必须有足够的磁盘空间来存储你计划加载的数据。
Deep Storage 是 Druid 弹性、容错设计的重要组成部分。如果 Druid 单机进程本地数据丢失,可以从 Deep Storage 恢复数据。
Metadata storage
元数据存储,存储各种共享的系统元数据,如 segment 可用性信息和 task 信息。在集群部署中,通常使用传统的 RDBMS,如 PostgreSQL 或 MySQL。在单机部署中,通常使用本地存储,如 Apache Derby 数据库。
Zookeeper
用来进行内部服务发现,协调,和主选举。
架构图(Architecture diagram)
下图可以看出使用官方建议的 Master/Query/Data 服务部署方式,查询和写入数据是如何进行的:
存储设计(Storage design)
Datasources and segments
Druid 数据存储在"datasources"中,它就像 RDBMS 中的 table。每一个 datasources 通过时间分区,或通过其他属性进行分区。每一个时间范围称之为"chunk"(比如,一天一个,如果你的 datasource 使用 day 分区)。在 chunk 中,数据被分区进一个或多个"segments"中。每一个 segment 是一个单独的文件,通常包含数百万行数据。一旦 segment 被存储进 chunks,其组织方式将如以下时间线所示:
一个 datasource 也许只有一个,也可能有数十万甚至上百万个 segment。每个 segment 生命周期开始于 MiddleManager 创建时,刚被创建时,segment 是可变和未提交的。segment 构建过程包含以下几步,旨在生成结构紧凑并支持快速查询的数据文件。
- 转换成列格式
- 使用 bitmap 创建索引
- 使用各种算法压缩数据
- 为 String 列做字典编码,用最小化 id 存储
- 对 bitmap 索引做 bitmap 压缩
- 对所有列做类型感知压缩
segment 定时提交和发布。此时,数据被写入 Deep Storage,并且再不可变,并从 MiddleManagers 进程迁移至 Historical 进程中。一个关于 segment 的 entry 将写入 metadata storage。这个 entry 是关于 segment 的元数据的自描述信息,包含如 segment 的数据模式,大小,Deep Storage 地址等信息。这些信息让 Coordinator 知道集群中哪些数据是可用的。
索引和移交(Indexing and handoff)
indexing 是每个 segment 创建的机制。handoff 是数据被发布并开始可以被 Historical 进程处理的机制。这机制在 indexing 侧的工作顺序如下:
- 启动一个 indexing task 并构建一个新的 segment。在构建之前必须先确定其标识。对于一个追加任务(如 kafka 任务,或 append 模式任务)可以调用 Overlord 的"allocate"API 来将一个潜在的新分区加入到一个已经存在的 segment 中。对于一个覆写任务(如 Hadoop 任务,或非 append 模式 index 任务) 将为 interval 创建新版本号和新 segment。
- 如果 indexing 任务是实时任务(如 Kafka 任务),此时 segment 可以立即被查询。数据是可用的,但还是未发布状态。
- 当 indexing 任务完成读取 segment 数据时,它将数据推送到 Deep Storage 上,并通过向 metadata store 写一个记录来发布数据。
- 如果 indexing 任务是实时任务,此时,它将等待 Historical 进程加载这个 segment。如果 indexing 任务不是实时任务,就立即退出。
这机制在 Coordinator/Historical 侧的工作如下:
- Coordinator 定期从 metadata storage 拉取已经发布的 segments(默认,每分钟执行)。
- 当 Coordinate 发现已发布但不可用的 segment 时,它将选择一个 Historical 进程去加载 segment,并指示 Historical 该做什么。
- Historical 加载 segment 并为其提供服务。
- 此时,如果 indexing 任务还在等待数据移交,就可以退出。
数据写入(indexing)和移交(handoff):
段标识(Segment identifiers)
Segment 标识由下面四部分组成:
- Datasource 名称。
- 时间间隔(segment 包含的时间间隔,对应数据摄入时
segmentGranularity
指定参数)。 - 版本号(通常是 ISO8601 时间戳,对应 segment 首次生成时的时间)。
- 分区号(整数,在 datasource+interval+version 中唯一,不一定是连续的)。
例如,这是 datasource 为clarity-cloud0
,时间段为2018-05-21T16:00:00.000Z/2018-05-21T17:00:00.000Z
,版本号为2018-05-21T15:56:09.909Z
,分区号为 1 的标识符:
clarity-cloud0_2018-05-21T16:00:00.000Z_2018-05-21T17:00:00.000Z_2018-05-21T15:56:09.909Z_1
分区号为 0(块中的第一个分区)的 segment 省略了分区号,如以下示例所示,它是与前一个分区在同一时间块中的 segment,但分区号为 0 而不是 1:
clarity-cloud0_2018-05-21T16:00:00.000Z_2018-05-21T17:00:00.000Z_2018-05-21T15:56:09.909Z
段版本控制(segment versioning)
你可能想知道上一节中描述的“版本号”是什么。
Druid 支持批处理模式覆写。在 Driud 中,如果你要做的只是追加数据,那么每个时间块只有一个版本。但是,当你覆盖数据时,在幕后发生的事情是使用相同的数据源,相同的时间间隔,但版本号更高的方式创建了一组新的 segment。这向 Druid 系统的其余部分发出信号,表明应从群集中删除较旧的版本,而应使用新版本替换它。
对于用户而言,切换似乎是瞬间发生的,因为 Druid 通过先加载新数据(但不允许对其进行查询)来处理此问题,然后在所有新数据加载完毕后,立即将新查询切换到新 segment。然后,它在几分钟后删除旧 segment。
段(segment)生命周期
每个 segment 的生命周期都涉及以下三个主要领域:
- 元数据存储区:一旦构建完 segment,就将 segment 元数据(小的 JSON 数据,通常不超过几个 KB)存储在
元数据存储区
中。将 segmnet 的记录插入元数据存储的操作称为发布。然后将元数据中的use
布尔值设置成可用
。由实时任务创建的 segment 将在发布之前可用,因为它们仅在 segment 完成时才发布,并且不接受任何其他数据。 - 深度存储:segment 数据构建完成后,并在将元数据发布到元数据存储之前,立即将 segment 数据文件推送到深度存储。
- 查询的可用性:segment 可用于在某些 Druid 数据服务器上进行查询,例如实时任务或Historical进程。
你可以使用 Druid SQL sys.segments
表检查当前 segment 的状态 。它包括以下标志:
is_published
:如果 segment 元数据已发布到存储的元数据中,used
则为 true,此值也为 true。is_available
:如果该 segment 当前可用于实时任务或Historical查询,则为 True。is_realtime
:如果 segment 在实时任务上可用,则为 true 。对于使用实时写入的数据源,通常会先设置成true
,然后随着 segment 的发布和移交而变成false
。is_overshadowed
:如果该 segment 已发布(used
设置为 true)并且被其他一些已发布的 segment 完全覆盖,则为 true。通常,这是一个过渡状态,处于此状态的 segment 很快就会将其used
标志自动设置为 false。
查询处理
查询首先进入Broker
进程,Broker
将得出哪些 segment 具有与该查询有关的数据(segment 列表始终按时间规划,也可以根据其他属性来规划,这取决于数据源的分区方式),然后,Broker
将确定哪些 Historical
和 MiddleManager
正在为这些 segment 提供服务,并将重写的子查询发送给每个进程。Historical
/ MiddleManager
进程将接受查询,对其进行处理并返回结果。Broker
接收结果并将它们合并在一起以得到最终答案,并将其返回给客户端。
Broker
会分析每个请求,优化查询,尽可能的减少每个查询必须扫描的数据量。相比于 Broker 过滤器做的优化,每个 segment 内的索引结构允许 Druid 在查看任何数据行之前先找出哪些行(如果有)与过滤器集匹配。一旦 Druid 知道哪些行与特定查询匹配,它就只会访问该查询所需的特定列。在这些列中,Druid 可以在行与行之间跳过,从而避免读取与查询过滤器不匹配的数据。
因此,Druid 使用三种不同的技术来优化查询性能:
检索每个查询需访问的 segment。
在每个 segment 中,使用索引来标识查询的行。
在每个 segment 中,仅读取与特定查询相关的行和列。
系列推荐
Mysql:小主键,大问题
Mysql大数据量问题与解决
你应该知道一些其他存储——列式存储
时间序列数据库(TSDB)初识与选择(InfluxDB、OpenTSDB、Druid、Elasticsearch对比)
十分钟了解Apache Druid(集数据仓库、时间序列、全文检索于一体的存储方案)
Apache Druid 底层存储设计(列存储与全文检索)
Apache Druid 的集群设计与工作流程
想了解更多数据存储,时间序列,Druid 的知识,可关注我的公众号。点「在看」是我们创造好文的动力
Apache Druid 的集群设计与工作流程的更多相关文章
- Tomcat:基于Apache+Tomcat的集群搭建
根据Tomcat的官方文档说明可以知道,使用Tomcat配置集群需要与其它Web Server配合使用才可以完成,典型的有Apache和IIS. 这里就使用Apache+Tomcat方式来完成基于To ...
- [Kubernetes]如何让集群为我们工作?
前一段时间倒腾k8s的时候,写了一系列的博客,有很多人不理解那样做的意义是什么,为什么要那样做,这篇文章就尝试解释一下,在实际环境中,是如何让集群为我们工作的. 因为只研究了一个月左右的时间,认识难免 ...
- Redis集群设计原理
---恢复内容开始--- Redis集群设计包括2部分:哈希Slot和节点主从,本篇博文通过3张图来搞明白Redis的集群设计. 节点主从: 主从设计不算什么新鲜玩意,在数据库中我们也经常用主从来做读 ...
- 【集群】Redis集群设计原理
Redis集群设计包括2部分:哈希Slot和节点主从 节点主从: 主从设计不算什么新鲜玩意,在数据库中我们也经常用主从来做读写分离,直接上图: 图上能看得到的信息: 1, 只有1个Master,可以有 ...
- 三张图秒懂Redis集群设计原理
转载Redis Cluster原理 转载https://blog.csdn.net/yejingtao703/article/details/78484151 redis集群部署方式: 单机 主从 r ...
- window xp Apache与Tomcat集群配置--转载
转载地址:http://www.cnblogs.com/obullxl/archive/2011/06/09/apache-tomcat-cluster-config.html 一. 环境说明 Win ...
- Apache+Tomcat +mod_proxy集群负载均衡及session
序言: 在玩Apache+Tomcat +mod_jk集群负载均衡及session的时候发现,还有一种方式可以实现,就是网上各位大牛们说的mod_proxy反向代理. 实在弄的我的知识细胞洋洋.实 ...
- 在 Linux 多节点安装配置 Apache Zookeeper 分布式集群
规划: 三台物理服务器就形成了(法定人数).对于高可用性集群,您可以使用高于3的任何奇数.例如,如果设置5台服务器,则集群可以处理两个故障节点等. 物理服务器需要开启的端口 2888 , 3888 和 ...
- 7.redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?
作者:中华石杉 面试题 redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗? 面试官心理分析 在前几年, ...
随机推荐
- day23-logging模块
# logging日志记录的两个内容:1.有5种级别的日志记录模式.2.两种配置方式:basicconfig.logger对象. # logging的作用: #1.排错的时候需要打印很多细节来帮助排错 ...
- java后端导出excel
最近工作中需要导出excel.这次机智一点做个笔记,顺便写了一个比较通用的工具类.自然目前不能生成java实体类属性嵌套多次的这种没办法导出了,后续有需要的时候我再改改. 首先,java后端导出exc ...
- ofo小黄车推出车身商业化广告,能自救成功吗?
ofo终于还是扛不住了!作为之前与摩拜相抗衡的巨头,ofo其实也是最被看好的共享单车企业之一.可惜共享单车行业的窘境,终究不是成为巨头后就能拯救的.摩拜被美团收购后,ofo就成为巨头垂涎的目标.数十亿 ...
- mysql 数据库 创建用户和授权
创建用户和密码 CREATE USER '用户名'@'%' IDENTIFIED BY '密码'; 创建几个数据库 例如 db1,db2 用户授权访问指定的数据库 grant all privileg ...
- 听《Sara》
Sara这首歌太好听了,虽然没有清楚具体是唱什么,但我感觉是讲一个故事,很好奇,我找到了歌词. Sara 塞拉 鲍勃迪伦 I laid on a dune, I looked at the sky, ...
- [LC] 268. Missing Number
Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missin ...
- kafka运行找不到或无法加载主类 Files\Java\jdk1.8.0_131\lib\dt.jar;C:\Program
最近在研究Flink+kafka解决方案, kafka的安装首先需要安装zookeeper,在安装zookeeper是报错找不到或无法加载主类 Files\Java\jdk1.8.0_131\lib\ ...
- jmeter如何解决乱码问题
使用jmeter的时候时常遇到中文乱码的情况,下面总结一下几个解决方法,方便以后进行复习. 1.添加后置处理器Beanshell PostProcessor,在输入框内写入“prve.setDateE ...
- the extent of|fill in|find itimpossible to|something|the other day|Be man enough to do sth/for sth|cure sb of |draw out| gone over|made for | see someone off,|
area or length; amount 面积,范围:长度:数量 We don't yet know the extent of his injuries (= how bad his injur ...
- NEON优化之《简介》
NDK支持NEON环境配置:https://blog.csdn.net/app_12062011/article/details/50462351 一个很典型的例子:http://hilbert-sp ...