Druid数据规划

简介: ## 数据规划 Druid索引好的数据放在Historical中,随着数据规模的扩大,分离数据的需求逐渐变得迫切。Druid提供了Tier机制与数据加载Rule机制,通过它们能很好的将数据进行分离,从而达到灵活的分布数据的目的。 #### Tier机制 Tier机制的作用是将Historical节点进行分组。默认情况下所有的Historical节点属于语默认的“_default_

数据规划

Druid索引好的数据放在Historical中,随着数据规模的扩大,分离数据的需求逐渐变得迫切。Druid提供了Tier机制与数据加载Rule机制,通过它们能很好的将数据进行分离,从而达到灵活的分布数据的目的。

Tier机制

Tier机制的作用是将Historical节点进行分组。默认情况下所有的Historical节点属于语默认的“_default_tier”分组。但是我们能通过Historical配置文件中的“druid.server.tier”参数来指定分组。另外请注意Tier只针对Historical节点,而与datasource无关。

Tier in Historical nodes

数据加载Rule机制

设置了Tier之后,再给Tier添加对应的数据加载Rule,就能实现数据分离的目的。数据加载Rule机制是进行数据分离的基础,也是本文的重点。

Rule主要分两大类Load与Drop,每个大类有细分为Period、Interval和Forever三种。其中Period的意思是最近的一段时间,比如最近一天,随着时间的推移这段时间内的数据也会更迭。Interval和Forever分别指固定时间段与整个数据源的生命周期。

与Tier不同,Rule都是针对datasource的。比如我们给datasource1设置了一些Rule,这些Rule只针对datasource1的数据生效,对其它datasource没有影响。

Druid应用Rule遵循两个原则:(1)按顺序;(2)数据只能应用一条Rule。为了更好的解释它们,请看以下示例:

Apply rules to each tiers

上例中分别应用了三条Rule到三个Tier中,这三条Rule组合后的意思是:将最近一天的数据加载到hot分组中,后两天的数据加载到cold分组中,剩下的数据加载到default分组中。

第一天(当前天)的数据很好理解应用Rule1,数据被加载到hot分组所在的Historical中。因为第一天的数据已经被应用了Rule1,所以Rule2对第一天的数据失效,所以只有第二第三天的数据被加载到cold分组的Historical中。同理前三天的数据已经应用了Rule,只有剩余的数据应用Rule3,加载到了default分组的Historical中。

随着时间的推移,新的一天的数据变成了第一天,它们被加载到hot分组的Historical中,老的第一天数据被迁移到cold分组的Historical中,同理cold分组前移一天的数据到default分组的Historical中。

Interval类型的Rule很好理解不做过多的解释。以上是Druid提供的Tier与Rule机制,它们对管理规划Druid中的数据提供了基础。下面我们从几个生产环境中很可能出现的场景讨论如何对Druid中的数据进行规划。

冷热数据分离

对于大部分业务来说用户关注的焦点都在最近一段时间内,也就是对一个较长时间段内的数据来说,数据是分冷热的,我们需要做的是尽量保证热数据的高效查询。

而对于Druid来说查询的高效与否有两个很重要的因素:(1)机器配置,主要是CPU与内存;(2)操作系统buffer内存与数据量的比例。在考虑机器成本的前提下,如果我们把这两项资源更多的倾向于热数据,那么对查询效率的提升应该是显而易见的。到此我们已经明确了需求与大概思路,下边看具体如何解决。

首先看第一点将最近的热数据放在配置较好的机器中,冷数据放在较差的机器中。我们将Historical进行分组:一组为"hot"(配置较好的机器,打算存放最近的热数据);另一组为"_default_tier"(配置较差的机器,打算存放冷数据)。然后配置如下规则,以将冷热不同的数据加载到对应的Historical中。

{"type":"loadByPeriod","tieredReplicants":{"hot":1},"period":"P1D"} //load recent 1 day data into hot tier
{"type":"loadForever","tieredReplicants":{"_default_tier":1}} //load the rest data into _default_tier tier

