加载

如何利用索引和主存储,是一种两难的选择。

  • 选择不使用索引,只使用主存储:除非查询的字段就是主存储的排序字段,否则就需要顺序扫描整个主存储。
  • 选择使用索引,然后用找到的row id去主存储加载数据:这样会导致很多碎片化的随机读操作。(ES检索出来的一堆ID,然后根据这些ID去数据库里取东西就是碎片化的磁盘操作!)

没有所谓完美的解决方案。MySQL支持索引,一般索引检索出来的行数也就是在1~100条之间。如果索引检索出来很多行,很有可能MySQL会选择不使用索引而直接扫描主存储,这就是因为用row id去主存储里读取行的内容是碎片化的随机读操作,这在普通磁盘上很慢。

Opentsdb是另外一个极端,它完全没有索引,只有主存储。使用Opentsdb可以按照主存储的排序顺序快速地扫描很多条记录。但是访问的不是按主存储的排序顺序仍然要面对随机读的问题。

Elasticsearch/Lucene的解决办法是让主存储的随机读操作变得很快,从而可以充分利用索引,而不用惧怕从主存储里随机读加载几百万行带来的代价。

Opentsdb 的弱点

Opentsdb没有索引,主存储是Hbase。所有的数据点按照时间顺序排列存储在Hbase中。Hbase是一种支持排序的存储引擎,其排序的 方式是根据每个row的rowkey(就是关系数据库里的主键的概念)。MySQL存储时间序列的最佳实践是利用MySQL的Innodb的 clustered index特性,使用它去模仿类似Hbase按rowkey排序的效果。所以Opentsdb的弱点也基本适用于MySQL。Opentsdb的 rowkey的设计大致如下:

[metric_name][timestamp][tags](和百度TSDB无异!)

举例而言:

Proc.load_avg.1m 12:05:00 ip=10.0.0.1
Proc.load_avg.1m 12:05:00 ip=10.0.0.2
Proc.load_avg.1m 12:05:01 ip=10.0.0.1
Proc.load_avg.1m 12:05:01 ip=10.0.0.2
Proc.load_avg.5m 12:05:00 ip=10.0.0.1
Proc.load_avg:5m 12:05:00 ip=10.0.0.2

也就是行是先按照metric_name排序,再按照timestamp排序,再按照tags来排序。

对于这样的rowkey设计,获取一个metric在一个时间范围内的所有数据是很快的,比如Proc.load_avg.1m在12:05到12:10之间的所有数据。先找到Proc.load_avg.1m 12:05:00的行号,然后按顺序扫描就可以了。

但是以下两种情况就麻烦了。

  • 获取12:05 到 12:10 所有 Proc.load_avg.* 的数据,如果预先知道所有的metric name包括Proc.load_avg.1m,Proc.load_avg.5m,Proc.load_avg.15m。这样会导致很多的随机读。如果 不预先知道所有的metric name,就无法知道Proc.load_avg.*代表了什么。
  • 获取指定ip的数据。因为ip是做为tags保存的。即便是访问一个ip的数据,也要把所有其他的ip数据读取出来再过滤掉。如果ip总数有十 多万个,那么查询的效率也会非常低。为了让这样的查询变得更快,需要把ip编码到metric_name里去。比如 ip.10.0.0.1.Proc.load_avg.1m 这样。

所以结论是,不用索引是不行的。如果希望支持任意条件的组合查询,只有主存储的排序是无法对所有查询条件进行优化的。但是如果查询条件是固定的一种,那么可以像Opentsdb这样只有一个主存储,做针对性的优化。

DocValues为什么快?

DocValues是一种按列组织的存储格式,这种存储方式降低了随机读的成本。传统的按行存储是这样的:

1和2代表的是docid。颜色代表的是不同的字段。

改成按列存储是这样的:

按列存储的话会把一个文件分成多个文件,每个列一个。对于每个文件,都是按照docid排序的(???不是field values吗?)。这样一来,只要知道docid,就可以计算出这个docid在这个文件里的偏移量。也就是对于每个docid需要一次随机读操作。

那么这种排列是如何让随机读更快的呢?秘密在于Lucene底层读取文件的方式是基于memory mapped byte buffer的,也就是mmap。这种文件访问的方式是由操作系统去缓存这个文件到内存里。这样在内存足够的情况下,访问文件就相当于访问内存。那么随机 读操作也就不再是磁盘操作了,而是对内存的随机读。

那么为什么按行存储不能用mmap的方式呢?因为按行存储的方式一个文件里包含了很多列的数据,这个文件尺寸往往很大,超过了操作系统的文件缓存的大小。而按列存储的方式把不同列分成了很多文件,可以只缓存用到的那些列,而不让很少使用的列数据浪费内存。

按列存储之后,一个列的数据和前面的posting list就差不多了。很多应用在posting list上的压缩技术也可以应用到DocValues上。这不但减少了文件尺寸,而且提高数据加载的速度。因为我们知道从磁盘到内存的带宽是很小的,普通 磁盘也就每秒100MB的读速度。利用压缩,我们可以把数据以压缩的方式读取出来,然后在内存里再进行解压,从而获得比读取原始数据更高的效率。

如果内存不够是不是会使得随机读的速度变慢?肯定会的。但是mmap是操作系统实现的API,其内部有预读取机制。如果读取offset为100的 文件位置,默认会把后面16k的文件内容都预读取出来都缓存在内存里。因为DocValues是只读,而且顺序排序存储的。相比b-tree等存储结构, 在磁盘上没有空洞和碎片。而随机读的时候也是按照DocId排序的。所以如果读取的DocId是紧密相连的,实际上也相当于把随机读变成了顺序读了。 Random_read(100), Random_read(101), Random_read(102)就相当于Scan(100~102)了。

