首页 > 其他分享 >mini-lsm通关笔记Week2Overview

mini-lsm通关笔记Week2Overview

时间:2024-09-25 18:50:37浏览次数:10  
标签:mini 存储 SST lsm 合并 引擎 key Week2Overview 放大

Week 2 Overview: Compaction and Persistence

在上周,您已经实现了LSM存储引擎的所有必要结构,并且您的存储引擎已经支持读写接口。在本周中,我们将深入探讨SST文件的磁盘组织,并研究在系统中实现性能和成本效益的最佳方法。我们将花4天时间学习不同的compaction策略,从最简单的到最复杂的,然后为存储引擎持久化实现剩下的部分。在本周结束时,您将拥有一个功能齐全且高效的LSM存储引擎。

合并和读放大

我们先来说说合并。在前面的部分中,我们简单地将memtable转储到一个L0 SST中。想象一下,你已经写入了千兆字节的数据,现在你有100个SST。每个读请求(不过滤)需要从这些SST读取100个块。这个放大就是读放大——一个get操作需要发送到磁盘的I/O请求数。

为了减少读取放大,我们可以将所有L0 SST合并到一个更大的结构中,这样就可以只读取一个SST和一个块来检索请求的数据。假设我们还有这100个SST,现在,我们对这100个SST进行合并排序,以生成另外100个SST,每个SST都包含不重叠的键值范围。这个过程就是合并,这100个不重叠的SST就是一个排序的run

为了使这一过程更加清晰,让我们来看一个具体的示例:

SST 1: key range 00000 - key 10000, 1000 keys
SST 2: key range 00005 - key 10005, 1000 keys
SST 3: key range 00010 - key 10010, 1000 keys

在LSM结构中,我们有3个SST。如果我们需要访问键02333,我们需要探测这3个SST。如果我们可以进行合并,我们可能会得到以下3个新的SST:

SST 4: key range 00000 - key 03000, 1000 keys
SST 5: key range 03001 - key 06000, 1000 keys
SST 6: key range 06000 - key 10010, 1000 keys

通过合并SST 1、2和3创建3个新SST。我们可以得到一个排序后的3000个key,然后将它们拆分成3个文件,这样就可以避免一个超大的SST文件。现在我们的LSM状态有3个不重叠的SST,我们只需要访问SST 4,找到键02333。

合并和写放大的两个极端

因此,从上面的例子中,我们有2种幼稚的方法来处理LSM结构—根本不进行合并,和总是在转储新的SST时进行完全合并。

合并是一个耗时的操作。它需要从某些文件中读取所有数据,并将相同数量的文件写入磁盘。这个操作会占用大量的CPU资源和I/O资源。完全不做合并会导致高读放大,但它不需要写入新文件。总是执行完全合并可以减少读取放大,但它需要不断地重写磁盘上的文件。

转储到磁盘的memtables与写入磁盘的总数据的比值就是写放大。也就是说,没有合并的写放大率是1倍,因为一旦SST被转储到磁盘,它们就会一直停留在那里。总是做合并有非常高的写放大。如果我们在每次获取SST时都执行一次完全合并,那么写入磁盘的数据将是转储SST数量的二次方。例如,如果我们将100个SST转储到磁盘,我们将执行2个文件、3个文件、...100个文件的合并,其中我们实际写入磁盘的数据总量约为5000个SST。在这种情况下,写入100个SST后的写放大将是50倍。

一个好的合并策略可以在读放大、写放大和空间放大(我们后面会讲到)之间取得平衡。在通用的LSM存储引擎中,通常不可能找到一种策略,可以在所有这3个因素中实现最低的放大,除非引擎可以使用某些特定的数据模式。LSM的好处是,我们可以从理论上分析合并策略的放大,所有这些事情都发生在后台。我们可以选择合并策略,并动态地改变其中的一些参数,从而将我们的存储引擎调整到最佳状态。合并策略都是关于权衡的,基于LSM的存储引擎让我们可以在运行时选择要交换的内容。

业内一个典型的业务场景是这样的:用户在启动一个产品时,首先将数据批量注入到存储引擎中,通常是每秒千兆字节。然后,系统上线,用户开始在系统上做小交易。在第一阶段,引擎应该能够快速存储数据,因此我们可以使用最小化写入放大的合并策略来加速这一过程。然后,我们调整合并算法的参数,使其针对读放大进行优化,并做一次完全的合并,对已有的数据进行重新排序,这样系统上线后就可以稳定运行了。

如果业务场景类似于时间序列数据库,则用户可能总是按时间填充和截断数据。因此,即使没有合并,这些append-only的数据仍然可以在磁盘上具有低放大。因此,在现实生活中,你应该注意用户的模式或特定需求,并利用这些信息来优化你的系统。

合并策略概述

合并策略通常的目的是控制排序的run层数,从而使读放大保持在一个合理的数量。通常有两类合并策略:分级(leveled)和分层(tiered)。

在分级合并中,用户可以指定最大级别数,即系统中排序的run的层数(L0除外)。例如,RocksDB通常在分级合并模式下保持6级(排序的run)。在合并过程中,来自两个相邻层的SST将被合并,然后产生的SST将被放到两个层的较低层。因此,在分级合并中,您通常会看到一个小的排序的run与一个大的排序的run合并。排序的run(级别)在大小上呈指数增长-较低的级别在大小上将是较高的级别的<some number>倍。

在分层合并中,引擎将通过合并它们或让转储新的SST作为新的排序的run(层)来动态调整排序的run的数量,以最小化写入放大。在此策略中,您通常会看到引擎合并两个大小相等的排序的run。如果合并策略不选择合并层,则层数可能会很高,因此读取放大率会很高。在本教程中,我们将实现RocksDB的通用合并,这是一种分层合并策略。

