[SIGMOD 22 学习]《Adaptive Hybrid Indexes》解读

本文涉及的产品
对象存储 OSS,20GB 3个月
日志服务 SLS,月写入数据量 50GB 1个月
对象存储 OSS,恶意文件检测 1000次 1年
简介: 本文是学习总结,有错误处欢迎交流。

Paper:Adaptive Hybrid Indexes

本文是学习总结,有错误处欢迎交流。

背景

index 是查询处理系统中性能影响的关键部分,DBMS 广泛采用 B-tree、trie、hash table,特别是 OLTP 系统的索引的存储开销非常大(一些场景下,一半以上的内存是由索引结构消耗的)。内存在现代数据库上加速效果非常明显,但很多场景下将所有数据放入内存已不可能。AWS 提供 24 TB 的 RAM 实例,每小时消耗 $120;即使 SSDs、NVME 被大量应用,但 IO 操作效率远慢于内存。

作者把索引优化技术按介入的时间分为三个阶段:

  1. development-time:单类型数据结构
  1. 设计 state-of-the-art 数据结构满足 CRUD 操作,整体均衡,重点对主要操作做优化。
  2. compact index 技术,减少内存空间,通常比 state-of-the-art index 要慢。例如 succinct index 通过减少数据结构上的 pointer 并在运行时计算 offset,在 lookup、scan、udpate 上性能差一些。
  1. build-time:在一个 index(不同的数据块)上使用多种 encoding 组合,根据数据特征,在写入时选择数据结构。
  2. run-time:build-time 是一种静态组合,单不考虑动态的 workload(工况),run-time 时可以拿到更多的 工况信息帮助优化索引结构。

论文提出一个框架:workload-adaptive hybrid index,将 encoding 决策时机延后到 run-time 进行。

思路

"The RUM conjecture" 描述了一个数据结构不能同时做到对读、写、存储空间的最优化。但在实际业务场景下,可以观察到一些 skewed workload(query pattern、key pattern、数据特征)情况,此时 RUM 冲突被弱化了。

现有的一些针对 skewed worklaod 优化的研究,主要的方法是把访问频度数据放在内存上。受限于数据大、内存有限,提出 hot-cold 分类问题,也即 top-k 频繁集挖掘问题,在一个大的数据集合上:

  • 过小的抽样率,导致分类错误率上升。
  • 过大的抽样率,收集、分析采样数据的开销会很大。

论文贡献是提出利用 skewed workload pattern 来设定索引数据结构(tree node layout)的方法:

  • 基于自适应、运行时抽样方法记录访问频率等统计信息。
  • hybrid index 思路,对于每一块数据,根据细粒度统计信息判定 tree node 为 hot/cold,动态选择合适的 encoding。
  • 目标是在性能牺牲不大的同时有效降低内存开销(结果:相比 state-of-the-art index,减少 82% 空间,保留 90% 性能)。

Adaptive Hybrid Indexs

架构设计

数据库传统的索引在所有叶子节点上编码方式相同,预分配固定的 key/value slot 支持高效读、写操作,缺点就是内存占用大。

比较 lookup、insert 两项操作在压缩和非压缩 B+ 树:

  • 70% 叶子节点时,LZ4 压缩后存储量减少 47%。
  • 不同存储介质间比较,内存有极大性能优势。
  • 以内存为例,压缩数据上操作相比非压缩数据上操作,效率大幅降低。

因此,论文在架构设计的关键点有两个:混合多种索引优势,运行时优化分支选择。

包括两个阶段(两阶段会一直交替、重复):

  1. Sample:给 index 中不同部分块的访问操作做抽样、聚合统计。
  2. Adaptation:运行一个启发式分类算法做 hot、cold 节点判定,hot 使用性能优化格式,cold 则使用高压缩格式。

接口设计

两个概念:

  • adaptation manager:框架的控制器。
  • basic unit:收集统计信息和进行 encoding 转换的基本单元。用唯一标识符(identifiers)表示,例如 B+ tree 使用指针,succinct index 使用位置 offset。

代码接口清晰,这里稍作解读:

  • 为降低采样跟踪的消耗,因此限定在一个子集上,引入一个是否需要被抽样的判断标准(下文即将提到的 skip length、sample size)。
  • bloomfilter 是对 hashmap 的一次前置操作(优化性能),identifier 必须先在 bloomfilter 中出现,才有可能被加入 hashmap(防止 cold 节点被意外地加入采样跟踪)。
  • 采样可支持 thread_local 进行,进一步降低其并发开销。
  • 通过 C++ 模版可变参数、完美转发,框架可以方便地将上下文信息(例如父子节点)转发给 adaptation manager。

Sample 过程

