Druid把它的索引存储在segment的文件中,segment是以时间进行分区的。在基本的设置中,segment文件是根据一定的时间间隔创建的,通过granularitySpec中的 segmentGranularity参数来配置时间间隔。为了使Druid在繁重的查询压力下正常运行,设置segment文件的大小在300MB~700MB之间是非常重要的。如果我们的segment文件大于这个范围,需要考虑改变时间间隔的粒度或者对数据进行分区并在我们的partitionsSpec里面调整targetPartitionSize参数(这个参数的比较好的起始点是5百万行)。详细信息查看下面的分片部分和 Batch ingestion 的 分区说明部分
segment文件的核心数据结构
我们描述一下segment文件的内部结构,它本质上是列式存储:每一列的数据都在不同的数据结构中布局。通过分别存储每一列,Druid可以通过只扫描查询实际需要的列来减少查询延迟。有三种基本的列类型:时间戳列,维度列,指标列,例如:

时间戳和指标列非常简单:在幕后,每一个都是用LZ4压缩的整数或浮点值数组。一旦一个查询知道哪些行需要被查询,它只需要进行简单的解压,拉取相关的行,然后应用期望的聚合操作。如果查询不需要某一个列,则这个列的数据就会被跳过。
维度列不一样的原因是它们需要支持过滤和分组操作,因此每个维度都需要以下三种数据结构:
1、需要一个字典来映射值(这些值被当做字符串对待)到整形的ID
2、使用字典进行编码的列值的一个列表
3、对于列的不同的值,使用bitmap来表明哪一行包含这个值

为什么需要这三种数据结构呢?通过字典来把字符串映射到整形,从而能紧凑的表达2和3;3中的bitmap非常方面的应用于 and 和 or 操作。数据结构2中的列表的值用来做分组和topN查询的。换句话说,基于过滤器的聚合指标查询不需要涉及到数据结构2中存储的维度值。

我们使用上面例子中的page列来直观的感受一下这些数据结构,这个维度列的三种数据结构展示如下:
1、经过字典编码的列数据:

"Justin Bieber": 0, 
"Ke$ha": 1 
}

2、列数据:
[0,
 0, 
1, 
1]
3、bitmap:列的每个唯一值对应一行
value="Justin Bieber": [1,1,0,0] --第一行和第二行存在,第三行和第三行不存在这个值。
value="Ke$ha": [0,0,1,1]

需要注意的是,bitmap与前两个数据结构不同,前两个数据结构在数据大小上呈线性增长(在最坏的情况下),而bitmap的大小是数据的大小乘以列的基数。不过呢,我们可以采用压缩算法,我们知道对于每一行的列数据,只有一个非零项的bitmap。这意味着高基数列将具有非常稀疏的,高度可压缩的位图。Druid使用特别适合位图的压缩算法( roaring bitmap压缩)来利用这一点。

多值列
如果一个DataSource使用了多值列,那么segment 文件的数据结构看起来会有一点不同。让我们想象一下上面的例子,如果第二行同时拥有'Ke$ha' 和 'Justin Bieber' 值,在这种情况下,这三种数据结构看起来就像下面展示的:
1、经过字典编码的列数据:
{ "Justin Bieber": 0, "Ke$ha": 1 }

2、列数据:
[0,
 [0,1], <--多值列在行里面存储多个值的数组
1, 
1]

3、bitmap 每一个代表唯一值
value="Justin Bieber": [1,1,0,0] 
value="Ke$ha": [0,1,1,1] ——多值列有多个非零项

注意:主要的不一样的地方就是第二行的列数据 和Ke$ha的bitmap。如果行里面存在多余一个值的列,它将会以数组的形式保存在列数据里面,另外,行里面的列数据存在N个值将会有N个非零项在bitmap里面。

SQL兼容的null处理
默认情况下,druid的字符串维度列中''和null是可以互换使用的,数值列和指标列不能出现null,如果出现会强制转换成0.然而druid提供了SQL兼容的null处理模式,它必须通过配置项druid.generic.useDefaultValueForNull在系统级别进行开启。当它设置为false的时候,druid在进行摄入的时候创建的segment会对字符列的''和null进行区分,同样数字列可以使用null而不是0.
在这种模式下,字符串维度列不包含额外的列结构,而只是为null保留额外的字典条目。数值型列需要在segment添加额外的bitmap来表示存在null的行。这会稍微增加segment的大小。SQL兼容的null处理也会在查询的时候带来性能损耗,因为需要检查null的bitmap。当然这个性能损耗只会发生在列实际包含null的值的时候。

命名约定
segment的标识由segment的DataSource、间隔的开始时间(iso 8601格式)、间隔的结束时间(ISO 8601格式)和一个版本号组成。如果数据需要根据时间范围分片的话,segment的标识还会包含一个分片数字。
segment的标识类似这样:datasource_intervalStart_intervalEnd_version_partitionNum

