druid内部节点先容:
- Historical: 汗青节点的职责重要是对汗青的数据举行存储和查询,汗青节点从Deep Storage下载Segment,然后相应Broker对于Segment的查询将查询效果返回给Broker节点,它们通过Zookeeper来声明本身存储的节点,同时也通过zookeeper来监听加载或删除Segment的信号。
- Coordinator:调和治点监测一组汗青节点来包管数据的可用和冗余。调和治点读取元数据存储来确定哪些Segment须要load到集群中,通过zk来感知Historical节点的存在,通过在Zookeeper上创建entry来和Historical节点通讯来告诉他们加载大概删除Segment。
- Overload: 统治节点,管理数据写入任务。
- Broker:节点吸取外部客户端的查询,而且将查询路由到汗青节点和实时节点。当Broker收到返回的效果的时间,它将效果merge起来然后返回给调用者。Broker通过Zook来感知实时节点和汗青节点的存在。
- Indexing Service: 索引服务是一些worker用来从实时获取数据大概批量插入数据。Realtime:获取实时数据。
- Tranquility: 是一个以push方式向Druid实时发送数据的应用。它替用户管理了分区、多副本、服务发现、防止数据丢失等多个标题,简化了用户利用Druid的难度。它支持多种数据泉源,包罗Samza、Spark、Storm、Kafka、Flink等等。
- Router:它用于把查询路由到差别的Broker,实现Broker层面的查询隔离,比方把热数据查询路由到指定的Broker聚集,把不告急的查询路由到剩下的Broker聚集。这种隔离在某些场景下非常有效,比方某些不告急的查询耗时过长,会影响其他告急查询的环境。当数据量没到达TB级别,大概对隔离Broker层面的查询没有急迫需求时,不保举利用Router。
Druid数据结构:
- Data Source:Druid的根本数据结构,在逻辑上可以明确为关系型数据库中的表。它包罗时间、维度和指标三列。
- Segment:Druid用来存储索引的数据格式,差别的索引按照时间跨度来分区,分区可通过segmentGranularity(分别索引的时间粒度)举行设置。
外部组件:
- Zookeeper集群
- 元数据存储实例:Mysql
- Deep Storage:HDFS
druid借助lambda头脑,很好的管理了实时处置处罚逻辑会抛弃时间窗口以外的数据的标题。
- 实时:通过tranquility拉取数据并导入druid
- 离线:通过druid提供的Hadoop Indexer(现实上是mr任务)获取hdfs数据,天生segment并导入hdfs,并将索引元信息导入mysql。druid定时轮询mysql并获取最新索引数据,末了通过指定负载平衡算法分配给工作节点
依赖
tranquility(4c8g120gx9)
/data/tranquility/config目次存储了许多json文件,界说了数据源的schema,也就是druid表结构,全部schema中设置的segmentGranularity都是hour级别, queryGranularity有hour也有minute级别
告急参数
segmentGranularity不即是queryGranularity
- segmentGranularity:索引粒度,也就是一个segment文件包罗的数据时间范围
- queryGranularity:查询粒度,也就是最小聚合粒度,代表数据存储的时间,在维度类似的环境下,同一查询粒度范围内的数据会主动被聚合,导致查询的时间只能查到该粒度级别的数据
- intermediatePersistPeriod:定时长期化增量索引的周期,现在大多是5min
- windowPeriod:时间窗口,表现假如数据时间比当前时间老大概比当前时间新,高出该窗口范围之外的全部被抛弃,现在大多是10min,也有5min
保举设置:intermediatePersistPeriod ≤ windowPeriod < segmentGranularity,queryGranularity<= segmentGranularity
tranquility工作流程:
tranquility会做两件事:
- 创建索引任务并发给overlord:tranquility发送的task会被overlord担当,末了会占用middle-manager的一个空闲slot。为防止太多task,tranquility会为同一个segmentGranularity范围之内的task分配同一个id,这个全部发送已往的task都会被归并。另有两个设置项影响task数目,tranquility可以在schema中为每个数据源设置partitions和replicants,一个小时以内哀求的task数目= partitions * replicants。现在middle-manager的全部slot数目都可以在overlord UI查察,可以根据剩余slot数目来修改设置中的partitions和replicants参数。创建的task重要目的是明确每个tranquility该往哪个peon发送实时数据,即实时数据在浩繁peon中负载平衡的计谋(稍后讨论handoff阶段)
- 将实时数据发送给peon进程:peon会通过EventReceiverFirehose服务袒露一个http接口,tranquility通过zookeeper获取task的分配信息,明确实时数据该往哪个peon发,并将peon袒露的接口发起post哀求,提交实时数据
内部组件
indexing service
- overlord(4c8g120gx2):吸取tranquility哀求的实时索引task,选择slot空闲最多的middle-manager,通过zk将task分配给middle-manager,填满为止。现在overlord两台呆板,master-slave结构
- middle-manager(4c8g120gx51):通过zk获取task,启动当地进程peon实行task
- peon:获取实时数据,实行task,完成索引创建。peon本身还负责索引查询服务
index service吸取tranquility哀求并处置处罚的整个流程:
peon完成了索引build,merge,handoff的整个生命周期
每个middle-manger有N个slot,对应N个peon,每次分配一个索引task就会创建一个peon进程,这个小时以内peon会占据这个slot,等完成handoff之后才开释
这个小时以内,peon会不绝天生增量索引,定时长期化索引,归并索引天生segment,末了handoff segment
handoff流程:
historical
historical提供索引加载和查询服务
汗青节点在从下载segment前,会从当地缓存查抄是否存在,假如不存在才从hdfs下载。下载完成之后,会根据zk获取到的压缩信息举行解压处置处罚并加载到内存,这时就能提供查询服务。
可以通过设置给汗青节点分别差别的层,然后在coordinator设置规则来加载指定命据源到某个层。如允许以实现冷热数据分别处置处罚,热数据查询多存量小,接纳更好的cpu和内存机型设置,冷数据查询少存量大,接纳更大的硬盘机型设置
broker
broker负责查询索引,现在是master-master结构
broker是查询节点,负责担当查询哀求,分析查询对象中的时间范围,根据时间范围将实时索引哀求(当前小时)路由到peon节点,将汗青索引哀求(1小时之前)路由到historical节点。吸取peon和historical查询返回的数据,在做一次归并,末了返回效果
为了进步查询服从,broker会将查询效果缓存(LRU),现在提供了两种方式:
- heap memory(现在利用)
- kv存储,如memcached
只会缓存汗青节点返回的数据,由于peon返回的实时数据经常改变,没有缓存的代价
coordinator
coordinator会调和汗青节点中segment的分配
- rules:每分钟从mysql拉取druid_rules和druid_segments,rules用来告知historical将怎样load和drop索引文件,coordinator会读取这些rules,然后修改zk,关照historical加载删除指定的segment,这些都可以在coordinator的UI设置
- load balance:根据zk中每个historical node负责的segment量,做负载平衡
- replication:在coordinator的UI中设置rules时,可以同时设置加载segment的备份数目,这些备份数目会以load balance的情势,分配到多个historical上面。这个备份数目与hdfs的segment备份数目不一样,hdfs谁人包管深度存储的数据不会丢失,historical上面备份是为了包管当某个historical挂掉的时间,其他存储了备份segment的节点能接着提供查询服务
外部依赖
zookeeper
druid依赖zk实现集群之间的交互
druid接纳shard-nothing架构,每个节点之间不直接和其他打交道,而是接纳zk来沟通。如许包管了druid本身的HA特性
peon和historical发布索引
- /druid/announcements:声明全部peon和historical的host
- /druid/segments:纪录全部peon和historical的host,以及他们负责的索引
提供indexing service相干数据(overlord页面数据泉源)
- /druid/indexer
- leaderLatchPath:overlord选主
- tasks:运行的peon任务
- status:peon任务状态
- announcements:声明middle-manager的capacity
coordinator用来关照historical加载卸载索引
- /druid/loadQueue/_historical_host/_segement_id:纪录汗青节点所负责的segment
coordinator选主
- coordinator:纪录coordinator信息
集群通讯
附属功能
- /druid/listeners:存储lookup数据
deep storage —— hdfs
存储索引文件
存储元数据
- druid_segments:索引元数据,数据源、是否可用、巨细、维度、指标
- druid_rules:关照historical该怎样加载、卸载索引的规则,可以在coordinator设置
- druid_config:存放运行时设置信息
- druid_audit:纪录设置、规则的变革
- druid_task(相干的几张表):overlord用来存放索引task数据,防止overlord挂掉导致task丢失
索引文件
segment就是压缩后的索引文件,定名方式为datasource_intervalStart_intervalEnd_version_partitionNum。如dsp_report_2011-01-01T01:00:00Z_2011-01-01T02:00:00Z_v1_0,代表dsp_report数据源,从2011-01-01那天1点到2点的数据,版本号为v1,分区数为0
深入分析segment存储结构
- version.bin:4字节,纪录segment version
- XXXXX.smoosh:该文件存放多个逻辑意义上的子文件,通过纪录offset来管理这些子文件。有的子文件存放了column信息,有的存放了索引元信息。column信息也就是真实存储的数据
- meta.smoosh:上面这些子文件名称以及他们出现的offset都纪录在meta.smoosh中
XXXXX.smoosh中存放的column是最告急的,可以分为Timestamp, Dimensions, Metrics三部分。
timestamp
|
domain
|
advertiser
|
device
|
city
|
click
|
cost
|
---|
2015-11-25T10:00:00Z |
youku.com |
BMW |
Android |
Peking |
9 |
0.9 |
2015-11-25T10:00:00Z |
youku.com |
BMW |
Iphone |
HongKong |
3 |
0.3 |
2015-11-25T10:00:00Z |
tudou.com |
PANDORA |
Iphone |
HongKong |
2 |
0.2 |
2015-11-25T10:00:00Z |
tudou.com |
PANDORA |
Iphone |
Peking |
1 |
0.1 |
- Timestamp:用时间戳来表现时间,可以用一系列时间戳表现该segment全部Timestamp列信息,接纳LZ4算法压缩
- Metrics:也是数字,存放方法同上,压缩算法同上
- Dimensions:由于Dimensions大多是字符串,接纳上面的存放方式无法很好压缩。现在Dimensions拆分成多个结构举行存储。
Dimensions结构:
- 将字符串映射为整数id的字典
- 纪录该dimension每一行的值,值用上述字典编码
- 为每个差别dimension的值,界说一个bitmap,存储该值出现的行号,接纳roaring压缩算法
上述结构中,1可以有效淘汰索引文件的巨细,2的底子上做排序可以很方便的做groupby归并处置处罚,3是快速完成where条件查询的利器。
内存管理
druid利用了三种差别范例的内存:
- 堆内存:broker用来缓存查询效果、简朴盘算
- 直接内存:一样寻常用来存储聚合操纵中所产生的临时数据
- MMap:汗青节点用来加载segment,快速,淘汰一次体系复制操纵。memory_for_segments = total_memory - heap - direct_memory - jvm_overhead,segment可用的内存越小,mmap操纵就会导致更多的内存换页操纵
! |