Bigtable: A Distributed Storage System for Structured Data

2003年USENIX,出自谷歌,开启分布式大数据时代的三篇论文之一,底层依赖 GFS 存储,上层供 MapReduce 查询使用

Abstract

是一种分布式结构化数据存储管理系统,存储量级是PB级别。存储的数据类型和延时要求差异都很大。论文介绍数 bigtable 的数据模型。

Introduction

BigTable 达成了几个目标:适用面广、伸缩性好、高性能、高可用。即可以满足吞吐导向的批处理的需求,也满足延迟敏感服务的需求。很多时候 BigTable 看起来像数据库,但又有不同的接口层。不支持全部关系数据模型、支持动态控制数据布局和格式。支持数据再底层存储时候的属性推断。数据用字符串作为行列名建索引。BigTable 把数据当字符串。

Data Model

BigTable 是一个稀疏、分布式、持久化、多维存储的字典(map)。map 由一个 row key、column key、timestamp 组合建索引,map 的值是字节流(array of bytes)。(row:string, column:string, time:int64) → string,以下是一个具体的例子:
在这里插入图片描述
这个 Webtable 表存储了网页内容,和引用该网页的网页地址。

Rows

对一个 row key 的读写都是原子的,不管里面包含了多少列。这个设计使得客户端使用的时候更好做并发控制。

BigTable按照字典序存储 row key。行范围动态划分,一个范围称为一个 tablet,其作为分布式存储平衡的单元。这个性质帮助客户端探索数据的局部性存储,得到更高的效率。比如对于 webtable 来说,同一个网站的页面因为 url 的倒序排列而聚集到一起。

Column Families

column keys 聚集到 column families 里面,column families 作为访问控制的基本单元。同一个 column families 的数据通常来说有相同的数据类型,并且系统会把数据放一起压缩。column family 先创建,再使用。系统的用意就是 column family 的数量比较少,并且不经常变动。相反,column 的数量不做限制。

一个 column key 的格式 family:qualifier,例如对于 webtable 来说,一个 column family是 language family。里面只有一个 column key,存储网页的 language ID。另一个 column family 是 anchor,如图一所示。

Timestamps

每个 BigTable 的单元格可以存储同一份数据的多个版本,版本号就是 timestamp。并且从大到小倒序排列。为了高效管理,系统支持设置保留最近几个版本,或者回收多久以前的旧版本。

API

提供了基本的API来控制 BigTable,比如创建表,改变列,访问控制等。一个简单的例子:

// Open the table
Table *T = OpenOrDie("/bigtable/web/webtable");
// Write a new anchor and delete an old anchor
RowMutation r1(T, "com.cnn.www");
r1.Set("anchor:www.c-span.org", "CNN");
r1.Delete("anchor:www.abc.com");
Operation op;        // 原子的将这些改变落地
Apply(&op, &r1)

还有一个用 Scanner 来扫描特定行列的例子:

Scanner scanner(T);
ScanStream *stream;
stream = scanner.FetchColumnFamily("anchor");
stream->SetReturnAllVersions();
scanner.Lookup("com.cnn.www");
for (; !stream->Done(); stream->Next()) {printf("%s %s %lld %s\n",scanner.RowName(),stream->ColumnName(),stream->MicroTimestamp(),stream->Value());
}

BigTable 支持单行的事务,用 read-modify-write 模式保证原子性。支持单元格计数。支持服务器上执行客户端提供的脚本,脚本功能是对数据进行转化,过滤,统计等操作。

Building Blocks

BigTable 依赖几个谷歌内部的基础服务,第一个就是GFS。

存储文件格式是 Google SSTable 文件格式。这个格式是一种持久化,有序、不可变的 key -> value 映射格式,key 和 value 都是字符串的二进制数组形式。每一个 SSTable 包括连续的 blocks,一个 block 64KB。block index 用于查找 block。当 SSTable 打开的时候,block index 载入内存,通过二分查找找到合适的索引。然后从磁盘读取合适的 block。此外 SSTable 还可以映射到内存中,这样可以完全避免磁盘操作。

