【AICon】探索RAG 技术在实际应用中遇到的挑战及应对策略!AICon精华内容已上线73%>>> 了解详情
写点什么

亚军 watermelon 作品解析

  • 2019-11-25
  • 本文字数:2833 字

    阅读完需:约 9 分钟

亚军watermelon作品解析

今年夏天有幸参加了华为云 TaurusDB 性能挑战赛,并与众多优秀大咖同台竞技、切磋交流,我们感到十分荣幸。我们是一支名叫 watermelon 的三人组团队,均是在读研究生,分别来自浙江大学和上海交通大学,都是明年毕业。初赛和复赛的成绩都是第四名,历史成绩非常的稳定。


这里我们总结了此次参赛的体验,包括对题目重点的解读、我们设计的架构(网络、磁盘、缓存等),以及我们设计的每一个性能优化点。

题目重点解读

  • KV 都是定长的:这样简化了文件和内存的操作和管理。

  • value 远大于 key:把 KV 分离存储,解除索引和数据之间的耦合性。

  • 线程数固定:测评程序固定使用 16 个线程访问数据库。

  • 只需要保证进程意外退出时的持久性:所以可以利用操作系统的缓存对写入方式进行一些优化。

  • 分阶段测评:随机写、随机读、顺序读三个阶段互相没有重叠。

  • 计算节点无状态:我们知道,在这种基于共享存储的计算存储分离架构下,所有持久化数据只能存于存储节点,计算节点只进行逻辑操作。

  • 数据读取的线程和数据写入线程之间没有绑定关系:也就是说每个线程不是只读取自己写入的数据,与初赛不一样,读取线程 id 不一定读的是相同 id 写入的数据。

  • 最后,随机读的随机性在每个时刻只局限在一个 10M 热点分区内,并且热点分区按写入的顺序逆序推进。

核心架构

我们计算节点和存储节点的线程采用一对一的 tcp 连接,因为测评程序是 16 线程,所以连接数就是 16。在存储节点,我们有数据持久化产生的文件,以及读写文件的缓存。


在计算节点,我们维护了读数据的缓存,但是没有写数据的缓存,因为要保证计算节点被 kill 的数据持久性。并且我们的索引也是只在计算节点上维护的,在数据库启动阶段从存储节点把索引数据拉到计算节点。


文件组织形式

  • 首先,按写入线程进行数据的分区,也就是说每个写入线程按顺序写自己的分区文件,这样就避免了多线程写同一个文件冲突的问题。

  • 然后,在每个分区内,将 key 和 value 分离存储为两个文件,一个是 key log,一个是 value log,可以解除索引和数据之间的耦合性。并且我们为了提高写入 value 的速度,对 value 进行了缓存,缓存中凑齐若干个 value 后,再一起进行刷盘。

  • 为了保证缓存不丢失,缓存也使用了 mmap 的形式,因此对应有一个缓存文件。

  • 我们的索引也是按分区进行构建的,每个分区是一个 hash,里面存的是该分区所有数据的索引项,索引项就是一个 key 和 一个 value offset。


性能优化

复赛的优化历程,我们从最开始跑通的 2300s,到最后的 780s,中间经过了好几次架构和方法的改变。


  • 我们的第一个优化是,在启动阶段把 key 从存储节点批量的传到计算节点,这样相比每个 key 都请求一次,批量的方法相当于减少了一半的网络请求,使得时间提升了 300s。

  • 由于我们无法搞定网络传输大数据包的问题,因此我们选择先在存储节点实现顺序读和随机读的缓存,这样减少了存储节点的 io 次数,时间提升了 500s。

  • 我们解决了网络传输的问题,所以先在计算节点进行了顺序读的缓存,成绩提升到 1100s。

  • 我们按存储节点缓存一样的思路,把随机读缓存也拿到了计算节点,这样做之后我们的成绩就已经突破了 800s。

  • 最后我们又优化了一些细节问题,最终成绩是 781s。



围绕读写文件,缓存策略,和网络传输这三个方面,来讲解我们是如何把这个系统的性能提升到极致的。


读写文件

