主要特性:
Druid当前允许以类似 Dremel 和PowerDrill的方式单表查询,但也增加了一些新特性。
就系统而言,Druid功能位于PowerDrill和Dremel之间。它实现几乎所有Dremel提供的工具(Dremel处理任意嵌套数据结构,而Druid只允许一个基于数组的嵌套级别)并且从PowerDrill吸收一些有趣的数据格式和压缩方法。 Druid对于需要实时单一、海量数据流摄取产品非常适合。特别是如果你面向无停机操作时,如果你对查询查询的灵活性和原始数据访问要求,高于对速度和无停机操作,Druid可能不是正确的解决方案。在谈到查询速度时候,很有必要澄清“快速”的意思是:Druid是完全有可能在6TB的数据集上实现秒级查询。 架构:Druid是由不同角色的系统构建而成的一个整体系统,它的名字来自在许多角色扮演游戏中的Druid类:它是一个shape-shifter,可以在一个群组中采取许多不同的形式来满足各种不同的角色。 Druid的整体架构中目前包括以下节点类型: Historical 节点是对“historical”数据(非实时)进行处理存储和查询的地方。historical节点响应从broker节点发来的查询,并将结果返回给broker节点。它们在Zookeeper的管理下提供服务,并使用Zookeeper监视信号加载或删除新数据段.。 Realtime节点实时摄取数据,它们负责监听输入数据流并让其在内部的Druid系统立即获取,Realtime节点同样只响应broker节点的查询请求,返回查询结果到broker节点。旧数据会被从Realtime节点转存至Historical节点。 Coordinator 节点监控historical节点组,以确保数据可用、可复制,并且在一般的“最佳”配置。它们通过从MySQL读取数据段的元数据信息,来决定哪些数据段应该在集群中被加载,使用Zookeeper来确定哪个historical节点存在,并且创建Zookeeper条目告诉historical节点加载和删除新数据段。 Broker 节点接收来自外部客户端的查询,并将这些查询转发到Realtime和Historical节点。当Broker节点收到结果,它们将合并这些结果并将它们返回给调用者。由于了解拓扑,Broker节点使用Zookeeper来确定哪些Realtime和Historical节点的存在。 Indexer 节点会形成一个加载批处理和实时数据到系统中的集群,同时会对存储在系统中的数据变更(也称为索引服务)做出响应。 这种分离让每个节点只关心自身的最优操作。通过将Historical 和Realtime分离,将对进入系统的实时流数据监控和处理的内存分离。通过将Coordinator和Broker分离,把查询操作和维持集群上的“好的”数据分布的操作分离。 下面的关系图显示了架构中的查询和数据流,以及和哪个节点相关: 除了这些节点,系统还有3个外部依赖:
下面的图说明了集群的管理层,展示特定的节点和依赖如何通过跟踪和交换元数据来帮助管理集群: 数据存储获取数据到Druid系统需要一个索引进程,如上面图所示。这给系统一个机会,为了优化查询速度,分析数据,添加索引结构,压缩和调整布局。
LZF (切换到Snappy尚未实现)索引过程的输出存储在一个LOB存储系统中,数据被Historical节点加载,首先是通过将数据下载到它们的本地磁盘,然后在服务查询之前内存映射它。 如果Historical节点死亡,它将不再服务它的数据,但考虑到数据仍可以在“deep storage”中获取,任何其他节点只需下载数据,就可以开始服务。这实际上意味着可以从集群中删除所有的Historical节点,然后重新指配给它们,而没有任何数据丢失。 为了使数据存在于集群内部,一个条目必须被添加在一个MySQL实例表中。这个条目是关于数据的自描述元数据,包括诸如数据段的模式、大小以及在“deep storage”中的位置等。 容错Historical正如上面所讨论的,如果一个historical节点死亡,另一个历史的节点可以取而代之,不用担心数据丢失。 Coordinator可以运行在一个热故障转移配置上。如果没coordinators在运行,然后数据拓扑将停止变化,但该系统将继续运行。 Broker可以并行或在hot fail-over上运行。 Realtime取决于delivery流的语义,它们可以并行运行处理完全相同的流。它们定期检查磁盘并最终推送到Historical节点,并且可以采取措施恢复死亡进程,如果访问本地磁盘是将数据添加到系统的唯一方式,那么如果失去本地磁盘的访问可能导致数据丢失。 “deepstorage”文件系统如果不可用,新数据将无法进入集群,但集群将继续按原来方式操作。 MySQL如果不可用,Coordinator将无法找出系统中的新segment,但原有的数据仍然可以被查询到。 ZooKeeper如果不可用,数据拓扑结构改变将不能进行,但Broker将相应的保持它们最新的数据拓扑视图和持续服务请求。 查询处理一个查询首先进入Broker,Broker将查询与已知存在的数据段匹配。然后选择一组服务那些segment的机器,并且为每个服务器重写查询来指定目标segment。Historical/Realtime节点将查询、处理、并返回结果。Broker然后将结果合并在一起,得到最终的它返回的结果。通过这种方式,broker可以在看到行数据之前删除所有与查询不匹配的数据。 对于在更高细粒度水平的filter,每个segment内部的索引结构在看到任意行数据之前,允许historical节点找出哪些(如果有的话)行匹配filter组。它可以在位图索引做所有的filter boolean algebra,并且从来没有直接看到一行数据。 一旦知道行与当前查询相匹配,它可以直接访问它关心的列,而无需加载其它数据。
In-memory?Druid并不总是以及只在内存。当我们第一次构建它时,它始终是全内存的,但随着时间的推移,将所有客户数据保持在内存中是行不通的。然后,我们增加了内存映射数据能力以及允许操作系统处理页面数据在内存里外的需求。我们的production集群主要用来配置内存映射行为的操作。(编译/魏伟 审校/周小璐) 更多介绍请点击Druid官网: Druid |