论文分享 | FAST'23 阿里云提出的针对SMR优化的存储引擎SMRSTORE
今天分享的一篇最近阅读的论文是FAST'23的SMRstore: A Storage Engine for Cloud Object Storage on HM-SMR Drives。
https://www.usenix.org/conference/fast23/presentation/zhou
这篇文章是由阿里巴巴公司完成的,在这篇文章中,团队针对SMR的特性提出了一种新的存储引擎SMRSTORE,该存储引擎充分利用了SMR更高的存储密度来降低最高15%成本,并通过优秀的设计使得效率与CMR集群相当,对于阿里云这样的大规模存储集群而言,降低15%的成本且不需要付出性能代价会带来很大的收益。
如果对于不了解SMR的读者,可以点击副推查看相应知识点,对SMR硬盘有了一定的认识后也就不难理解阿里提出该引擎的根本动机——降低成本。但是,要降低成本,必须要以可接受的最小限度的性能牺牲为前提,接下来,我们就继续来看看,阿里采用了什么手段来优化SMR的性能。
我们先把结论放在前面,以下的优化手段类似于ZNS:
1)SMRSTORE直接管理了全部的地址空间,取代了文件系统,将空间划分为zone,每个zone只能append顺序写入,禁止随机写入;
2)无论元数据还是数据,都采用log的形式写入SMR顺序zone;
3)GC是导致性能下降的关键,指导数据放置,设计相关策略,每个zone只允许相似生命周期的数据共享,并尽可能为大数据分配完整zone。
背景
对象存储往往需要使用到大量的HDD,成本效益是构建一个具有竞争力的云对象存储的关键挑战。由于SMR的出现,通过堆叠磁道相较于CMR增加了25%的存储密度,但是由于对随机写的限制,需要设计新的软件栈或存储引擎。
当前市面上针对HM-SMR存在三种软件栈设计方式,分别位于不同的层次,首先是块IO子系统层,通过设计STL将SMR映射成为普通块设备(dm-zoned),其次是文件系统层,支持日志结构或copy-on-write的文件系统也可以直接适配SMR特性(F2FS),最后是实现于应用层(GearDB)或是直接应用于Alibaba Archive Storage Service 、Huawei Object Store等服务。
文章分析认为,应用dm-zoned由于随机更新会使得吞吐量严重下滑,应用F2FS等文件系统由于大量GC会导致吞吐量的剧烈变化(文章第三章结合数据进行了测试),因此,前两种方法并不使用于实际,阿里巴巴团队选择了结合阿里OSS架构,利用ZBD接口,综合设计了GC、全日志化的直接设计了一个运行于用户态的存储引擎SMTSTORE。
OSS Workflow

本次研发的SMRSTORE将应用于Alibaba Cloud Object Storage Service (OSS),因此,文章有必要介绍一下当前OSS工作流,OSS IO栈包含一个前端层、一个服务层和一个称为盘古的分布式存储持久化层,前端层的工作主要是处理HTTP请求,并将其发送到服务层,服务层由大量的KV服务器组成,它主要是两个职责,一个是将对象写入到盘古,另一个是使用基于LSM-Tree的KV存储维护对象的元数据(从对象名称到相应PANGU文件中的位置的映射),并将这些元数据写入额外的PANGU文件。
盘古是一个分布式文件系统,每个盘古集群由一组主服务器master和大量的仓储服务器chunkserver组成,主服务器中管理了盘古文件的元数据信息,仓储服务器中存储了盘古文件的具体数据。每个仓储服务器由60个负责存储的HDD和2个负责缓存的SSD组成,对于HDD利用Linux软件栈进行IO,采用EXT4文件系统管理,对于SSD则使用了一个自主设计的存储文件系统。

