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

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

相关文章

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.

Oracle数据库常见字段类型大全以及超详细解析

《Oracle数据库常见字段类型大全以及超详细解析》在Oracle数据库中查询特定表的字段个数通常需要使用SQL语句来完成,:本文主要介绍Oracle数据库常见字段类型大全以及超详细解析,文中通过... 目录前言一、字符类型(Character)1、CHAR:定长字符数据类型2、VARCHAR2:变长字符数

Win11安装PostgreSQL数据库的两种方式详细步骤

《Win11安装PostgreSQL数据库的两种方式详细步骤》PostgreSQL是备受业界青睐的关系型数据库,尤其是在地理空间和移动领域,:本文主要介绍Win11安装PostgreSQL数据库的... 目录一、exe文件安装 (推荐)下载安装包1. 选择操作系统2. 跳转到EDB(PostgreSQL 的

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

mysql数据库重置表主键id的实现

《mysql数据库重置表主键id的实现》在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,本文主要介绍了mysql数据库重置表主键id的实现,具有一定的参考价值,感兴趣的可以了... 目录关键语法演示案例在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,当我们

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma

java常见报错及解决方案总结

《java常见报错及解决方案总结》:本文主要介绍Java编程中常见错误类型及示例,包括语法错误、空指针异常、数组下标越界、类型转换异常、文件未找到异常、除以零异常、非法线程操作异常、方法未定义异常... 目录1. 语法错误 (Syntax Errors)示例 1:解决方案:2. 空指针异常 (NullPoi

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES