Druid 介绍
- Druid 常用应用领域:
- Druid 特点:
- Druid 适用场景
- Druid 不适用场景
- Druid 架构
- 进程和服务器
- 外部依赖
- 架构图
- 数据源和段
- 查询处理
Apache Druid是一个用于大数据实时查询和分析的高容错、高性能开源分布式时序数据库系统,旨在快速处理大规模的数据,并能够实现快速查询和分析。尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。创建Druid的最初意图主要是为了解决查询延迟问题,当时试图使用Hadoop来实现交互式查询分析,但是很难满足实时分析的需要。而Druid提供了以交互方式访问数据的能力,并权衡了查询的灵活性和性能而采取了特殊的存储格式。
Druid 常用应用领域:
- 点击流分析,(web和移动分析)
- 网络遥测分析(网络性能监控)
- 服务器度量存储
- 供应链分析(制造指标)
- 应用程序的性能指标
- 数字营销/广告分析
- 商业智能/OLAP
Druid 特点:
Druid的核心架构结合了数据仓库,时序数据库,日志搜索系统的思想,主要有以下这些特点:
- 列存储格式: Druid使用面向列的存储,这意味着它只需要加载特定查询所需的精确列。这极大地提高了只访问几列的查询的速度。此外,每个列的存储都针对其特定的数据类型进行了优化,该数据类型支持快速扫描和聚合
- 可伸缩的分布式系统: Druid通常部署在数十到数百台服务器的集群中,可以提供每秒数百万条记录的吞吐率、数万亿条记录的保存率,以及亚秒到几秒的查询延迟
- 大规模并行处理: 大规模并行处理。Druid可以在整个集群中并行处理查询。实时或批量摄入。Druid可以实时摄取数据(摄取的数据可以立即查询),也可以批量摄取。
- 实时或批量摄入: Druid可以实时摄取数据(摄取的数据可以立即查询),也可以批量摄取。
- 自愈,自平衡,操作方便: 作为一个操作人员,要向外或向内扩展集群,只需添加或删除服务器,集群就会在后台自动地重新平衡自己,而不会有任何停机时间。如果Druid的服务器失败了,系统会自动绕过伤害,直到这些服务器被替换。Druid被设计成24/7运行,不需要任何原因的计划停机时间,包括配置更改和软件更新。
- 云原生的、容错的架构,不会丢失数据: 一旦Druid摄取了您的数据,副本就会安全地存储在深存储中(通常是云存储、HDFS或共享文件系统)。你的数据可以从深层存储恢复,即使每一个Druid服务器失败。对于只影响少数Druid服务器的有限故障,复制确保在系统恢复时仍然可以进行查询。
- 快速过滤索引: Druid使用CONCISE 或者 Roaring 的压缩位图索引创建索引,支持跨多个列的快速过滤和搜索
- 基于时间的分区: Druid首先按时间分区数据,并且可以根据其他字段进行分区。这意味着基于时间的查询将只访问与查询的时间范围匹配的分区。这将显著提高基于时间的数据的性能。
- 近似算法 : Druid包括近似计数的算法-区分,近似排序,和计算近似直方图和分位数。这些算法提供有限的内存使用,通常比精确计算快得多。在精度比速度更重要的情况下, Druid也提供精确的计数-独特和精确的排名。
- 自动总结在摄取的时间: Druid选择性地支持数据摘要在摄入时间。这种汇总部分地预聚合了您的数据,可以节省大量成本并提高性能
Druid 适用场景
- 数据插入频繁, 修改更新比较少的场景
- 大多数查询都是聚合和报表查询(“分组”查询), 还有搜索和扫描查询
- 查询延迟目标是100ms到几秒钟
- 数据有一个时间成分(Druid包括优化和与时间相关的设计选择)
- 数据库会有多个表,每个查询只能命中一个大型的分布式表, 但涉及多个较小的“lookup”表。
- 有高基数(cardinality )的数据列(例如url、用户id),需要对它们进行快速计数和排序
- 希望从Kafka、HDFS、平面文件或Amazon S3之类的对象存储加载数据
Druid 不适用场景
- 需要使用主键对现有记录进行低延迟更新, Druid支持流的插入,但不支持流的更新(更新是使用后台批处理作业完成的)。
- 离线报表系统,其中查询延迟不是非常重要
- 想要执行“大”链接查询(将一个大表链接到另一个大表),并且您可以接受费数小时才能完成的查询
Druid 架构
Druid被设计成一个云友好且易于操作的多进程的分布式架构,设计成云友好且易于操作。每个Druid进程类型都可以独立配置和缩放,从而在集群上提供最大的灵活性。这种设计还提供了增强的容错能力: 一个组件的停机不会立即影响其他组件
进程和服务器
Druid有几种进程类型,简要描述如下:
- Coordinator processes 协调进程, 调度管理集群上的数据可用性.
- Overlord processes 主控制进程,控制数据摄取工作负载的分配。
- Broker processes 代理进程,处理来自外部客户端的查询
- Router processes 路由进程,是可选进程,可以将请求路由到代理、协调器和主控程序
- Historical processes 历史进程, 可查询数据存储
- MiddleManager processes 中介管理者进程, 负责摄取数据的进程
Druid进程可以按您喜欢的任何方式部署,但是为了便于部署,我们建议将它们组织成三种服务器类型: 主服务器、查询服务器和数据服务器
- 主服务器: 运行协调程序和主进程,管理数据可用性和摄入.
- 查询服务器: 运行代理和可选路由器进程,处理来自外部客户端的查询
- 数据服务器: 运行历史和中介进程,执行摄取工作负载并存储所有可查询数据
有关进程和服务器组织的更多细节,请参见Druid进程和服务器
外部依赖
除了内置的进程类型,Druid还有三个外部依赖。它们的目的是能够利用现有的基础设施。
- 深层存储
每个Druid服务器都可以访问共享文件存储。这通常是一个分布式对象存储,如S3或HDFS,或一个网络挂载的文件系统。Druid使用它来存储任何已经进入系统的数据;
Druid只使用深层存储作为数据的备份,并作为在Druid进程之间传输数据的一种方式。为了响应查询,历史进程不从深层存储中读取,而是在提供任何查询之前从本地磁盘中读取预取的段。这意味着Druid在查询过程中不需要访问深层存储,帮助它提供最好的查询延迟。它还意味着,您必须在深存储和跨历史进程中拥有足够的磁盘空间,以便计划加载数据。
有关详细信息,请参见深度存储依赖项 - 元数据存储
元数据存储包含各种共享的系统元数据,如段可用性信息和任务信息。这通常是一个传统的RDBMS,如PostgreSQL或MySQL
有关详细信息,请参见元数据存储依赖项 - Zookeeper
用于内部服务的分布协调;
架构图
下图显示了使用建议的主/查询/数据服务器组织,查询和数据如何通过此体系结构
数据源和段
Druid数据存储在“数据源”中,这类似于传统RDBMS中的表。每个数据源都按时间分区,还可以进一步选择按其他属性分区。每个时间范围称为一个“块”(例如,如果您的数据源按天分区,则为一天)。在一个块中,数据被划分为一个或多个“段”。每个段都是一个文件,通常包含几百万行数据。由于段被组织成时间块,有时可以把段想象成生存在时间轴(x轴)上,如下所示:
一个数据源可能在任何地方只有几个段,甚至可能有数十万甚至数百万段。每个段都是在一个中介管理者上创建的,在这个意义上来说,段是可变的和未提交的。段构建过程包括以下步骤,旨在生成紧凑且支持快速查询的数据文件
- 转换为列格式
- 使用位图索引建立索引
- 使用各种算法进行压缩
- 字典编码与id存储最小化字符串列
- 位图索引的位图压缩
- 所有列的类型感知压缩
段会定期提交和发布, 此时,它们被写到深存储中,成为不可变的,并从中间进程转移到历史进程(有关详细信息,请参阅上面的架构->进程和服务器)。关于段的条目也被写入元数据存储。这个条目是关于段的自描述元数据,包括段的模式、大小和它在深存储中的位置。这些条目是协调器用来知道集群上应该有哪些数据可用的。
查询处理
查询首先进入代理,代理将在其中标识哪些段具有可能与该查询相关的数据。段列表总是按时间进行修剪,也可能根据数据源的分区方式由其他属性进行修剪。然后,代理将确定哪些历史记录和中介为这些段提供服务,并向每个流程发送重写的子查询。处理它们并返回结果。代理接收结果并将它们合并在一起,以获得最终的答案,并将其返回给原始调用者。
Broker修剪是druid限制每次查询必须扫描的数据量的重要方法,但这不是唯一的方法。相对于代理用于修剪的过滤器粒度更细的过滤器,每个段中的索引结构允许Druid在查看任何一行数据之前确定哪些行(如果有的话)匹配过滤器集。一旦Druid知道哪些行匹配特定的查询,它就只访问查询所需的特定列。在这些列中,Druid可以从一行跳到另一行,避免读取与查询过滤器不匹配的数据
所以Druid使用了三种不同的技术来最大化查询性能
- 修剪为每个查询访问哪些段。
- 在每个段中,使用索引确定必须访问哪些行
- 在每个段中,只读取与特定查询相关的特定行和列。
参考官方文档: https://druid.apache.org/docs/0.15.1-incubating/design/index.html