对于一个盘古文件,它都是一个只支持追加写的而且可能被切分存放于若干个大块Chunk,每个Chunk有一个唯一的UUID,盘古可以创建、追加写入、读、删除以及封装一个Chunk。封装操作会在1)Chunk大小达到限制;2)应用程序关闭了盘古文件或者写操作完成;3)遇到错误。时触发,因此,Chunk的大小不是固定的。对于一个盘古文件,只有最后一个Chunk可以被写入,只有已经封装的Chunk会从SSD缓存中持久化入HDD存储。盘古文件系统还设计了冗余和纠删码等功能以提供数据的容错能力。

上图表示了传统OSS中数据流,我们假设要写入一个Object Foo,首先在KV Server中找到对应的盘古文件及其偏移和大小,然后KV Server联系盘古主服务器,定位对应盘古文件的最后一个chunk的chunkserver,并由这个chunkserver将数据追加写入chunk对应的EXT4文件中,为了数据完整性检验,每个写入被切分为4KB大小,前4048B为数据,后48B为段位置和Checksum的footer,在每个chunkserver中,每个chunk在EXT4文件系统中的名字就是它的ChunkID。
将一个打开的盘古文件定义为流,一个流始于KV服务器打开了一个盘古文件,终于KV服务器关闭了盘古文件,根据操作和数据类别的不同,可以将流划分为以下五种,并且它们具有不同的服务要求:

设计
从前面的背景中可以看出,HDD存在与仓储服务器中,将CMR替换为SMR在原来的EXT4+Kernel场景下已经不再适用,再结合之前的分析,无论是使用dm-zoned还是F2FS,都不足以满足阿里的高性能要求,因此,需要针对仓储服务器的HDD相关模块设计新的存储引擎以支持SMR。

设计主要解决了以下几个关键挑战:
1)数据在存储引擎上应当如何排布?
所有的地址空间都由SMRSTORE管理。地址空间被划分为superzone、metazone、datazone,采用“record”作为metazone和datazone的基本单元。这样的排布方式似乎有点类似于F2FS:

但是,无论metazone还是datazone,在SMRSTORE中均是日志化的顺序写入,以下图方式排列:

如图所示,superzone为第一个SMR zone,存放了格式化版本、时间戳和其他一些系统配置,metazone为紧接着400个zone,存放了SMRSTORE的一些元数据,它们由3种不同类别的record组成,剩余均为datazone,由2种类别的record组成,data record中的负载按4KB进行切片和添加footer,从而允许只对DataRecord进行部分读取并校验完整性。
2)在之前的EXT4系统中,采用ChunkID为文件名的方式,索引Chunk,在新的存储引擎中如何设计数据索引?

数据索引存在于内存中,建立了ChunkID+offset+size到Datazone+offset+size的三元组映射。一个Chunk可以有多个record,它们都按照数据在Chunk中的偏移进行排序并构成一个Index Group链表,链表的起始地址保存在ChunkTable中,对一个Chunk+offset+size的访问流程就是查ChunkTable,再查链表,从而定位Datazone+offset+size。
需要注意的是,具体的查找算法在论文中并没有讨论,采用的数据结构和占用内存大小也没有具体说明。
3)区块该如何管理?
区块管理上,SMRSTORE基本和ZNS一致,采用了一个状态转换自动机对zone进行管理:

SMRSTORE维护了一个Zone Table,关联了ZoneID、状态、关联到zone的索引链表、写指针信息。在区块分配时,为了最大可能使得同一区块内的数据生命周期接近以及性能的稳定,分配时遵循以下原则:
仅允许相同流类型(见上表,他们具有接近的期望存在时间)的chunk共享一个datazone;
调整了最大的chunkSize=datazoneSize,使得对于大chunk,可以完整占据一个zone;
采用池化zone,为每个type的流预先分配和打开一定数量的zone。