收集统计信息分两类:

  • decentralized schema:存储跟踪到的信息到索引结构自身,引入额外存储空间消耗。比如为索引的每一段增加元数据,包括:最近访问时间,读、写次数。
  • centralized schema:即论文采用的方法,只对被访问到的数据段存储统计信息,将它与轻量级的抽样结合起来,有效降低跟踪带来的开销。

索引在处理 query 时,从上到下遍历内部结构。作者的方法是:基于预设参数(skip length)每隔 N 个(叶子节点)会被记录访问信息;考虑到最近经常的访问模式,系统在做抽样节点信息聚合统计时,把最近访问时间 epoch 也存储下来。

这里有两个重要参数:

  1. skip length(决定抽样频率):下图的实验数据表明,蓝线(直接抽样)、红线(bloomfilter 过滤后再抽样)两组数据随着 skip length 的降低,附加了更多的计算消耗。取阈值 20 时,性能损失 1.6% 是可接受的。

  1. sample size(决定抽样节点集合的大小):根据下面等式计算(n 是叶子节点大小,还包括分类错误率、信任度等一些参数,细节可参考原文)。

由于是 run-time 方案,采样在动态调整。adaptation manager 在下一个抽样阶段开始前将调整参数(skip length、sample size);同时也会参考 workload 稳定度信息,例如频繁发生 encoding 转变时,将减少 skip length 来实现更好的工况跟踪。

Adaptation 过程

基于聚合后的统计信息,所有的抽样节点被分类为 hot(top-k)、cold。根据 epoch 信息可将最近没被采样到的节点判定为 cold。hot 节点的数量也要参考内存上限的阈值。

通过 context-sensitive heuristic functions (CSHF) 做决策,并在必要时执行 encoding 转换。

分类的计算代价集中在优先队列(top-k)和 hashmap 访问、修改统计信息上。

分类算法如下图描述(Compr:压缩存储结构;Optimized:基于内存的性能优化结构):

除此之外,每个 node 上增加一个字节,保留最近八次分类结果作为历史数据。有些周期性场景可以使用离线模型,通过历史数据和预测值计算 node hot/cold 分类。

实现

文章基于以上方法,给出了在 B+ 树、前缀树上的两种实现。

Hybrid B+ Tree

一个背景:采用 B+ 树的系统在长期运行中,由于经常做 insert/delete,可能产生一些未使用的 slot,使得空间利用率低于 70%。

  1. encoding 类型

Hybrid B+ index 对叶子节点有如下三种编码方式,混合索引将根据场景选择适合的存储类型:

  • Gapped:传统的,可能有空的 slot,内存有一定浪费。
  • Packed:只对使用到的 slot 分配内存空间。read、update、delete(墓碑)操作友好,但 insert 效率极低。
  • Succinct:bit packing 方式存储 key、value,相当于一种压缩,增加了访问延迟。但紧凑的数据排列减少了 CPU cache miss。

  1. encoding 转换

从实验数据上看,涉及到 succinct 的转换都会产升较大开销。

在实现上,由于 insert/delete 可能导致 node 的split/merge,如果一个叶子节点转移到了新的父节点下,该信息必须在跟踪框架中传递,使得 adaptation manager 的上下文信息也做到更新。

Hybrid Trie

trie tree 常用于变长 key、前缀匹配,有两种改进型:

  • Adaptive Radix Tree(ART):指针方案,引入四种类型的 node 改进传统 trie tree 缓存命中率低的问题。其每一种类型有不同 lookup 性能,但 node 类型只由 key 决定,不考虑实际 workload。
  • Fast Succinct Tree(FST):没有孩子节点指针,通过两个 bitmap 来计算位置。大体上是其中一个维护了已存在的 label,另一个维护 path 是否终止的标记。

Hybrid Trie 将 development-time 的 ART 和 build-time 的 FST 结合起来,实现在 run-time 可适应实际工况的分支选择优化,并提供冷热转换支持。

上图中 1、2 就代表两种类型的转换过程,文中给出的一个场景测试(叶子节点占比 50%)结果:

  • FST -> ART:平均耗时 5000ns,需要重新插入构建,成本较高。
  • ART -> FST:平均耗时 100ns,只需少量操作(删除 ART 节点)。

由于 FST 不支持插入,导致需要重建。会引入 sub-tree,将 cold 节点做成子树,预留一些存储空间。这算是做到一定程度优化,但还需要不少工作来覆盖更多工况。

Hybrid Trie 的 lookup 过程如下(黄色标记部分是抽样框架的工作):

结果

在十种数据集上进行实验,将 workload 分为四类,每个类别按照累计分布来区分:

  1. Hybrid B+ tree

在 skewed workload 上,其存储空间上对比 Succinct 结构只有少量上涨,性能上做到接近 Gapped 结构。

  1. Hybrid Trie

其空间大小、性能上的综合表现符合预期。