空间放大

计算空间放大的最直观方法是将LSM引擎使用的实际空间除以用户空间使用量(即数据库大小或数据库中的行数等)。引擎将需要存储删除的墓碑,有时,如果合并发生得不够频繁,则会有同一个键的多个版本,因此会导致空间放大。

在引擎端,通常很难知道用户存储的确切数据量,除非我们扫描整个数据库,看看引擎中到底有多少个不再使用的版本。因此,估计空间放大的一种方法是将完整存储文件大小除以最后一级大小。这种估算方法背后的假设是,用户填充初始数据后,工作负载的插入率和删除率应该是相同的。我们假设用户端的数据大小不会改变,因此最后一层包含用户数据在某个时刻的快照,而上层包含新的更改。当合并将所有内容合并到最后一层时,使用这种估计方法,我们可以得到1x的空间放大系数。

请注意,合并也会占用空间——在合并完成之前,您不能删除正在合并的文件。如果您对数据库执行完全合并,您将需要与当前引擎文件大小相同的可用存储空间。

在这一部分中,我们将有一个合并模拟器来帮助你可视化合并过程和你的合并算法的决策。我们提供了最小的测试用例来检查您的合并算法的属性,您应该密切关注统计信息和合并模拟器的输出,以了解您的合并算法的工作情况。

持久化

在实现了合并算法之后,我们将在系统中实现两个关键组件:manifest,这是一个存储LSM状态的文件,WAL,它将memtable数据持久化到磁盘,然后作为SST刷新。完成这两个组件后,存储引擎将拥有完整的持久化支持,可以在您的产品中使用。

如果不想太深入探讨合并,也可以先看完2.1和2.2章,实现一个非常简单的Leveled合并算法,直接进入持久化部分。在第2周构建一个可工作的存储引擎时,不需要实现完全的leveled合并和universal合并。

零食时间

在实现了合并和持久化之后,我们将有一个关于实现批量写入接口和校验和的简短章节。

标签:mini,存储,SST,lsm,合并,引擎,key,Week2Overview,放大
From: https://www.cnblogs.com/cnyuyang/p/18431966

相关文章

  • 006.MinIO基础使用
    006.MinIO基础使用 目录图形界面使用bucketAccesskeys配置权限MonitoringTieringSiteReplication客户端使用mc客户端安装bucketobjectPolicyUserGroupsconfig集群管理curl工具使用 回到顶部图形界面使用bucketbucket创建图形界面创建b......
  • Minio生命周期规则及桶初始化
    packageorg.ailun;importio.minio.*;importio.minio.messages.*;importjava.util.List;/***@version1.0*@since:JDK11*/publicclassTest{privatestaticStringbucketName="bucketName";publicstaticvoidmain(String[......
  • CF164D Minimum Diameter 题解
    最小点覆盖模板题。思路考虑二分直径\(x\)。我们将距离\(>x\)的点对连一条边,那么每一条边的两端至少有一端需要被删掉。这是最小点覆盖的定义。那么就是判断最小点覆盖是否小于等于\(k\)。发现这个问题并不好用一些多项式复杂度的做法解决。考虑暴搜。每一次我们把度......
  • Ubuntu 上安装 Miniconda
    一、下载Miniconda打开终端。访问Anaconda官方仓库下载页面https://repo.anaconda.com/miniconda/选择Miniconda3-py310_24.7.1-0-Linux-x86_64.sh,进行下载。文件名当中的py310_24.7.1表示,在conda的默认的base环境中的Python版本是3.10,Miniconda版本是24.7.1。二......
  • Spring Boot+MinIO实战:掌握分片上传、秒传与断点续传,让文件管理更高效!
    在现代应用中,随着文件大小的不断增大和网络环境的复杂化,传统的文件上传方式已难以满足用户需求。通过将SpringBoot与MinIO集成,可以轻松实现文件的分片上传、秒传和续传功能,为用户提供更流畅的上传体验。分片上传分片上传是将大文件拆分成多个小块分别上传,避免单次上传大文件带......
  • minimind复现记录
    ......
  • IP地址+VLSM
    IP地址全局范围内定位设备----IP地址(32位)192.168.1.111——点分十进制——IPV4地址表示格式4组十进制IPV4地址范围:0.0.0.0——255.255.255.255IANA机构——五大类A类:第一个8位组的第一位一定取值为0   子网掩码/8=255.0.0.0最小:0.0.0.0最大:127.255.255.25......
  • Mini-git,了解文件如何存储在 Git 对象中
    昨天,我开始自己实现Git的核心功能之一——具体来说,文件是如何存储的、Git对象是什么、以及哈希和压缩的过程。我花了4个小时来开发,在这篇文章中,我将向您介绍我的思考过程和方法。当您提交文件时会发生什么?当您在Git中提交文件时,会在幕后发生几个重要步骤:文件压......
  • 实战教程:Minio与etcd本地部署 + Milvus本地数据库配置(亲测成功)
    一.minio本地部署1.获取安装包wgethttps://dl.minio.io/server/minio/release/linux-amd64/miniowgethttps://dl.min.io/client/mc/release/linux-amd64/mcchmod+xminiochmod+xmc#命令移到系统路径直接调用命令cpminio/use/local/bincpmc/use/local/......
  • openGemini 发布人才培养计划,与顶尖的数据库专家并肩成长
    一、摘要在技术革新的浪潮中,数据库技术是现代信息技术的基石,openGemini社区携手开发者,启动人才培养计划,旨在培养新一代云原生数据库技术人才,共同推动云原生数据库技术创新。二、社区介绍openGemini是一款开源的云原生分布式时序数据库,专注于海量可观测性数据的存储和分析,2022......