4)垃圾回收应该怎么进行?
垃圾回收的步骤非常经典:受害段选择、数据迁移和元数据更新。受害段选择使用了贪心算法选取垃圾最多的zone回收,数据迁移时扫描zone关联的有效的索引,将他们的数据迁移到干净zone,并设置了一个动态的GC吞吐量阀门以避免后台GC对前台性能产生影响,元数据更新将对应的索引关系更新,即完成了整个垃圾回收过程。
5)启动时如何恢复当前拓扑结构?(recovery逻辑)
最后一个问题是如何恢复内存中数据结构,比如上面都有提及的metadata table和zone table,手段是将他们每隔一段时间存放在metazone里面。
SMRSTORE设计了checkpoint,作为当前内存中数据结构的快照。checkpoint由若干个record组成用于记录相关的table(例如,metadata table比较大,需要若干record,zone table通常一个table就够了),一个checkpoint从特殊的start_record开始,到end_record结束。
SMRSTORE 对于chunk的创建、封装、删除操作会写入journal记录,但是不会记录写入(性能考虑,但有其他方法可以确保相应结构正确),因为checkpoint的设计是non-blocking的,checkpoint的records可能会和journal交叉,journal的存在确保数据结构可以被正确恢复。

一个完整的恢复过程是:
找到最近的一个checkpoint,实现方法是直接扫描整个metazone区域(前400个zone);
将checkpoint加载入内存恢复出checkpoint快照保存下来的数据结构;
重放start-end之间的所有journal,恢复在checkpoint之后的操作;
扫描datazone,由于没有journal记录写入,应该扫描datazone,将对应的有效的元数据更新写入内存;
论文的实验部分不是本文重点关注的内容,感兴趣的读者可以自行阅读,阅读原文可以快速直达。
相关文章:
论文分享 | FAST'23 阿里云提出的针对SMR优化的存储引擎SMRSTORE
今天分享的一篇最近阅读的论文是FAST23的SMRstore: A Storage Engine for Cloud Object Storage on HM-SMR Drives。 https://www.usenix.org/conference/fast23/presentation/zhou 这篇文章是由阿里巴巴公司完成的,在这篇文章中,团队针对SMR的特性提出了…...
题目:建造房屋 (蓝桥OJ3362)
问题描述: 代码: #include<bits/stdc.h> using namespace std; int n, m, k, ans, mod 1e9 7; long long dp[55][2605]; /*dp[i][j]:第i个街道上建j个房屋的总方案数枚举所有的转移,累加到dp[n][k]即总方案数 */ int main() {cin >> n &…...
智能合约平台开发指南
随着区块链技术的普及,智能合约平台已经成为了这个领域的一个重要趋势。智能合约可以自动化执行合同条款,大大减少了执行和监督合同条款所需的成本和时间。那么,如何开发一个智能合约平台呢?以下是一些关键步骤。 一、选择合适的区…...
数学建模-最优包衣厚度终点判别法(主成分分析)
💞💞 前言 hello hello~ ,这里是viperrrrrrr~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页ÿ…...
Mysql内存表及使用场景(12/16)
内存表(Memory引擎) InnoDB引擎使用B树作为主键索引,数据按照索引顺序存储,称为索引组织表(Index Organized Table)。 Memory引擎的数据和索引分开存储,数据以数组形式存放,主键索…...
Django交易商场
Hello,我是小恒不会java 最近学习django,写了一个demo,学到了不少东西。 我在GitHub上开源了,提示‘自行查看代码,维护,运行’。 最近有事,先发布代码了,我就随缘维护更新吧 介绍: 定…...
华为校园公开课走入上海交大,鸿蒙成为专业核心课程
4月12日,华为校园公开课在中国上海交通大学成功举办,吸引了来自计算机等相关专业的150余名学生参加。据了解,由吴帆、陈贵海、过敏意、吴晨涛、刘生钟等教授在中国上海交通大学面向计算机系本科生开设的《操作系统》课程,是该系学…...
【会员单位】泰州玉安环境工程有限公司
中华环保联合会理事单位 水环境治理专业委员会副主任委员单位 我会为会员单位提供服务: 1、企业宣传与技术项目对接; 2、企业标准、行业标准制定; 3、院士专家指导与人才培训 4、国际与国内会议交流 5、专精特新、小巨人等申报认证 6…...
Google视觉机器人超级汇总:从RT、RT-2到AutoRT/SARA-RT/RT-Trajectory、RT-H
前言 随着对视觉语言机器人研究的深入,发现Google的工作很值得深挖,比如RT-2 想到很多工作都是站在Google的肩上做产品和应用,Google真是科技进步的核心推动力,做了大量大模型的基础设施,服(推荐重点关注下Googl…...
LeetCode-1143. 最长公共子序列【字符串 动态规划】
LeetCode-1143. 最长公共子序列【字符串 动态规划】 题目描述:解题思路一:动规五部曲解题思路二:1维DP解题思路三:0 题目描述: 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。…...
从0开始创建单链表
前言 这次我来为大家讲解链表,首先我们来理解一下什么是单链表,我们可以将单链表想象成火车 每一节车厢装着货物和连接下一个车厢的链子,单链表也是如此,它是将一个又一个的数据封装到节点上,节点里不仅包含着数据&…...
STC89C52学习笔记(十)
STC89C52学习笔记(十) 综述:本文介绍了DS18B20和单总线协议,以及讲述了如何使用DS18B20测量温度。 一、单总线协议 1.只有一根通讯线:DQ (常见的运用单总线的两种设备:DS18B20和DHT11&#…...
初识二叉树和二叉树的基本操作
目录 一、树 1.什么是树 2. 与树相关的概念 二、二叉树 1.什么是二叉树 2.二叉树特点 3.满二叉树与完全二叉树 4.二叉树性质 相关题目: 5.二叉树的存储 6.二叉树的遍历和基本操作 二叉树的遍历 二叉树的基本操作 一、树 1.什么是树 子树是不相交的;…...
如何开辟动态二维数组(C语言)
1. 开辟动态二维数组 C语言标准库中并没有可以直接开辟动态二维数组的函数,但我们可以通过动态一维数组来模拟动态二维数组。 二维数组其实可以看作是一个存着"DataType []"类型数据的一维数组,也就是存放着一维数组地址的一维数组。 所以&…...
【MATLAB第104期】基于MATLAB的xgboost的敏感性分析/特征值排序计算(针对多输入单输出回归预测模型)
【MATLAB第104期】基于MATLAB的xgboost的敏感性分析/特征值排序计算(针对多输入单输出回归预测模型) 因matlab的xgboost训练模型不含敏感性分析算法,本文通过使用single算法,即单特征因素对输出影响进行分析,得出不同…...
C语言程序与设计——工程项目开发
之前我们已经了解了C语言的基础知识部分,掌握这些之后,基本就可以开发一些小程序了。在开发时,就会出现合作的情况,C语言是如何协作开发的呢,将在这一篇文章进行演示。 工程项目开发 在开发过程中,你接到…...
【Java核心技术】第6章 接口
1 接口 接口不是类,而是对希望符合这个接口的类的一组需求 1.1 Comparable 接口 要对对象进行比较,就要实现(implement)比较(comparable)接口 注意: implements Comparable<Manager> Comparable接口是泛型接口 class Manager exten…...
【Java探索之旅】从输入输出到猜数字游戏
🎥 屿小夏 : 个人主页 🔥个人专栏 : Java编程秘籍 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一、输入输出1.1 输出到控制台1.2 从键盘输入 二、猜数字游戏2.1 所需知识:…...
【动态规划】【01背包】Leetcode 1049. 最后一块石头的重量 II
【动态规划】【01背包】Leetcode 1049. 最后一块石头的重量 II 解法 ---------------🎈🎈题目链接🎈🎈------------------- 解法 😒: 我的代码实现> 动规五部曲 ✒️确定dp数组以及下标的含义 dp[j]表示容量为…...
2023 年上海市大学生程序设计竞赛 - 四月赛
A. 宝石划分 A. 宝石划分 - 2023 年上海市大学生程序设计竞赛 - 四月赛 - ECNU Online Judge 找距离N最近的M的因数q,输出M/q 如果是暴力所的话,会超时 #include <bits/stdc.h> using namespace std; int main(){ios::sync_with_stdio(false)…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