Druid内部采用Json的形式来表示,这里约定下文的Rule也都采用Json的形式。但是我们给datasource设置Rule的时候是通过coordinator的web console界面完成的。

再来看第二点,Druid使用操作系统buffer机制来减少磁盘IO,从而加速查询。Historical能配置自己本地缓存数据使用磁盘最大容量,这是一个很重要的参数,存放冷数据的Historical机器需要一个较大值以存放较多的数据。同样该参数能通过Historical的配置文件指定:

druid.segmentCache.locations=[{"path":"/path/to/druid/segment/cache","maxSize"\:300000000000}]

备份数据分离

为了保证查询服务的高可用性,Druid提供了数据replication机制。考虑到生产环境中机器的共性,比如是否在同一机架上,如果机架故障或断电这一批机器将不可用。出于可用性考虑,可能有将数据分布到两批机器上的需求。为此首先需要将两批机器配置成不同的Tier。然后配置如下Rule:

{"tieredReplicants":{"tier_1":1, "tier_2":1},"type":"loadForever"}

业务数据分离

默认情况下所有的Historical节点都在“_default_tier”中,所有的datasource都公平的使用机器资源。在机器资源有限的情况下,需要优先保证重要业务的查询。为此可以将业务进行分离,重要业务分配较多的机器资源。思路同上首先进行分组,在配置Rule:

{"tieredReplicants":{"tier_1":2},"type":"loadForever"}  // for important datasources
{"tieredReplicants":{"tier_2":2},"type":"loadForever"}  // for normal datasources

加载部分数据

Druid的使用场景多是一些报表类业务,报表具有很强的时效性,很多场景都只关注最近一段时间的数据,所以为了更充分的利用资源,可以将不关注的数据从Druid中剔除出去。我们可以配置如下Rule:

{"type":"loadByPeriod","period":"P3D","tieredReplicants":{"_default_tier":2}}
{"type":"dropForever"}

上例的两个Rule保留最近3天的数据,其它的则从Druid(也就是Historical)中删掉。删掉的只是Druid本地缓存的数据,Deep Storage中的数据没有删掉。所以有一天删掉这两个Rule,Druid又会将数据加载回来。特别注意这两个Rule的顺序,反过来的话会删掉Druid中所有的数据。

数据分离对查询效率的影响

Druid对数据进行查询的优化有两个基本的点。第一在内存利用上充分利用操作系统Buffer减少IO操作;第二在架构上采用分布式查询树架构,以增加查询的并行性。以下尝试分别从内存利用与架构两个方面对比数据分离与不分离对查询的影响。

首先架构方面,Druid采用的分布式查询树有点类似下图:

Query in Druid

Broker节点接收到客户端的请求后,同是分发请求到相应的多个Historical节点,Historical节点首先本地查询并聚合一次数据,发送到Borker节点,Broker节点再次聚合多个Historical节点发送过来的数据,并最终返回给客户端。在整个请求处理过程中,Historical节点本地查询数据环节占用大部分时间,所以尽量多的增加Historical节点的并行度能有效缩短查询时间。

为了达到增加查询并行度的目的,Druid尽量将时间上连续的Segment分散到不同的Historical节点中,算法细节可以查看github上相关文档。但是如果将数据进行分离,就减小了查询时候Historical的并行度。

所以就提高Historical查询并行度角度来说,分离数据后查询效率是要降低的。

再来看内存利用方面,将查询热度最高的数据放到内存中能保证最优的整体查询效率,由于操作系统Buffer采用LRU机制淘汰数据,所以它本身就保证了热数据常驻内存的原则。如果人为将数据进行切割,如果切割得当还好,否则破坏了这个原则,对查询效率是有影响的。

随着业务与数据的增加,分离数据的需求在特定场景下是有的。但是分离数据后对查询效率是有影响的,尤其在集群规模小的情况下,影响可能会较大,所以分离数据的时候需要谨慎。

写在最后

以上是本人在使用Druid过程中,对数据规划方面的一点认识,由于水平有限,如有问题欢迎指正。

