第二届华为云数据库挑战赛参赛总结

2024-03-28 15:32

本文主要是介绍第二届华为云数据库挑战赛参赛总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

        • 1. 赛题分析
        • 2. 程序结构及存储结构设计
          • 2.1 分区策略
          • 2.2 存储结构&索引结构
        • 3. 读写实现
        • 4. 细节优化
        • 5. Java的不足
        • 6. 总结

继上次参加第五届中间件性能挑战赛之后,又一次参加类似的工程类性能比赛,和上次的TSDB题目类似,本次是实现多版本的KV数据库,由于上次的遗憾出局(复赛第七),这次抱着破釜成舟一定要拿奖的的心态,最终结果也算比较满意(复赛第五,Java语言最高分)。

1. 赛题分析

本次比赛需实现一个多版本的KV数据库引擎,写入为随机写,查询功能为MinV~NV Delta的累加结果,同时需支持进程奔溃级的故障恢复。本赛题的读写比例为7:1,需寻找合适的数据组织方式来最小化写入和查询IO的总耗时。

赛题介绍

代码地址

2. 程序结构及存储结构设计
2.1 分区策略

评测程序是30/15个线程并发的发送数据,读写同时在进行。由于key可能在多个线程中出现,为了减少一次查询的IO次数,我们在写入时让相同的key放入一个文件。但是如果全局单文件的话同步消耗不可忽视。因此我们决定基于key进行分区。最多30个线程写,理想情况下,同一时间每个线程写不同的文件,因此将分区定为30。文件Id为hash(key)%30。

由于索引结构中包含了key/version,因此查询时不需要文件中的key/version,所以在一个分区下我们将key/version存入一个文件,delta存一个文件,查询时只需读取delta文件。

2.2 存储结构&索引结构

为了让读取尽量能够在一次IO中完成,我们采用了随机写delta数据的方式,尽量将相同的key紧凑的存储,将文件分为多个page,page的大小固定,如果一个key的delta超过了page的阈值,则顺序开辟一个page存放此key的delta,一个page中只会存放一个key的delta。

key和version采用顺序追加写,同时每个key/version后面追加一个delta的偏移坐标。一个分区Bucket的结构如下图所示:
在这里插入图片描述

Key/ Version文件有两个作用

  1. 故障恢复时构建内存索引。
  2. 当数据总量大至索引无法在内存中存放,可以将key/version文件排序,在内存中构建稀疏索引,采用二分查找来查询所需的key和 version。

由于索引数据可以全放入内存,相比于B+树,Hash索引更具有查询优势。因此采用基本LongObjectHashMap充当索引,即Key -> Versions的映射,Versions保存了key所有的v,以及该key所拥有的pages。

3. 读写实现

写入接口的传入的是一个package,我们对package中相同的key进行压缩合并,同时和可能溢出int,但是不会超过long,因此对合并之后的delta进行压缩。然后逐个遍历不同的key,通过hash(key)取得key的分区Id,根据当前分区的索引判断key是否需要开辟一个page,如果不需要就将delta追加至已存在的page中。否则就开辟新page,并且将新的page位置添加至索引中。key/version/off追加至id.key文件。

key只会在一个文件中,只需找到相应的bucket中的Map索引,遍历Versions中的version即可,因为delta是聚集存储,基本上一次IO即可完成查询。

  • 压缩

    Package中可能有多个相同的key,由于Package内共享一个version,因此可以认为相同的key的delta可以累加为1个。n个key的field占用空间M = (32 + log2n)*64 /8

4. 细节优化
  1. 缓存

    由于写入和读取在引擎侧基本都是内存复用,评测结束还有3.5G左右的内存空闲,但是由于评测程序占用内存的峰值在2G左右,我们采用了通用的1.8G固定大小的缓存。还有些没有采用的定向优化方案,比如二阶段写入时缓存替换、绕过峰值追加缓存等等

  2. JVM gc参数调优

  • 调大年轻代老年代的比例,减少Full GC次数,线上Full gc由于之前1:1 的至少三次降至最多一次

  • 使用-XX:+UseAdaptiveSizePolicy`自适应调节STW和吞吐

    最终gc的耗时在4秒左右

  1. 减少索引的内存占用,复用对象等。
5. Java的不足

赛后我们也在想为什么与cpp的差距,往往Java和cpp的差距在于内存占用,本次比赛中cpp的程序总共占用在1.5G以内,包括测评程序。而Java的内存占用在3G左右,导致的差距就是缓存的容量,cpp可以缓存2.5G,而Java最多可缓存1.8G的数据。

6. 总结

从第一个版本的900秒至最后的85秒,这是一个对赛题认知的过程,比赛就是比赛,当然能做到工程化的扩展是加分项,但是如果连决赛都进不去,那就毫无意义了。

这篇关于第二届华为云数据库挑战赛参赛总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/855993

相关文章

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

使用shardingsphere实现mysql数据库分片方式

《使用shardingsphere实现mysql数据库分片方式》本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置... 目录一、ShardingSphere 简介1.1 对比1.2 核心概念1.3 Sharding-Sp

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

MySQL 数据库表与查询操作实战案例

《MySQL数据库表与查询操作实战案例》本文将通过实际案例,详细介绍MySQL中数据库表的设计、数据插入以及常用的查询操作,帮助初学者快速上手,感兴趣的朋友跟随小编一起看看吧... 目录mysql 数据库表操作与查询实战案例项目一:产品相关数据库设计与创建一、数据库及表结构设计二、数据库与表的创建项目二:员