segment的组件
在幕后,一个segment有好几个文件组成,清单如下:
1、version.bin
使用4字节的整数来表示当前segment的版本,比如v9 segment,版本就是0x0, 0x0, 0x0, 0x9
2、meta.smoosh
元数据文件,存储了其他smoosh文件的内容(文件名和偏移量)
3、xxxxx.smoosh
一系列连续的二进制文件
这些smoosh文件表示多个文件顺序的放在一起以最小化文件描述符(用来打开存储的数据)的数量。这些文件最大是2GB(匹配java的bytebuffer的内存限制)。对于每个列,smoosh文件都是使用单独的文件进行数据的存储,以及一个index.drd文件,其中包含有关该段的额外元数据。
还有一个称为“__time间”的特殊列,它引用段的时间列。随着代码的发展,这可能会变得越来越不特别,但现在它就像我妈妈一直告诉我的那样特别。
在代码库中,segment具有内部格式版本。当前段格式版本是v9。

列的格式
每个列都会存储两部分内容:
1、json的列描述
2、剩下的就是列的二进制数据
列描述本质上是一个对象,它允许我们使用json多样化的反序列化来最少化的代码影响去添加新的和有趣的序列化方法。它包含一些列的元数据(它的类型,是不是多值……)和可以反序列化剩余的二进制数据的序列化和反序列化的逻辑

创建segment的时候分片
分片
同一个DataSource在相同的时间间隔可能会存在多个segment。这些segment在时间间隔里形成了一个块。依据shardSpec的类型来进行数据的切分,只有当一个块完成时,Druid才能进行查询。这就是说,假如一个块包含三个segment,例如:
sampleData_2011-01-01T02:00:00:00Z_2011-01-01T03:00:00:00Z_v1_0
sampleData_2011-01-01T02:00:00:00Z_2011-01-01T03:00:00:00Z_v1_1
sampleData_2011-01-01T02:00:00:00Z_2011-01-01T03:00:00:00Z_v1_2
当需要查询时间间隔为2011-01-01T02:00:00:00Z_2011-01-01T03:00:00:00Z的数据,所有这三个segment都必须加载完成。

例外的是线性分片声明,线性分片声明不需要强制块必须完成,并且在分片没有加载到系统中时也能完成查询。例如:如果我们的实时摄入创建了三个线性分片声明的segment,并且只有两个segment加载到系统里面,查询的时候会返回这两个segment的数据。

模式修改
替换segment
druid使用DataSource,时间间隔,版本和分区号唯一标识segment,分区号只有在一个segment 标识中可见是当某些时间粒度的时候存在多个segment。例如:如果我们有一个按小时的segment,但是我们的数据太多导致一个segment没法存储,我们就可以在相同的时间创建多个segment。这些segment拥有相同的DataSource,时间间隔和版本,但是会线性的增加分区好。
foo_2015-01-01/2015-01-02_v1_0
foo_2015-01-01/2015-01-02_v1_1 
foo_2015-01-01/2015-01-02_v1_2
在上面的示例中,DataSource= foo,时间间隔=2015-01-01/2015-01-02,version=v1,分区号=0.如果在后续的某一个时间点,我们使用新的模式从新索引了数据,则新创建的segment将会使用一个高的版本
foo_2015-01-01/2015-01-02_v2_0 
foo_2015-01-01/2015-01-02_v2_1 
foo_2015-01-01/2015-01-02_v2_2
druid批量索引(要么基于Hadoop要么基于索引任务)保证基于时间间隔的原子性更新。在我们的例子中,除非有所有的2015-01-01/2015-01-02的v2 segment全部加载到druid的集群中,否则查询就使用v1的segment。一旦所有的v2segment加载完成并可查询,所有的查询都会忽略v1segment并切换到v2 segment。稍后v1segment就会从集群中卸载。

需要注意的是只有在时间间隔内的所有segment才是原子性的。整体的更新不是原子性的。例如:我们有如下的segment:
foo_2015-01-01/2015-01-02_v1_0 
foo_2015-01-02/2015-01-03_v1_1 
foo_2015-01-03/2015-01-04_v1_2
v2segment将在构建后立即加载到集群中,并在segment重叠的时间段内替换v1段。在完全加载v2段之前,集群可能混合了v1和v2段。
foo_2015-01-01/2015-01-02_v1_0 
foo_2015-01-02/2015-01-03_v2_1 
foo_2015-01-03/2015-01-04_v1_2
正如上例,查询可能会同时命中v1和v2的segment。