BigTable 还依赖一个高可用的分布式锁服务 Chubby。Chubby 有5个服务组成,其中一个是 master,用来处理请求。当超过一半副本存活的时候,集群可用。Chubby 使用 Paxos 算法来保持副本间的一致性。Chubby 基本可以看作是 zookeeper 的谷歌版。客户端和 Chubby 保持session,能一致性的读写小文件,文件带锁,Chubby 支持对保存文件注册回调函数。

BigTable 用 Chubby 有几个不同用处:确保任何时刻只有最多一个 master;存储 bootstrap 文件地址;tablet 服务发现和死亡摘除;存储表的 schema 信息(每张表的 column family);保存存储权限列表。Chubby 不可用了,BigTable 也就不可用了。

5 Implementation

整体有三大组件:客户端需要链接的依赖库,一个 master Server,一堆 tablet Servers。tablet server 可以动态加入或者移除集群。

master 的职责是分配 tablets 给 tablet servers;发现并加入 tablet server,删除过期的 tablet server,平衡 tablet servers 之间的负载,垃圾回收无效的文件,表格 schema 的变化。

tablet Server 负责一系列的 tablet,包括读写请求,对于增长过大的 tablet 负责分裂。

client 也是直接和 tablet Server 进行读写数据通信。client 不依赖 master 获取 tablet 的定位信息,绝大多数 client 不会和 master进行通讯。

一个 BigTable 集群储存多张 table,每个 table 由多个 tablet 组成,每个 tablet 里面存储 row range 里面的全部数据。一开始,一张 table 只有一个 tablet,随着 table 数据增长,会自动分裂成多个 tablet,每一个 tablet 大约100~200M

5.1 Tablet Location

三层结构存储 tablet 位置信息的 B+ 树
在这里插入图片描述
Chubby 里面保存 root tablet 的地址,root tablet 不会分裂,里面保存其他所有 MetaData 里的 tablet,而MetaData 里面的 tablet 里保存 user tablet 的位置信息。

MetaData table 保存一个 row key 存储在 tablet 的位置信息,这个位置信息是 tablet 对其所属 table 标识符和row key的开始行和结束行的 encoding。其中存储的是以开始和结尾的Row Key作为键,tablet位置作为值的映射。每一个 MetaData row 差不多1KB,通常128MB的大小的 MetaData tablet 限制,三层的 location schema 能存储2^34 个 tablets。

client 会 cache tablet 的位置信息,如果 cache 中没有或者不正确,就递归的向上查找。这个位置信息存储在内存中,客户端在读取时也会采取“预取”策略,一次读取多个 tablet 位置信息。

MetaData 里面还存储一些二级信息,例如事件日志,用于调试。

5.2 Tablet Assignment

master 追踪所有 tablet Server,一个 tablet 一个时刻也只能分配给一个 tablet Server。
当一个 tablet 没有被分配,如果出现足够资源的 tablet Server,master 就会将其分配给这个 tablet Server。

BigTable 用 Chubby 来追踪 tablet Server。当 tablet Server 启动的时候,在 Chubby 的一个特定目录下申请一个排它锁(一个唯一文件名的文件)。master 会一直监控这个目录以感知 tablet Server 的变化。当 tablet Server 不服务的时候,就会释放 Chubby 上的锁。

master 会周期性的询问 tablet Server 是否还持有 Chubby 上的锁。如果 tablet 不持有或者无法应答 master 的请求,master 会尝试获取这个 tablet Server 的锁,并删除这个文件对应的锁。之后 master 会标记 tablets 为不可用。当 master 和 Chubby 断链,master 会自动退出,并不改变 tablet 的分配。

当 master 启动时,执行一下操作(1)获取 Chubby 上的 mater 锁,确保只有一个 master(2)master 扫描 Chubby 上的 server 目录,发现活着的 tablet Server。(3)和每个 tablet Server 通讯,查询被分配的 tablet(4)扫描 MetaData 表,如果遇到 tablet 没有被分配,标记为未分配。后续会对未分配的 tablet 做分配。

一个复杂的情况是扫描 MetaData 表的时候,MetaData tablet 本身就还未分配。因此在执行步骤(4)之前,如果 root table 没有 分配,master 把 root tablet 标记为未分配。因为 root table 包含所有 MetaData 的 tablets,所以 master 扫描 root table 之后就能扫描全部的 MetaData。