对于 key 这种小数据量的读写模式,采用 mmap 可以利用 page cache 将小数据读写转换为整个内存页的读写,减少了系统调用的时间消耗。value 的大小固定为 4KB,我们知道,写入数据大小要对齐 ssd 的内部 page 时,可以达到最优写入性能。


我们经过线上测试,按 1M 大小顺序写入数据可以达到最大吞吐量。所以,为每一个分区分配一个容量为 1M 的写缓冲区,写满 256 个 value 再将缓存数据一起刷盘,刷盘方式采用 direct io。并且,用 mmap 做缓存,可以保证数据持久性。

缓存策略

随机读的缓存要如何做,才能使得缓存命中率最高呢?


现在的背景是,随机读在每个时刻只局限在一个 10M 热点分区内,并且热点分区按写入的顺序逆序推进。


看图,上面是我们实际存储的文件,按 10M 分为了若干个 block,就是说,我们的缓存只能按 block 对齐进行加载数据。然后,下面是测评的热点分区示意图,我们发现一共 400w 数据,热点分区的边界跟实际数据 10M 边界很可能是不对齐的,并且边界值未知。所以,如果我们只用单个 10M 的缓存,会出现下面这样的问题。


假设当前阶段,测评程序要随机访问 hot1 这个热点分区。第一个位置,我们缓存加载了 block3,然后,访问第二个位置,发现缓存失效,加载了 block2,继续访问第三个位置,缓存又失效了,重现加载回了 block3 ,所以这样就产生了一个缓存来回震荡的问题,极端情况是,我要访问 400 万数据,一共要加载 400 万次大块的缓存,肯定超时,还不如不做缓存。



我们的方案是,采用两个 10M 的 buffer,一前一后,一起往前推进,这样非常完美的避免了缓存来回震荡的问题。并且这个 buffer 不一定是 10M,只要大于 10M 都可以解决这个问题。

网络传输

那么网络的传输效率又应该怎么做才最高呢?


我们发现,写入阶段的网络传输时间主要瓶颈是在周转时间上,也就是说,不是网络有多么拥塞导致网络传输变慢,而是说,value 发过去再回来,本身就需要这么长的时间。


所以我们的优化只能是让存储节点尽可能快的返回 ack 信号,我们的做法是在数据写入存储节点的 mmap 之后,就返回 ack,而不用等待 page cache 刷盘。对于持久性,recover 阶段会把 cache buffer 里面的数据都重新写进 value 文件里。



对于大块数据进行拆分,然后进行多次发送,可以在发送的同时进行流量控制,使吞吐量保持在一个较高的水平。我们的流量控制方法非常简单粗暴,在发送每两个 4k 数据之间,直接加一个延时,延时的方法是让 CPU 自旋一会。并且,存储节点也做了读缓存,把存储节点的读缓存,批量拆分传到计算节点。


整体架构解读

宏观上看,通过这次比赛,我们严格按照计算存储分离的思想来设计了我们的系统架构,对基于共享存储的计算存储分离架构有了一些认知和理解。


首先,我们看计算节点我们的架构只支持一个 RW 节点,进行数据的写入。但是 RO 节点在理论上是可以无限扩展的。并且,由于底层的共享存储,所以主从复制的延迟可以做到非常低。


当 RW 写入一个 kv 数据,对于 RO 节点,它只需要更新已经存在自己 buffer pool 中的数据,而如果发现 RW 写入的数据不在它的 buffer pool 中,那它什么也不做。只有在 RO 节点读取数据时,发现要请求的数据不在自己的 buffer pool 中,它才去下面的存储节点中拉取这个数据到自己的 buffer pool 中。


这样看来,我们在实现高可用功能时候,可以很直接的进行主从切换,RO 节点可以迅速提升为 RW 节点,直接开始对外服务。再看存储节点我们当前只是在单个节点上保证了数据的持久性,而这种 kv 存储可以扩展为分布式架构,采用多副本存储,从而能获得更好的容错性,和更好的读写性能。


所以这样一整套架构,可以解决很多实际的痛点,因此,会成为当今云数据库的一个趋势。



本文转载自 HW 云数据库。


