Google Vortex流式存储引擎分析

2024-06-22 22:28

本文主要是介绍Google Vortex流式存储引擎分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者:archimekai,转载请注明出处
参考文献: Edara, P., Forbesj, J., & Li, B. (2024). Vortex: A Stream-oriented Storage Engine For Big Data Analytics. Companion of the 2024 International Conference on Management of Data, 175–187. https://doi.org/10.1145/3626246.3653396

文章目录

  • Vortex: A Stream-oriented Storage Engine For Big Data Analytics
    • 为什么?
      • 现有批量数据处理的问题
      • 路线选择
    • 是什么?
    • 核心概念
        • vortex stream
        • streamlet
        • fragment
        • WOS与ROS
    • 架构
      • Stream Server
      • SMS
      • SOS
      • Thick Client Library
      • 负载均衡和故障恢复
    • 核心API示例
    • 写入流程
    • 读取流程
    • 总结

Vortex: A Stream-oriented Storage Engine For Big Data Analytics

免责声明:为了行文连贯,本文中掺杂了一些笔者的推测,请务必对照原论文阅读以免被误导。欢迎批评指正!

为什么?

在数据流(continuous stream)上的数据分析,缩短了从数据产生,到洞察见解的时间。为了更好地支持数据流上的分析,Google BigQuery构建了Vortex系统以支持实时分析。Vortex是一个把数据流放在首要位置的存储系统,其既能支持流式分析,又能支持批处理。借助于Vortex,BigQuery能够支持PB级数据的亚秒级导入和查询。

现有批量数据处理的问题

  • 新鲜度:流式数据处理对数据新鲜度的要求较高,现有的离线批量数据导入架构(新鲜度在小时级、天级)无法满足。
  • 数据丢失:生成流式数据的应用,通常运行在资源高度受限的环境中。这样的应用难以在本地缓存较多数据,常常需要对数据进行采样以减少数据量,导致数据流式。
  • 多次拷贝:批量数据处理中需要多次将中间结果写入临时存储,增加了数据处理时延,难以进行数据管理

路线选择

  • 路线一:将现有的批处理改造为支持处理流式数据(Spark)
  • 路线二:专门为流式数据处理构建系统,然后将这个系统也用在批处理上(Flink)

Vortex选择了后者。

是什么?

Vortex是一个专为(流式)追加写(append)优化的存储引擎。

  • 在架构上,Vortex是高度分布式的,在*region粒度(TODO 待确认)*进行数据复制(可用性较高)的存储引擎
  • 在可扩展性上,vortex的数据面和控制面均是分布式的,能够支持单表PB级数据
  • 在API上,Vortex为批处理和流处理提供了统一的API
  • 在事务能力上,Vortex的所有API均支持ACID性质
  • 在性能上,vortex提供亚秒级写入的SLA,这样客户端无需预留很大的buffer缓存要写入的数据
  • 在数据类型上,Vortex支持结构化和半结构化数据(见Dremel论文,本次不介绍)

下面本文将从核心概念,架构,API,写入读取流程等方面对Vortex进行分析,并总结一些vortex设计中值得我们借鉴的思路。

核心概念

在这里插入图片描述
如上图所示,stream是Vortex的核心概念,笔者将围绕stream展开介绍。

vortex stream

Vortex Stream(下文简称stream)是基于BigQuery Table的抽象。在同一个BigQuery Table上,可以同时存在多个stream,因此一个BigQuery Table也可以被视为多个stream的集合。

stream是用来承载写入和读取操作的实体。用户将要写入的行追加到stream的末尾(注意每个stream在当前时刻的末尾都是确定的)。当前已写入stream的行数,也被叫做stream的长度(length)。每一个写入stream的行,都会获得一个row offset。一个客户端可以创建一个或多个stream并发写入同一张表。一张表可以支持上万个客户端同时写入(从而能够达到很快的并发写入速度)。

同一个stream可以被多个reader并发读取。

在Vortex系统内部,一个stream由若干个streamlet组成,一个streamlet又由若干个fragment组成。

streamlet

streamlet由一组连续的行组成,是数据持久性(数据复制)管理的最小单位。为了保证数据的持久性(durability),每行数据(每个streamlet)至少要被写入两个borg cluster才会被认为写入成功。一个stream由一个或多个streamlet组成。stream中最多有一个streamlet是可写的,其必然是stream中的最后一个streamlet。对于可写的streamlet,其元信息(例如streamlet的当前长度)由stream server管理,spanner中保存的元信息仅作为缓存使用。对于已经写完的streamlet,spanner中会保存准确的元信息。

备注:streamlet有点类似于CU。

fragment

streamlet中的行可以进一步被分为若干组连续的行,被叫做fragment。也即一个streamlet由若干个fragment组成。fragment是数据物理存储管理的最小单位。fragment保存在colossus文件系统中的日志文件内。
fragment的大小按如下方式确定:(1)fragment不能太大,以便存储优化服务能比较快地把WOS转换为ROS (2)fragment不能太小,以免在元信息中创建太多的fragment,加重元信息管理的负担。 当向Fragment中写入数据时,Stream Server会缓存最大2MB的数据再写入。

每个fragment上还带有两个时间戳:creation_timestamp, deletion_timestamp。数据读取请求同样携带着一个快照时间戳snapshot_timestamp,通过比较这三个时间戳,可以判断fragment是否对数据读取请求可见。fragment可见的条件为:creation_timestamp <= snapshot_timestamp < deletion_timestamp

Fragment File Format: 如下图所示,文件头中有一个File Map。File Map列出了相同streamlet中的所有已经写入过的Fragment的信息。文件头中还有一个TrueTime时间戳。当数据写入后,还会在文件尾写入一个布隆过滤器,写入一个定长的文件尾。对于BUFFERED类型的流,在进行flush时,还会向Fragment中记录一个元信息,以保存flush时提交到了哪个row offset。
在这里插入图片描述