一个已有的 tablet 只有创建/删除、合并、分裂的时候才会改变。当 tablet 分裂时,tablet Server 往 MetaData 中记录新的 tablet,之后会通知 master。

5.3 Tablet Serving在这里插入图片描述

更新操作提交到 commit log 中,作为重做记录(redo log)。整体这块的顺序是WAL(write after log)。最近的一些更新提交存储在内存中,有序存储,这块儿叫做 memtable;老一些的更新提交存储在磁盘上的 sequence SSTable 上。所以可以看出来,一个 tablet 由三部分组成,磁盘上的 tablet log,一系列的 SSTable 文件,以及内存上的 memtable。这种操作在后续的 ElasticSearch 上也有体现。

为了恢复一个 tablet Server,tablet Server 会先读取其 MetaData 知道包含哪些 SSTable,并且 MetaData 里有一系列的重做指针,指向 commit log。tablet Server 读取 SSTable 索引,并通过重做指针指向的更新提交,重建 memtable。

新来一个写操作的时候,先校验格式、鉴权。通过之后先写都 commit log 里。多个 commit 聚合起来写,提升吞吐,写完之后,再把内容写入到 memtable。

读操作也是先校验,鉴权,然后在 memtable 和 SSTable 里面查询,并将结果合并。

5.4 Compactions

随着 memtable 越来越大,达到阈值之后冻结转化成 SSTable,写入GFS,同时创建一个新的 memtable。这个操作叫 minor compaction,能较少内存使用,也能较少 commit log 的大小。

minor compaction 每次都会创建一个 SSTable,放任不管小文件会越来越多。因此还需要控制文件数量, BigTable 通过一个默认的线程执行 major compaction 来达成。这个操作读取新生成的小碎 SSTable,然后合并写入一个新的大的 SSTable 里。

在 major compaction 会删除之前 SSTable 里面标记软删除的数据。

6 Refinements

Locality groups(存储位置分组)

Compression(数据压缩)

Caching for read performance(读时缓存)

Bloom filters(布隆过滤器)

例如5.3节里的图例表示,需要读取 tablet Server 下所有的 tablet 来获取最新的数据,这会有比较多的磁盘读取操作。在 tablet Server 上建立 bloom filter,验真查找的 row-cloumn 对是否在某个 SSTable 上,减少磁盘操作。

Speeding up tablet recovery(恢复加速)

master 移动一个 tablet 的时候,原来的 tablet Server 对这个 tablet 先做一次 minor compaction,这样能减少 commit log,从而加速恢复。然后该 tablet Server 停止对这个 tablet 服务。在确保卸载完全之前,还会在做一次 minor compaction,彻底干掉内存里的 commit log。

Exploiting immutability(不可变性)

除了SSTable缓存之外,Bigtable 系统的其他各个部分都被简化了,因为我们生成的所有 SSTable 都是不可变的。例如,当从SSTables 读取时,我们不需要同步访问文件系统。因此可以非常有效地实现对行的并发控制。读写都可以访问的唯一可变数据结构是 memtable。为了减少读取 memtable 时的争用,我们在写时复制每个memtable 行,并允许读和写并行进行。

由于 SSTables 是不可变的,永久删除已删除数据的问题转化为垃圾收集过时的 SSTables。每个 tablet Server 的 SSTable 都注册在 MetaData 中。主进程删除过时的 SSTables,作为对 SSTables 集的标记和清除垃圾回收,其中元数据表包含根集。

最后,SSTables 的不变性使得能够快速分割 tablet。我们不为每个子 tablet 生成一组新的 SSTable,而是让子 tablet 共享父tablet 的 SSTables。

9 Lessons

作者总结了大型分布式系统的一些经验

第一条经验:大型分布式系统容易受到多种失败类型的困扰,不仅仅是标准的网络不通,故障停止(fail-stop)等。例如内存和网络崩溃、锁倾斜、机器宕机、非对称的网络分裂、依赖系统的 bug、GFS配额超限、硬件过保等等。作者通过修改协议来缓解。例如在 RPC 里面增加校验和,去掉对依赖系统的一些假设。