segment会存在不同的模式
同一数据源的Druid段可能有不同的模式。如果一个字符串列(维度)存在于一个segment中而不是另一个segment中,则涉及这两个segment的查询仍然有效。对缺少维度的segment的查询将表现为该维度只有空值。类似地,如果一个段有一个数值列(metric),而另一个没有,那么查询缺少metric的段通常会看似在“做正确的事情”。在缺少的度量上的聚合的行为类似于该度量丢失。

Druid的segment相关推荐

  1. Druid的Segment Balance及其代价计算函数分析

    Balance $Cost(X, Y) $ $$ J_\alpha(x) = \sum_{m=0}^\infty \frac{(-1)^m}{m! \Gamma (m + \alpha + 1)} { ...

  2. 美团点评:基于Druid的Kylin存储引擎实践

    作者:康凯森 作者简介:美团大数据工程师,Apache Kylin Committer,目前主要负责美团 OLAP 系统(Kylin & Druid & Palo)的平台化建设. 8月 ...

  3. 快速了解Druid -- 实时大数据分析软件

    Druid 是什么 Druid 单词来源于西方古罗马的神话人物,中文常常翻译成德鲁伊.  本问介绍的Druid 是一个分布式的支持实时分析的数据存储系统(Data Store).美国广告技术公司Met ...

  4. OLAP引擎:基于Druid组件进行数据统计分析

    一.Druid概述 1.Druid简介 Druid是一款基于分布式架构的OLAP引擎,支持数据写入.低延时.高性能的数据分析,具有优秀的数据聚合能力与实时查询能力.在大数据分析.实时计算.监控等领域都 ...

  5. Druid 简介,架构,部署,python连接,hue链接druid

    架构 什么是Druid Druid是一个高效的数据查询系统,主要解决的是对于大量的基于时序的数据进行聚合查询.数据可以实时摄入,进入到Druid后立即可查,同时数据是几乎是不可变.通常是基于时序的事实 ...

  6. 实时分析数据库 Druid,Mark 一下

    本文已收录github:https://github.com/BigDataScholar/TheKingOfBigData,里面有大数据高频考点,Java一线大厂面试题资源,上百本免费电子书籍,作者 ...

  7. Druid -- 基于Imply方式集群部署

    向导 集群部署 1. 下载tar包,上传服务器,解压 2. 修改配置文件common.runtime.properties 3. 修改coordinator配置,vi overlord/runtime ...

  8. Druid集群搭建 使用套件2.2.3

     曹振华 关注 2017.07.17 22:02* 字数 304 阅读 2448评论 3喜欢 2 测试环境采用了三台虚拟机,每台4G内存 用到的软件有 mysql, hadoop-2.7.1, kaf ...

  9. 广告效果数据的实时计算与分析(Druid)(一)

    我是做SSP-供应方平台服务的,工作中除了负责SSP 管理后台的需求开发(如,媒体应用和位置的管理.流量分配.效果数据的报表展示.SDK性能分析等)之外,最主要的是负责SSP广告效果数据的实时统计与分 ...

最新文章

  1. 图像拼接--Creating full view panoramic image mosaics and environment maps
  2. 事关人类生存?为什么要探寻AI系统的可解释性?
  3. 第十二周项目1-阅读程序(三)
  4. 最强的浏览器插件——油猴脚本
  5. Java面试集合(二)
  6. 文件保存到服务器失败,Office 2010在服务器共享文件夹中保存文件失败
  7. python进阶(第三章2)字典和集合
  8. 20 FI配置-财务会计-定义税务科目
  9. Android 音频均衡器,可通过拖动调节音频EQ
  10. Vue调试工具的安装方法(动动鼠标就完成,不会意外报错,超爽~)
  11. 没想到Sharding-Jdbc竟然这么牛逼!一键实现读写分离、分库分表~
  12. 产品静电ESD测试标准
  13. als算法参数_矩阵分解之交替最小二乘ALS
  14. 初学者计算机电脑怎样学,初学者怎样学习电脑能够快速入门(免费科普电脑基础知识)...
  15. win10三国志14已停止工作解决方法--win10专业版
  16. OSI七层网络模型和网络协议
  17. 安装win10时无法安装若要在此计算机,win10安装时遇问题如何解决 win10安装解决方案...
  18. 【翻译】Chrome Developer Tools: Element 样式
  19. 键盘触发keypress事件,键值列表
  20. 诗歌(1)—定风波(常羡)

热门文章

  1. 敲门代码python_适用于Linux笔记本电脑的基于敲门的命令
  2. 创客学院知识巩固-04网络
  3. SQL注入进阶:掌握布尔盲注和延时注入攻击技巧
  4. PE工具制作/装机U盘制作
  5. Windows 10 神州网信政府版 麦克风、摄像头的使用
  6. DAPM-widget
  7. 李政道和杨振宁合作历程
  8. 晶体谐振器 晶体振荡器 正确区分
  9. element 表格显示图片
  10. Layui 表格 list页显示图片