数据结构
- DataSource(类似于表)
- 时间列:表明每行数据的时间,默认使用UTC并精确到毫秒
- 维度列:来自于OLAP概念,标识类别信息
- 指标列:用于聚合和计算的列,通常是一些数字
支持对任意指标列进行聚合(Roll Up)操作,如同维度列聚合或指定时间粒度的聚合。在存储时就对数据进行聚合是Druid的特点,可以节省存储空间,提高查询效率
- Segment结构
- 通过对segmentGranularity的设置,将不同时间范围的数据存储在不同Segment数据块中;查询数据仅需访问对应时间段内的数据块,效率极大提高。
- 提供面对列的数据压缩存储,并使用Bitmap等技术对访问进行优化
实时节点
实时节点主要负责实时数据摄入,生成Segment数据文件;
Segment文件的制造和传播
- 实时节点通过Firehose来消费实时数据
- 实时节点通过Plumber来生成数据文件,并将多个数据块合并成一个大的Segment
Segment文件的传播过程见上篇
高可用和可扩展性
可以使用一组节点组成Group共同消费一个Topic,使得每个分区不会被多余一个实时节点消费。当节点会主动将Offset提交到ZK,这样能实现节点失败重分配,同时保证了实时扩展性。
为了避免挂掉的节点已消费但未上传的数据丢失,可以采用以下方法
– 使得挂掉的节点恢复,重启时节点会加载所有尚未上传的Segment文件,保证数据完整
– 使用Tranquility和索引服务对Topic进行精确消费和备份。
历史节点
- 启动时,先检查本地已有的Segment文件,并从DeepStorage中下载属于自己但不在本地的Segment数据文件
- 查询时,现将Segment文件加载到内存再提供查询
- 历史节点的查询苏武与内存空间大小和负责的Segment数据文件大小之比 成正比
层的分组功能
- 数据温度用来描述数据被访问的频繁程度
- 热数据:经常被访问,数据量不大,要求最高响应
- 温数据:不常被访问,数据量中等,要求尽可能快
- 冷数据:偶尔被访问,数据量大,不要求响应速度
- Druid提出层(Tier)的概念,将历史节点根据性能容量分为不同的层,并且可让不同性质的DataSource使用不同的层来存储Segment
高可用和扩展
- 新的历史节点添加后会通过ZK被协调节点发现,协调节点会自动分配Segment给他
- 历史节点被移除后同样被协调节点发现,并将原本分配给这个节点的Segment分配给其他可用节点
查询节点
一般情况下,Druid集群对外提供服务的只有查询节点,查询节点会将实时节点和历史节点查询到的数据合并后返回客户端
缓存
Druid支持使用Cache机制来提高查询效率;查询时首先访问Cache,不命中时才会去访问数据
- 外部Cache,如Memcached
- 内部Cache,查询节点或历史节点的内存
高可用
可以使用如Nginx来完成对多个查询节点的负载均衡,以实现高可用
协调节点
协调节点负责历史节点的数据负载均衡和通过规则管理数据生命周期
数据负载均衡
对于历史节点来说,协调节点类似于他们的Master,协调节点会给历史节点分配数据,来达到数据负载均衡。当协调节点挂掉时,历史节点可以提供查询服务,但是不能接收新的Segment
管理生命周期
协调节点会根据DataSource配置的规则对于每个Segment文件逐条检查,当符合规则时就立即命令历史节点执行这个命令(加载或丢弃)
高可用性
默认情况下,从历史节点挂掉到协调节点重新分配这个节点上的Segment文件到其他历史节点的这段时间内,挂掉节点上的数据是不可访问的;但是可以通过增加副本的方式在多个历史节点上存储同一份数据来保障高可用
索引服务
索引服务也可以产生Segment文件,支持pull,push模式方式,可通过API编程的方式来灵活定义任务配置,并完成跟Segment相关的所有操作
主从架构
索引服务包含统治节点为主节点,中间管理者节点为从节点
统治节点
负责对外接收任务请求,对内将任务分解并下发到从节点上;统治节点提供RESTful的访问方法,可以通过HTTP请求提交任务或查看任务状态。统治节点有以下两种运行模式
- 本地模式:统治节点不止负责集群任务协调分配,也能启动一些苦工(peon)来完成具体工作
- 远程模式:统治节点和中间管理者运行在不同节点上,此时统治节点仅完成集群任务协调分配。
中间管理者&苦工
中间管理者就是索引服务的工作节点,负责接收统治节点分配的任务,并启动相关苦工(独立的JVM)来完成任务
Druid | Yarn | 功能 |
---|---|---|
统治节点 | ResourceManager | 集群资源管理和任务分配 |
中间管理者 | NodeManager | 管理独立节点的资源并接受任务 |
苦工 | Container | 在具体节点上完成具体任务 |