什么是Druid?

Druid是一个专为大型数据集上的高性能切片和骰子分析(“ OLAP ”风格)而设计的数据存储。Druid最常用作为GUI分析应用程序提供动力的数据存储,或者用作需要快速聚合的高度并发API的后端。Druid的常见应用领域包括:

Druid的主要特点是:

  1. 列式存储格式。Druid使用面向列的存储,这意味着它只需要加载特定查询所需的精确列。这为只查看几列的查询提供了巨大的速度提升。此外,每列都针对其特定数据类型进行了优化,支持快速扫描和聚合。
  2. 可扩展的分布式系 Druid通常部署在数十到数百台服务器的集群中,并且可以提供数百万条记录/秒的摄取率,保留数万亿条记录,以及亚秒级到几秒钟的查询延迟。
  3. 大规模并行处理。Druid可以在整个集群中并行处理查询。
  4. Realtime or batch ingestion. Druid can ingest data either realtime (ingested data is immediately available for querying) or in batches.
  5. Self-healing, self-balancing, easy to operate. As an operator, to scale the cluster out or in, simply add or remove servers and the cluster will rebalance itself automatically, in the background, without any downtime. If any Druid servers fail, the system will automatically route around the damage until those servers can be replaced. Druid is designed to run 24/7 with no need for planned downtimes for any reason, including configuration changes and software updates.
  6. 云原生,容错的架构,不会丢失数据。一旦Druid摄取了您的数据,副本就会安全地存储在深层存储(通常是云存储,HDFS或共享文件系统)中。即使每个Druid服务器都出现故障,您的数据也可以从深层存储中恢复。对于仅影响少数Druid服务器的更有限的故障,复制可确保在系统恢复时仍可进行查询。
  7. 用于快速过滤的索引。Druid使用CONCISERoaring压缩位图索引来创建索引,这些索引可以跨多个列快速过滤和搜索。
  8. 近似算法。Druid包括用于近似计数 - 不同,近似排序以及近似直方图和分位数的计算的算法。这些算法提供有限的内存使用,并且通常比精确计算快得多。对于精确度比速度更重要的情况,Druid还提供精确计数 - 不同且精确的排名。
  9. 摄取时自动汇总。Druid可选择在摄取时支持数据汇总。此摘要部分预先汇总了您的数据,可以节省大量成本并提高性能。

我什么时候应该使用Druid?

如果您的用例符合以下几个描述符,Druid可能是一个不错的选择:

情况下,您可能会希望使用Druid包括:

建筑

Druid拥有一个多进程,分布式架构,旨在实现云友好且易于操作。每个Druid流程类型都可以独立配置和扩展,为您的群集提供最大的灵活性。此设计还提供增强的容错能力:一个组件的中断不会立即影响其他组件。

Druid的过程类型是:

Druid进程可以单独部署(每个物理服务器,虚拟服务器或容器一个),也可以在共享服务器上共存。一个常见的托管计划是三种类型的计划:

  1. “数据”服务器运行历史和中间管理程序。
  2. “查询”服务器运行Broker和(可选)路由器进程。
  3. “Master”服务器运行Coordinator和Overlord进程。他们也可以运行ZooKeeper。

除了这些流程类型,Druid还有三个外部依赖项。这些旨在能够利用现有的基础设施。

这种架构背后的想法是使Druid集群在生产中大规模运作变得简单。例如,深度存储和元数据存储与集群其余部分的分离意味着Druid进程具有极强的容错能力:即使每个Druid服务器都出现故障,您仍然可以从存储在深存储中的数据和元数据中重新启动集群。商店。

下图显示了查询和数据如何流经此体系结构:

img

数据源和细分

Druid数据存储在“数据源”中,类似于传统RDBMS中的表。每个数据源按时间划分,并可选择进一步按其他属性划分。每个时间范围都称为“块”(例如,如果您的数据源按天分区,则为一天)。在块中,数据被划分为一个或多个“段”。每个段都是单个文件,通常包含多达几百万行数据。由于段被组织成时间块,因此将段视为生活在时间轴上有时会有所帮助,如下所示:

img

数据源可能只有几个段,最多可达数十万甚至数百万个段。每个段都开始在MiddleManager上创建生命,并且在那时,它是可变的和未提交的。分段构建过程包括以下步骤,旨在生成紧凑的数据文件并支持快速查询:

定期提交和发布细分。此时,它们被写入深层存储,变为不可变,并从MiddleManagers迁移到历史进程(有关详细信息,请参阅上面的体系结构)。关于该段的条目也被写入元数据存储。此条目是有关该段的自描述元数据,包括段的架构,其大小以及它在深层存储上的位置。这些条目是协调器用于了解群集上应该有哪些数据的用途。

查询处理

查询首先进入Broker,Broker将识别哪些段具有可能与该查询相关的数据。段列表始终按时间进行修剪,也可能会被其他属性修剪,具体取决于数据源的分区方式。然后,代理将识别哪些Historicals和MiddleManagers正在为这些段提供服务,并向每个进程发送重写的子查询。Historical / MiddleManager进程将接受查询,处理它们并返回结果。Broker接收结果并将它们合并在一起以获得最终答案,并将其返回给原始调用者。

经纪人修剪是Druid限制每个查询必须扫描的数据量的重要方式,但这不是唯一的方法。对于比Broker可用于修剪更细粒度的过滤器,每个段内的索引结构允许Druid在查看任何数据行之前确定哪些(如果有)行匹配过滤器集。一旦Druid知道哪些行与特定查询匹配,它只会访问该查询所需的特定列。在这些列中,Druid可以从一行跳到另一行,避免读取与查询过滤器不匹配的数据。

所以Druid使用三种不同的技术来最大化查询性能:

外部依赖

深度存储

Druid仅将深度存储用作数据的备份,并将其作为在Druid进程之间在后台传输数据的一种方式。要响应查询,历史进程不会从深层存储读取,而是在提供任何查询之前从其本地磁盘读取预取的段。这意味着Druid在查询期间永远不需要访问深层存储,从而帮助它提供最佳的查询延迟。这也意味着您必须在深度存储和整个历史进程中拥有足够的磁盘空间来存储您计划加载的数据。

有关更多详细信息,请参阅深层存储依赖性

元数据存储

元数据存储保存各种系统元数据,例如段可用性信息和任务信息。

有关更多详细信息,请参阅元数据存储依赖性

动物园管理员

Druid使用ZooKeeper(ZK)来管理当前的集群状态。

有关更多详细信息,请参阅Zookeeper依赖项