转自infoq 时间序列数据库的秘密

转载于:https://www.cnblogs.com/bonelee/p/6432732.html

时间序列数据库——索引用ES、聚合分析时加载数据用什么?docvalues的列存储貌似更优优势一些...相关推荐

  1. SpringMvc 系统启动时加载数据到内存中

    SpringMvc 系统启动时加载数据到内存中 学习了:http://blog.csdn.net/newstruts/article/details/18668269 https://www.cnbl ...

  2. Launcher3源码分析(LauncherModel加载数据)

    LauncherModel继承BroadcastReceiver,显然是一个广播接收者.在上一篇Launcher的启动中讲到桌面数据的加载工作是在LauncherModel中执行的,那么它是如何加载数 ...

  3. spark运行时加载hive,hdfs配置文件

    以前我用spark连接hive都是把hive的配置文件放在spark的conf目录,后来有个项目在运行时才能确定要连接哪个hive源,我就找了个能在运行时加载配置文件的方法,代码如下: import ...

  4. Android之Launcher分析和修改4——初始化加载数据

    上面一篇文章说了Launcher是如何被启动的,Launcher启动的过程主要是加载界面数据然后显示出来, 界面数据都是系统APP有关的数据,都是从Launcher的数据库读取,下面我们详细分析Lau ...

  5. RecyclerView使用 及 滑动时加载图片优化方案

    RecyclerView使用 及 滑动时加载图片优化方案 简述 本篇博文主要给大家分享关于RecyclerView控件的使用及通过继承RecyclerView来实现滑动时加载图片的优化方案,也同样能解 ...

  6. Mybatis3源码分析(05)-加载Configuration-加载MappedStatement

    2019独角兽企业重金招聘Python工程师标准>>> Mybatis3源码分析(05)-加载Configuration-加载MappedStatement 博客分类: java m ...

  7. android listview 只加载显示的图片大小,Android ListView只加载当前屏幕内的图片(解决list滑动时加载卡顿)...

    最近在做ListView分页显示,其中包括图片 和文字(先下载解析文字内容,再异步加载图片)发现每次点击下一页后,文字内容加载完毕,马上向下滑动,由于这时后台在用线程池异步下载图片,我每页有20条,也 ...

  8. 设置 COM加载项 启动时加载(及 解决 PDFMaker 文件遗失问题)

    设置 COM加载项 启动时加载(及 解决 PDFMaker 文件遗失问题) 我习惯于使用 Adobe Acrobat 的右键菜单文件合并功能合并 Word 文件,这个功能需要使用到 PDFMaker. ...

  9. 南大通用数据库-Gbase-8a-学习-14-LOAD加载数据

    一.测试环境 名称 值 cpu Intel® Core™ i5-1035G1 CPU @ 1.00GHz 操作系统 CentOS Linux release 7.9.2009 (Core) Gbase ...

最新文章

  1. 计算MySQL的内存峰值公式
  2. platform设备驱动全透析
  3. 2020,再见;2021,我来了!
  4. windows和linux没有启动选择,重装Windows后,LILO启动选单不见了,无法进入Linux系统怎么办...
  5. LeetCode(657)——机器人能否返回原点(JavaScript)
  6. 传说有位游客在山顶大声谈论着小孤嫁彭郎的故事
  7. C#学习基础---BrowsableAttribute.Browsable属性
  8. vc服务器的作用,总结虚拟化服务器的好处
  9. 当智能门锁已不再是锁
  10. 计算机教室管理员应知应会,教室管理
  11. java mian是什么_java mian方法详解
  12. 逆概率加权法(Inverse Probability Weighting, IPW)的原理及R实现
  13. cityengine笔记
  14. 环境和社会风险分类c类_A、B、C级风险隐患分类标准
  15. 乓乓响再次冲刺香港上市,黄建义、张卫平夫妇套现约2130万元
  16. 微信收货地址开发分享
  17. 发布会直播平台哪家好
  18. Ae/Pr/FCPX抠图插件:Primatte Keyer Mac大大提高工作效率
  19. 基于STM32单片机的智能家居毕设
  20. 全网清晰虚拟机安装截图

热门文章

  1. TextBoxSuggest,输入框提示工具,输入建议,输入匹配,辅助输入,输入即时提示,文本编辑器,Visual Studio效果,高速查询引擎,哈希树,模糊匹配,百万条零毫秒
  2. 计算机组成原理DMA方式原理,计算机组成原理4(程序查询方式、程序中断方式、DMA方式及其I/O接口电路)...
  3. linux下用dd命令拷贝硬盘黑屏,linux下用dd命令拷贝硬盘
  4. opencv 安装_如何在 CentOS 8 上安装 OpenCV
  5. mysql监控nginx_mysql和nginx服务是否正常监控脚本
  6. python爬虫源码下载 视频_Python爬虫下载视频文件部分源码
  7. 私有5g网络_欧洲通过FUDGE5G的启动来支持工业4.0的云原生私有5G
  8. mysql命令行的光标不显示和git-bash不能直接使用mysql登录的问题
  9. python【力扣LeetCode算法题库】300 最长上升子序列(动态规划)
  10. Tensorflow【实战Google深度学习框架】预训练与微调含代码(看不懂你来打我)