按照时间线(横轴)维度,分 sample、adaptation 两个过程,可以看到索引结构 expand/compact 过程。这是 adaptation manager 上若干策略的结果:及时感知数据访问特性变化,进而动态调节。

总结:个人觉得论文思路上比较正常,阐述得很清晰,提供了实现(代码接口)和很多详尽的实验数据,感兴趣可以看原文。

目录
相关文章
|
Java Linux C语言
java中的synchronized和linux系统的futex到底什么个关系?
首先,futex不是个完整的锁,它是“支持实现userspace的锁的building block“。也就是说,如果你想实现一个mutex,但不想把整个mutex都弄到内核里面去,可以通过futex来实现。但futex本身主要就是俩系统调用futex_wait和futex_wake. 为了更好的解释这个问题,这里先梳理下锁本身是怎么工作的。
java中的synchronized和linux系统的futex到底什么个关系?
|
5月前
|
存储 消息中间件 Kafka
基于 Flink 的中国电信星海时空数据多引擎实时改造
本文整理自中国电信集团大数据架构师李新虎老师在Flink Forward Asia 2024的分享,围绕星海时空智能系统展开,涵盖四个核心部分:时空数据现状、实时场景多引擎化、典型应用及未来展望。系统日处理8000亿条数据,具备亚米级定位能力,通过Flink多引擎架构解决数据膨胀与响应时效等问题,优化资源利用并提升计算效率。应用场景包括运动状态识别、个体行为分析和群智感知,未来将推进湖仓一体改造与三维时空服务体系建设,助力数字化转型与智慧城市建设。
626 3
基于 Flink 的中国电信星海时空数据多引擎实时改造
element-plus:Dialog 对话框在有滚动条的页面会抖动
element-plus:Dialog 对话框在有滚动条的页面会抖动
818 0
element-plus:Dialog 对话框在有滚动条的页面会抖动
|
数据采集 自然语言处理 搜索推荐
图文详解 DFS 和 BFS | 算法必看系列知识二十四
深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法,生产上广泛用于拓扑排序,寻路(走迷宫),搜索引擎,爬虫等,也频繁出现在高频面试题中。
35681 6
图文详解 DFS 和 BFS | 算法必看系列知识二十四
|
安全 网络协议 API
Docker搭建Let's Encrypt并连接阿里云自动签发https证书
Docker搭建Let's Encrypt并连接阿里云自动签发https证书
Docker搭建Let's Encrypt并连接阿里云自动签发https证书
|
8月前
|
SQL 存储 Apache
基于 Flink 进行增量批计算的探索与实践
本文整理自阿里云高级技术专家、Apache Flink PMC朱翥老师在Flink Forward Asia 2024的分享,内容分为三部分:背景介绍、工作介绍和总结展望。首先介绍了增量计算的定义及其与批计算、流计算的区别,阐述了增量计算的优势及典型需求场景,并解释了为何选择Flink进行增量计算。其次,详细描述了当前的工作进展,包括增量计算流程、执行计划生成、控制消费数据量级及执行进度记录恢复等关键技术点。最后,展示了增量计算的简单示例、性能测评结果,并对未来工作进行了规划。
910 6
基于 Flink 进行增量批计算的探索与实践
|
10月前
|
数据可视化 定位技术
OKR:如何将战略目标拆解成可执行的团队任务
在现代职场中,方向不明和目标模糊常使团队陷入困境。OKR(目标与关键结果)的引入,如同“人生GPS”,不仅让工作更加有序,还帮助团队重拾奋斗的意义。通过明确大方向、拆解目标及搭建透明看板,OKR实现了目标清晰、过程透明、结果可衡量,有效提升了团队的执行力和士气。
435 1
OKR:如何将战略目标拆解成可执行的团队任务
|
机器学习/深度学习 边缘计算 PyTorch
PyTorch 与 ONNX:模型的跨平台部署策略
【8月更文第27天】深度学习模型的训练通常是在具有强大计算能力的平台上完成的,比如配备有高性能 GPU 的服务器。然而,为了将这些模型应用到实际产品中,往往需要将其部署到各种不同的设备上,包括移动设备、边缘计算设备甚至是嵌入式系统。这就需要一种能够在多种平台上运行的模型格式。ONNX(Open Neural Network Exchange)作为一种开放的标准,旨在解决模型的可移植性问题,使得开发者可以在不同的框架之间无缝迁移模型。本文将介绍如何使用 PyTorch 将训练好的模型导出为 ONNX 格式,并进一步探讨如何在不同平台上部署这些模型。
1223 2
|
存储 算法 安全
程序员必知:分布式一致性Raft与JRaft
程序员必知:分布式一致性Raft与JRaft
182 0
|
API C# 图形学
程序技术好文:深入理解xLua热更新原理
程序技术好文:深入理解xLua热更新原理
535 0