暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

索引统计功能实现,携程&OceanBase开源共建实践

原创 OceanBase数据库 2024-03-12
638

自从 2021 年 OceanBase 开源以来,携程一直致力于其在实际业务场景下的应用实践,探索新一代分布式数据库的可能性。随着携程业务需求的增长和多样化,OceanBase 的应用范围也越来越广,与之对应的积累的实践经验也越来越丰富,作为用户,我们希望进一步参与到 OceanBase 开源社区的建设中,推进国产分布式数据库的发展。其中,携程和 OceanBase 共同实现了索引统计功能,本文将介绍此次开源实践。


图片


经过 2 年的探索实践,携程已经形成了比较完善的 OceanBase 应用体系。2021 年,携程将 OceanBase 初步应用于日志库场景,以评估 OceanBase 的性能、稳定性及数据压缩率。与此同时进行了周边工具的建设,如发布工具,Canal 工具等,并完善了标准化的上下线流程,为深化应用打下基础。


随着使用流程的逐渐成熟,以及生产数据量的不断增长,携程拓展了 OceanBase 的使用场景,将其作为历史冷数据的归档库(见图 1),利用其高压缩率节省 85% 的存储成本。如今,携程越来越多的业务场景使用 OceanBase,如结算业务、推荐业务及其他在线 OLTP 业务场景,得益于分布式的扩容能力,我们可以更加轻松地应对各种高负载的情况。(*延展阅读:存储成本降低85%,携程历史库场景的降本实践

图片

图 1 OceanBase 存储归档冷数据


除了体会到分布式数据库高性能、大容量、灵活扩展等优势外,我们也面临运维体系的挑战。因为我们已经有多年的 MySQL 使用经验,形成了相对成熟的 MySQL 开发和运维流程,所以我们在使用 OceanBase 时,希望它可以尽量兼容现有的各项开发、运维流程,包括数据库的上下线、表结构的发布变更、应用的访问方式、大数据取数等;还能提供超越 MySQL 的运维潜力。方便我们将 OceanBase 平滑接入现有的自动化运维系统,同时借助强大的分布式拓展能力进一步提升我们的运维能力。


对此,携程针对 OceanBase 建立了监控告警系统、慢日志审计系统、数据库迁移工具等,但在使用过程中,我们发现相比 MySQL,OceanBase 4.2.1 并不能完全满足我们的运维工作需求,例如没有提供类似 MySQL 的索引统计功能、详细的表级增删改查统计功能等。针对这些问题,我们向 OceanBase 团队提出了反馈,一方面我们希望 OceanBase 可以功能更加丰富,完全满足我们的使用需求,另一方面,希望参与分布式数据库的建设,为 OceanBase 社区贡献一份力量。


基于此,携程很荣幸和 OceanBase 团队达成了源码共建的合作关系,由我们提出需求协作开发并最终并入社区版源码,目前我们已在 OceanBase 4.3 中合作完成了索引统计功能,下面就该功能的设计和实现进行详细的介绍。


(一)需求背景

OceanBase 4.2.1 亟需开发针对索引使用上的监控功能:例如索引被引用的次数,一段时间内的频率,读写访问的次数等。这些统计数据对于数据库的运维是非常重要的,存在很多应用场景。


1)删除索引时需要确认索引是否被访问。用户一般通过创建索引来加速查询的过程,然而过多的索引,可能会占用过多的磁盘空间,查询时的索引选择和争用的开销也会上升,索引走错的概率也会增大,因此需要清理冗余索引。业务 SQL 发生变化时也可能需要下线老的索引,索引统计功能可以极大地降低删除索引的风险。


2)通过采集各个时间段的索引使用情况,我们可以感知整张表的访问热度趋势。例如图 2 中的例子,用户可以根据图中趋势分析出这张表的访问高峰时段,以及各个不同索引的访问趋势,在添加新索引后可以观察趋势验证索引效果,例如图中 idx_b_c 索引添加之后 idx_b 索引就逐渐不再被访问。


3)通过采集索引的读写访问次数,可以分析表的访问模式,以进行进一步的优化。 MySQL 的索引统计功能就提供了表级别的读写统计数据,利用这些数据,用户可以采集每张表的读写访问趋势,从而判断这些表是读多写少还是写多读少等并根据访问模式选择更合适的优化方案,例如使用缓存、优化写入方式等。

图片

图 2 索引访问数据示例


传统的数据库 MySQL 和 Oracle 都提供了索引监控功能,前者利用 performance_shcema 中的内存表详细统计了每个索引被访问的次数及各种类型语句(增删改查)的执行次数,携程就是利用这些数据评估各个表的和索引的访问情况和负载类型;后者则将索引统计信息定期持久化到磁盘,DBA 可以通过特定视图访问。


综上所述,我们认为索引监控功能对于 OceanBase 也是非常有必要的。


(二)设计方案