2019-11-25 08:00539

评论

发布
暂无评论
发现更多内容

推荐一款优秀电商开源项目

越长大越悲伤

开源 推荐算法 电商 Java'

好家伙!GitHub公选“头牌”阿里大牛开源1300页炫彩性能调优手记

做梦都在改BUG

Java 性能优化 性能调优

阿里内部一份手打524页《Java中高级核心知识》令人犹如醍醐灌顶

程序知音

Java java面试 java架构 后端技术 Java面试八股文

十年程序老狗手写分布式服务架构:原理、设计与实战

小小怪下士

Java 程序员 分布式 后端

智慧改变公厕,市政智慧公厕方案解决城市公共厕所难题

光明源智慧厕所

智慧城市

AI日课@20230408:如何基于大模型训练一个自己的数字克隆

无人之路

ChatGPT

使用Tuxera NTFS Mac修护移动磁盘:步骤详解

Rose

Tuxera NTFS Mac2022 Tuxera NTFS教程 ntfs

5分钟搞懂5G安全增强

俞凡

5G 安全 网络 通信

开源7天Github斩获4.5万Stars!阿里2023版高并发设计实录鲨疯了

程序员小毕

数据库 程序员 面试 高并发 架构师

程序员未来是不是会大量失业?

Jackpop

失真函数、失真矩阵与平均失真

timerring

信息论

macOS 13 Ventura (苹果最新系统) v13.3.1正式版

Rose

macOS 13 Ventura 苹果最新系统 Macos13系统

Mac 触控增强神器BetterTouchTool详细图文使用教程

Rose

苹果电脑 BetterTouchTool破解 BetterTouchTool教程 Mac 触控板

Java岗程序员必备学习方向,全会拿45Koffer没问题!

Java你猿哥

Java 面试 面经 Java工程师 春招

肝完阿里最新Java并发编程全优笔记,我成功晋升公司架构组

Java你猿哥

Java 架构师 并发 面经 Java工程师

【AIGC未来的发展方向】面向人工智能的第一步,一文告诉你人工智能是什么以及未来的方向分析

洛神灬殇

人工智能 4月日更 AIGC ChatGPT

如何优雅地使用 Markdown?

Jackpop

简单好用的文件对比工具:Beyond Compare 4中文版

真大的脸盆

Mac Mac 软件 文件对比 文件对比工具 对比文件

Spring Boot自动配置原理详解和自定义封装实现starter

做梦都在改BUG

Java Spring Boot 自动配置

MouseBoost for Mac(右键助手)中文版

Rose

mac电脑 MouseBoost for Mac MouseBoost激活版 右键鼠标助手工具

sketch文件导出没有背景色怎么办? sketch背景色消失的解决办法

Rose

sketch Mac Sketch下载 sketch无背景

【算法数据结构专题】「延时队列算法」史上手把手教你针对层级时间轮(TimingWheel)实现延时队列的开发实战落地(下)

洛神灬殇

数据结构 算法训练 时间轮算法 时间轮(TimeWheel)

Cornerstone for Mac(最好用的SVN管理工具) v4.2永久激活版

Rose

mac软件下载 SVN客户端 cornerstone 4破解 Cornerstone mac版

【异常解决】postman请求提示Full authentication is required to access this resource

No8g攻城狮

测试 Postman

系统清理工具:Cocktail 16.3.3注册激活版

真大的脸盆

Mac Mac 软件 清理工具 清理优化 清理优化软件

哪个网站的电子书最多?

Jackpop

ChatGPT - SpringBoot Prompting Chain

Marvin Ma

软件开发 ChatGPT

AI Prompt Engineering 提示工程:提升你的创意与效率

kcodez

人工智能 ChatGPT 提示工程

有哪些 python 的在线练习题或编程挑战的网站?

Jackpop

流批一体数据交换引擎 etl-engine

weigeonlyyou

flink 消费 kafka 物联网 数据迁移 Kafka ETL 大数据‘’

Django笔记四之字段属性

Hunter熊

Python django model field 字段属性

亚军watermelon作品解析_语言 & 开发_HW云数据库_InfoQ精选文章