streamlet和fragment对用户不可见,相关信息记录在Spanner中。

WOS与ROS

WOS:write optimized storage format。当数据通过vortex的写入API进入系统后,首先以这种格式存储。顾名思义,这种格式对写入速度比较友好。

ROS: read optimized storage format。数据被写入一段时间后,会被后台的整理任务整理为ROS格式。ROS的主要由两种,也即capacitor和parquet。

架构

在这里插入图片描述

如上图所示,vortex中主要包括stream server, SMS, SOS三个组件。在客户端运行着vortex的client library。

Stream Server

stream server组成vortex的数据平面。stream server负责管理streamlet和fragment的元信息,并通过事务日志和检查点的方式确保上述元信息被持久化。Fragment被存储在colossus上的日志文件中,检查点、事务日志同样也被存储在colossus中。每个borg cluster中常常有上百个stream server。

  • Fragment文件:见上文
  • 日志文件:日志文件中会多保存一份File Map,以便BigQuery读取数据时,能直接通过Stream Server的日志文件确认有哪些fragments要读取

SMS

SMS即stream metadata server。SMS组成vortex的控制平面。SMS管理stream,streamlet、fragment,并将streamlet分配给某一个Stream Server负责处理。

SOS

SOS即Storage Optimization Service。将WOS转为ROS,并将旧数据标记为已删除。SOS以LSM树的方式维护Fragments。首先,SOS将WOS转换为ROS,同时减少Fragment的数量。SOS还会在后台进行自动数据聚簇。

Thick Client Library

之所以叫做厚客户端,是因为vortex的客户端可以绕过SMS直接同stream server交互,并且支持故障重试。

负载均衡和故障恢复

BigQuery的框架中,每个用户的工作负载由一个主borg cluster和一个辅borg cluster负责处理。具体到Vortex的处理逻辑,当用户使用Vortex写入数据时,优先由主borg cluster进行处理。当主borg cluster暂时不可用时,vortex会透明地转移到辅borg cluster上继续处理。

主borg cluster是以table为粒度进行分配的。也就是说,一个table只能有一个主borg cluster负责处理,多个table的负载可以被均衡到多个borg cluster上。一个table的元信息由主borg cluster中的一个SMS负责处理。Google的数据应用程序负载均衡服务Slicer会监控SMS的状态,当SMS不可用时,Slicer会自动将table的管理任务迁移到主borg cluster中的其他SMS上。当某个SMS负载过高时,Slicer同样会执行类似的迁移动作。由于table的元信息由Spanner管理,元信息的一致性可以由Spanner保证。

核心API示例

enum StreamType {
STREAM_TYPE_UNBUFFERED = 0,
STREAM_TYPE_BUFFERED = 1,
STREAM_TYPE_PENDING = 2,
};
CreateStreamOptions options;
options.set_stream_type(STREAM_TYPE_UNBUFFERED);
Stream s = CreateStream(table_name, options);RowSet row_set;
// Populate row_set from the input data and the schema.
// ...
// Append data to the end of a Stream.
AppendStreamResponse response = AppendStream(s, row_set,
[row_offset]);Status status = FlushStream(s, row_offset)std::vector<Stream> streams = GetStreams();
Status status = BatchCommitStreams(streams);Status status = FinalizeStream(s);

写入流程

在这里插入图片描述
大体流程如下:

  • vortex client发送写入请求到SMS
  • SMS找到或创建一个未使用的stream,并确保有一个stream server上已创建该stream的streamlet。
  • SMS告诉客户端streamlet id和stream server的地址。
  • 客户端建立一条到stream server的长连接,以便向streamlet写入数据。

推测的细节如下:

client slicer SMS stream server colossus spanner 本图为推测 CreateStream select a SMS based on load,etc CreateStream select a stream server based on load,etc 返回id,地址给客户端 Create Streamlet data transfer (AppendStream(streamletid)) 何时创建frag? create fragment snappy compress encrypt write frag loop [max buffer 2MB] finish fragment update metadata loop [fragments] flush stream write commit record create new stream let 重复上面的写入过程 FinalizeStream client slicer SMS stream server colossus spanner

备注:默认情况下,Vortex不会应用主键约束。也就是用户可以创建主键,但是Vortex仍然允许主键重复。如果用户希望确保主键的唯一性,用户在写入数据时应该只使用UPSERT,DELETE这两种操作,这样vortex就会按照主键的语义操作数据。

读取流程

推测的读取流程如下:

client bigquery spanner Stream Server colossus select xxx gen_snapshot_time() get_frags() (if ss is online,把ss当成缓存用) get_frags() get_frags() (ROS+WOS) filter frags based on snapshot_time read data in frags until last record client bigquery spanner Stream Server colossus

关键点:BigQuery支持直接从colossus上读取vortex所写入的文件。

总结

Vortex中以下设计值得学习:

  • 面向写入和读取,使用不同的存储格式,从而兼顾写入性能和读取性能
  • 使用thick client library,减轻服务器的压力
  • 写入需要server的,但是读取可以不要server,直接让客户端从分布式存储上读,从而降低存储成本

这篇关于Google Vortex流式存储引擎分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Redis存储的列表分页和检索的实现方法

《Redis存储的列表分页和检索的实现方法》在Redis中,列表(List)是一种有序的数据结构,通常用于存储一系列元素,由于列表是有序的,可以通过索引来访问元素,因此可以很方便地实现分页和检索功能,... 目录一、Redis 列表的基本操作二、分页实现三、检索实现3.1 方法 1:客户端过滤3.2 方法

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实