高效数据查询设计思想
OLTP(on-line transaction processing)联机事务处理
关于如何设计一个OLTP存储系统,核心需求是实现海量数据集中的低延时随机读写操作,我们探讨下它的核心设计思想:
select id, name from student;
-
数据排序:在海量数据中要想保证低延时的随机读写操作,数据最好是排序的
-
范围分区:当数据排序之后,可以进行范围分区,来平摊负载,让多台服务器联合起来对外提供服务
-
内存+磁盘:保证处理效率,也保证数据安全
-
内存:必须经过设计,内存具备优秀的数据结构,保证基本的读写高效,甚至为了不同的需求,可以让读写效率倾斜
-
写缓存:将为了实现数据有序而进行的低效率随机写转换为内存随机写+磁盘顺序写的方式
-
读缓存:将经常查询的热点数据缓存在内存中,提高查询效率
-
磁盘:数据必须存放在磁盘,保证数据安全。磁盘数据文件必须经过精心设计,保证扫描磁盘数据文件的高效率
-
跳表:基于数据排序+范围分区构建索引表,形成跳表的拓扑结构,方便用户操作时快速定位数据分区的位置
-
LSM-Tree存储引擎:把随机写变成顺序追加,在通过定期合并的方式来合并数据,去除无效数据,从而实现数据的删除和修改
-
布隆过滤器:快速判断一个元素(1)是否存在于一个庞大集合内/文件中(100E) ,常数级别的执行效率
海量数据中,如果进行高效率的查询的核心思想:设计一种架构,能够快速把待搜寻的数据范围降低到原来的1/n,然后再结合索引或者热点数据放在内存等思路,就能实现高效率的查询了。
OLAP(On-Line Analytical Processing)联机分析处理
那么一个专门用来做OLAP分析的存储引擎该如何设计呢?
如何在海量数据中,针对大量数据进行查询分析呢?
核心需求是实现海量数据集中的高性能低延迟查询分析功能,一些常见的方案和手段如下:
select department, avg(age) from student group by department;
- 数据排序
- 数据分区分片+分布式查询
- 列式存储+字段类型统一
- 列裁剪
- 预聚合(搜索引擎:输入关键词,搜索引擎根据关键词到数据库找到这个关键词对应的所有的URL:这些URL就是提前计算出来的)
- 利用CPU特性:向量化引擎,操作系统必须支持
- 主键索引+二级索引+位图素引+布隆索引等等各种索引技术
- 支持近似计算,pv一个电商平台的sku总数
- 定制引擎:多样化的存储引擎满足不同场景的特定需求
- 多样化算法选择:Volnitsky高效字符串搜索算法和HyperLogLog基于概率高效去重算法
总结一下:单条记录的增删改等操作,通过数据的横向划分,做到数据操作的快速定位,在海量数据查询分析中,一般就是针对大量行少量列做分析,既然并不是全部列,那么把数据做纵向切分把表中的数据按照列来单独存储,那么在做分析的时候,同样可以快速把待查询分析的数据总量降低到原来表的1/n,同样提高效率。而且对于常用的聚合逻辑的结果,也可以提前算出来缓存起来用来提供效率,这就是预聚合技术。提到预聚合,大家会想到Kylin, Kylin 是一个把预聚合技术发挥到极致的一个OLAP技术,但是Kylin也有它的缺点:
1、预聚合只支持固定的分析场景,无法满足自定义分析场景,所以预聚合只能作为一种可选方案
2、维度组合爆炸会导致数据膨胀,这样会造成不必要的计算和存储开销。无必要的维度组合的计算就属于浪费资源。
3、大概率数据都是增量生成,预聚合不能进行数据更新。所以会产生大量的重算。