第二大经验:除非清楚新功能有什么用,否则延迟增加新需求很重要。例如作者想实现【事务】的时候,等实际使用了来,才发现只需要实现单行级别的事务就可以了。

第三大经验:系统级的监控非常重要(例如监控 BigTable 本身和使用 BigTable 的客户端)。例如扩展了RPC系统,用于追踪系统通过RPC做的重要动作。这个特性帮助排查解决了很多问题。

最重要的经验:设计简单的价值。考虑到我们系统的规模,以及代码随着时间的推移以意想不到的方式演变的事实,我们发现代码和设计的清晰性对代码维护和调试有着巨大的帮助。其中一个例子就是我们的tablet服务器成员协议。我们的第一个协议很简单:主机定期向tablet服务器发出租约,如果租约到期,tablet服务器就会自杀。不幸的是,这种协议在出现网络问题时会大大降低可用性,而且对主恢复时间也很敏感。我们重新设计了几次协议,直到我们有了一个性能良好的协议。但是,生成的协议太复杂,并且依赖于其他应用程序很少使用的Chubby功能的行为。 我们发现,不仅在Bigtable代码中,而且在Chubby代码中,我们花费大量时间调试晦涩难解的案例。 最终,我们放弃了该协议,转而使用仅依赖于广泛使用的Chubby功能的更新的更简单协议。

参考链接:
https://zhuanlan.zhihu.com/p/338566270
https://zhuanlan.zhihu.com/p/164926186
https://zhuanlan.zhihu.com/p/158607288

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/27563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有监督学习——梯度下降

1. 梯度下降 梯度下降(Gradient Descent)是计算机计算能力有限的条件下启用的逐步逼近、迭代求解方法,在理论上不保证下降求得最优解。 e.g. 假设有三维曲面表达函数空间,长(x)、宽(y)轴为子变量,高(z)是因变量&…

大模型企业落地:汽车行业知识大模型应用

前言 在当今这个信息爆炸的时代,知识管理成为了企业提升核心竞争力的关键。特别是在汽车行业这样一个技术密集、信息量庞大的领域,如何高效管理和利用知识资源,成为了每个企业必须面对的挑战。 汽车行业的知识管理痛点 汽车行业作为现代工…

10.错误处理

标题 一、概述二、panic!与不可恢复错误2.1 出错时2.2 示例2.3 panic!的 backtrace 三、Result 与可恢复的错误3.1 引入3.2 错误示例3.3 传播错误1)概念2)传播错误示例3)传播错误的简写:?运算符 一、概述 Rust将错误分…

springboot网上书店管理系统-计算机毕业设计源码03780

摘 要 网上书店管理系统采用B/S结构、java开发语言、以及Mysql数据库等技术。系统主要分为管理员和用户两部分,管理员管理主要功能包括:首页、站点管理(轮播图)用户管理(管理员、注册用户)内容管理&#x…

深入理解ReentrantLock

深入理解ReentrantLock 在Java并发编程中,锁(Lock)是控制多个线程对共享资源访问的重要工具。虽然Synchronized关键字是实现锁的常用方式,但它在功能上比较有限。ReentrantLock是java.util.concurrent.locks包中提供的一个更加灵…

FreeRTOS移植:STM32L476 nucleo-L476RG 开发板《02》

系列文章 FreeRTOS移植:STM32L476 nucleo-L476RG 开发板《01》 说明 上一篇 FreeRTOS移植:STM32L476 nucleo-L476RG 开发板《01》 主要讲了一下如何快速搭建一个 STM32 裸机工程,其实 STM32CubeMX 可以生成 FreeRTOS 的工程,这就…

Linux host映射 设置主机名并通过主机名找到指定系统

一、windows ping linux 1.windows进入到 C:\Windows\System32\drivers\etc\hosts 内,使用edit with notepad打开hosts文件,在下面添加需要寻找的ip以及其主机名。该ip以及主机名即linux的一致。需要查看linux主机名的在终端使用 hostname进行查看&#…

spring boot3登录开发-邮箱登录/注册接口实现

⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 🌊山高路远,行路漫漫,终有归途 目录 写在前面 上文衔接 内容简介 功能分析 所需依赖 邮箱验证登录/注册实现 1.创建交互对象 2.登录注册业务逻辑实…

JDK17 你的下一个白月光

JDK版本升级的非常快,现在已经到JDK20了。JDK版本虽多,但应用最广泛的还得是JDK8,正所谓“他发任他发,我用Java8”。 但实际情况却不是这样,越来越多的java工程师拥抱 JDK17,于是了解了一下 JDK17新语法&a…

Star-CCM+自动网格执行方法与设置技巧

在Star中进行一个仿真项目时,有时会创建多个自动网格。网格创建结束后需要执行。在Star中,网格执行可以分为三种。分别是:单独执行操作;多个执行操作;全部执行操作。接下来将三种执行操作的方法与步骤进行介绍。 其次,如果不习惯用自定义控制网格,有时在一个项目中就会…

大模型+人工智能:重塑地方志管理的新力量

前言 在科技日新月异的今天,人工智能(AI)正以前所未有的速度渗透到各个领域,改变着我们的工作和生活方式。特别是在地方志管理这一领域,大模型和人工智能的结合正在开启一场深刻的变革。今天,就让我们一起…

【复旦邱锡鹏教授《神经网络与深度学习公开课》笔记】梯度的反向传播算法

矩阵微积分(Matrix Calculus) 在开始之前,需要先了解矩阵微积分的一些计算规则。 首先,对于矩阵微积分的表示,通常由两种符号约定: 分母布局 标量关于向量的导数为列向量 向量关于标量的导数为行向量 N维…

LDR6500:手机电脑拓展坞转接器方案的卓越之选

随着科技的飞速发展,手机和电脑已成为我们日常生活中不可或缺的工具。然而,它们的接口有限,经常难以满足我们多样化的需求。这时,一款高效、稳定的拓展坞转接器就显得尤为重要。LDR6500,作为乐得瑞科技精心研发的USB P…

【计算机视觉(10)】

基于Python的OpenCV基础入门——图像滤波去噪 图像滤波去噪均值滤波中值滤波高斯滤波双边滤波方框滤波图像滤波去噪代码实现及其效果图 图像滤波去噪 图像滤波去噪是一种图像处理方法,它通过应用滤波器来减少或消除图像中的噪声。噪声是图像中不希望的、无用的、干…

安装sqlserver2022 express

1、下载 SQL Server 下载 | Microsoft 双击sql2022-ssei-expr 2、安装 下载完成以后,将会出现以下对话框 : 点击【全新SQL Server独立安装或向现有安全添加功能】 下一步,下一步: 下一步: 下一步,这里我…

【LeetCode:2779. 数组的最大美丽值 + 排序 + 二分】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

【docker】如何解决artalk的跨域访问问题

今天折腾halo的时候,发现artalk出现跨域访问报错,内容如下。 Access to fetch at https://artk.musnow.top/api/stat from origin https://halo.musnow.top has been blocked by CORS policy: The Access-Control-Allow-Origin header contains multipl…

Kotlin编程实践-【Java如何调用Kotlin中带默认值参数的函数】

问题 如果你有一个带有默认参数值的 Kotlin 函数,如何从 Java 调用它而无须为每个参数显式指定值? 方案 为函数添加注解JvmOverloads。 也就是为Java添加重载方法,这样Java调用Kotlin的方法时就不用传递全部的参数了。 示例 在 Kotlin …

企业环保创A标准

在环保日益受到重视的今天,企业如何有效地进行环保管理,提高自身的环保水平,已成为一个不可忽视的议题。而企业环保创A标准,正是为了评估企业的环保水平和环保管理能力而制定的一项重要评价标准。朗观视觉小编将详细解析企业环保创…

XILINX 7系列XDMA使用_IP核介绍以及工程搭建

文章目录 一、XDMA IP核1.1、接口说明1.2、配置页说明 二、XDMA工程搭建2.1、BD搭建2.2 Linux下XDMA驱动安装2.3 Linux下使用XDMA进行数据传输 一、XDMA IP核 1.1、接口说明 sys_clk:主机给PCIE提供的时钟信号,通过原理图查看 sys_rst_n:主机…