目录
相关文章
|
11月前
|
存储 消息中间件 druid
Druid 架构原理及核心特性详解
Druid 是一个分布式、支持实时多维OLAP分析的列式存储数据处理系统,适用于高速实时数据读取和灵活的多维数据分析。它通过Segment、Datasource等元数据概念管理数据,并依赖Zookeeper、Hadoop和Kafka等组件实现高可用性和扩展性。Druid采用列式存储、并行计算和预计算等技术优化查询性能,支持离线和实时数据分析。尽管其存储成本较高且查询语言功能有限,但在大数据实时分析领域表现出色。
2468 19
|
Arthas 消息中间件 监控
记一次SSL握手导致业务线程阻塞的案例分析
记一次SSL握手导致业务线程阻塞的案例分析
464 0
|
机器学习/深度学习 人工智能 IDE
Cursor免费 GPT-4 IDE 工具的保姆级使用教程
本文介绍了Cursor这一基于人工智能技术的代码生成工具,包括其特点(利用自然语言处理和深度学习算法,可生成高质量代码,支持多种编程语言,能在多种操作系统上运行)及使用教程。教程内容涵盖下载(通过官网获取对应系统版本并安装)、初始化配置(如配置快捷键、AI指定语言,导入VS Code扩展,设置数据偏好,登录/注册)、安装插件(设置Cursor中文、配置gitee)、配置模型和Key(选择模型、配置密钥、自定义模型并进行测试)以及如何使用(打开提示词面板)等步骤。
12441 6
 Cursor免费 GPT-4 IDE 工具的保姆级使用教程
|
数据可视化 Java 测试技术
JMeter 如何实现 Elasticsearch 8.X 性能测试?
JMeter 如何实现 Elasticsearch 8.X 性能测试?
|
缓存 安全 数据库连接
sqlsession对象为什么不能被共享?
sqlsession对象为什么不能被共享?
192 0
|
Java
线程 - 一句话说明白 Java 线程池中 shutdown 和 shutdownNow 的区别
线程 - 一句话说明白 Java 线程池中 shutdown 和 shutdownNow 的区别
884 0
|
存储 缓存 固态存储
深入探讨LSM Compaction机制
compaction在以LSM-Tree为架构的系统中是非常关键的模块,log append的方式带来了高吞吐的写,内存中的数据到达上限后不断刷盘,数据范围互相交叠的层越来越多,相同key的数据不断积累,引起读性能下降和空间膨胀。因此,compaction机制被引入,通过周期性的后台任务不断的回收旧版本数据和将多层合并为一层的方式来优化读性能和空间问题。而compaction的策略和任务调度成为新的难题,看似简单的功能,实则需要各方面的权衡,涉及空间、I/O、cpu资源和缓存等多个层面。这篇文章将从compaction策略、挑战、几个主流lsmtree系统的实现和学术上的研究几个方向来探讨
4466 1
深入探讨LSM Compaction机制
|
存储 JSON Oracle
【最佳实践】esrally:Elasticsearch 官方压测工具及运用详解
由于 Elasticsearch(后文简称 es) 的简单易用及其在大数据处理方面的良好性能,越来越多的公司选用 es 作为自己的业务解决方案。然而在引入新的解决方案前,不免要做一番调研和测试,本文便是介绍官方的一个 es 压测工具 esrally,希望能为大家带来帮助。
20055 0
【最佳实践】esrally:Elasticsearch 官方压测工具及运用详解
|
算法 Java 测试技术
Java随机算法(一)(r11笔记第14天)
问:如何生成一个随机的字符串?答:让新手退出VIM 。 生成一个随机数看起来很简单,一直以来却深知它的不易,怎么让一个确定的值得到一个不确定的值,这个想起来都有点困难,而且这部分内容,自己也花了些时间去看Java源码,结果发现远比自己琢磨的要复杂的多,加上也有些日子没写过Java代码,可谓是困难重重,写了一小部分的总结发现,竟然有很多不大理解的地方。
1882 0