为同时适应 MySQL 和 Oracle 模式下的用户访问,OceanBase 索引统计功能采用持久化存储设计,数据存在内部表,两种模式下的用户可以通过不同视图访问;由于 OceanBase 是多租户设计,索引统计功能也需要具备租户级别的控制和统计能力;另外,为了尽可能降低性能影响,参考 Oracle,该功能提供抽样统计模式选项。


如图 3 所示,索引统计采用增量数据写入内存,定期刷到内部表的方式实现,各个租户的增量数据、相关配置、定时任务以及内部表都是独立的。不同的 SQL 线程在访问到索引时会更新其租户下的索引统计数据,各个租户的定时任务会负责配置的刷新和内部表的更新,用户可以通过视图查询索引信息。

图片
图 3 索引统计实现


(三)实现细节

索引统计功能的主要流程可以抽象为三个阶段。


  • 数据收集:收集索引使用数据。
  • 数据管理:在内存中维护管理索引统计数据。
  • 数据上报:将收集到的数据持久化到内部表中。


图 3 中的流程就是这三个阶段的具体体现。另外,我们在实现的过程中也重点考虑了索引统计对数据库性能的影响,并进行了相应的优化。


阶段1:数据收集

考虑到兼容 MySQL 和 Oracle 的索引统计功能,收集的数据包括索引的使用次数、上次使用的时间、扫描的行数、各种类型查询的数量等。OceanBase 支持 SQL / OBKV(TableAPI) 两种方式对数据进行访问,数据统计需要考虑 SQL 和 TableAPI 两种访问形式。但由于 TableApi 使用与 SQL 模式不同的 TableScan 算子,ObTableApiScanExecutor 和 ObTableScanOp,若在 TableScan 算子层统计索引使用,那么就需要分别适配 TableAPI 和 SQL 两种模式的算子;如果在更底层 DAS 层进行统计,则只能按分区粒度统计,无法获取表级数据。因此决定在 TableScan 算子层实现两种统计方式,在算子关闭时更新内存中的索引使用信息。目前,索引统计会收集索引的访问次数和访问时间。

图片

图 4 索引统计数据收集流程图


阶段 2:数据管理

各个租户会维护自身的索引统计数据,具体到内存中,增量数据储存在多个 hashmap 中,租户初始化时会根据自身的内存和 CPU 资源选择合适的 hashmap 数量来保证最优性能。索引数据更新时会随机选择 hashmap 写入数据,目的是降低并发访问时的锁竞争,同时数据采样也发生在此处,将根据租户配置的采样比随机写入数据。选择在写入时采样一方面可以减少性能影响和内存占用,另一方面不在数据上报时采样可以更精确地检测索引是否被删除。


阶段 3:数据上报

租户内存中的增量数据会通过定时任务的方式写入内部表完成数据上报,该任务使用 OceanBase SharedTimer 的方式实现,避免消耗额外的线程资源。上报过程中会对内存中每个 hashmap 进行全量的遍历,通过 batch insert 的方式将增量数据写入内部表,这个过程还会检查对应索引表是否已经删除,hashmap 和内部表中的数据将在索引删除一段时间之后被删除。


索引统计性能优化

在开发和测试过程中,我们发现索引统计信息写入内存的过程有可能对整体的语句执行主流程产生性能影响。从图 4 的流程也可以看到,索引统计发生在整个语句执行的关键路径中,因此这一步的性能优化尤为重要。最开始我们采用单个hashmap进行数据存储,在数据上报时进行采样的方式。


由于统计是在 TableScan 算子关闭时写入 hashmap,每次执行使用索引的语句都会对 hashmap 进行写入,在高并发访问相同的索引场景下,由于需要写入相同的hash 桶,就会产生较多的锁竞争,从火焰图可以看到,整个调用栈中锁等待占用了较长时间。针对这个问题,我们和 OceanBase 的同学进行讨论后决定对 hashmap 进行分片,使用多个 hashmap 的方式来减少锁竞争,并将采样逻辑移到数据收集阶段,减少写 hashmap 的次数,这样一来,索引统计整体的性能影响就降低了很多。当然,用户也可以动态配置采样比例或者暂时关闭采样模式以获取更为准确的索引统计信息。

图片

图 5 单 Hashmap 模式访问火焰图


数据展示

  • 内部表:__all_index_usage_info


  • 视图:DBA_INDEX_USAGE, CDB_INDEX_USAGE


内部表用于定时任务内部数据存储,视图则是呈现给用户使用,兼容 Oracle 的 DBA_INDEX_USAGE 字段,目前支持索引使用次数和使用时间的展示,后续可以进一步拓展。

图片

图 6 索引统计视图示例


图片


本次开源共建,一方面丰富了 OceanBase 的功能,使其满足了携程的使用需求,另一方面也加强了我们团队的源码开发能力,为日后进一步地使用和共建打下了基础。非常感谢 OceanBase 团队提供的共建机会和技术支持,希望以后可以继续合作,共同推进国产分布式数据库的发展,实现共建共赢!

最后修改时间:2024-03-14 15:31:43
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论