-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
blockio #144
Comments
github.com/facebook/rocksdb/pull/12937/files |
https://ronekins.com/2024/01/16/how-to-reduce-linux-block-storage-io-sizes/ max_hw_sectors_kb (read-only) > max_sectors_kb (read/write) 注意max_sectors_kb大小 一个sector 512B https://kernel.dk/when-2mb-turns-into-512k.pdf IO调度,是存在组合的 bio 256 个page 4k 多个bio 组合成batch |
https://fee-mendes.gitbook.io/scylladb-mc-compare#tests-and-results seastar简单场景是没优势的。 停止对技术名字的神圣化 |
https://www.scylladb.com/2017/07/31/database-caches-not-good/ 多一跳 外部缓存破坏后段数据缓存。这个点可以,需要重放 热key 点查,防止冷冲击 外部缓存不安全 存疑 外部缓存没有更好的和数据库后段数据联动,这个和前面的 有点冲突 防止冷启动/proxy预热是比较重要的点 |
This comment was marked as resolved.
This comment was marked as resolved.
Vortex 的主要特点: 一个可扩展的、最先进的列式文件格式 parquet 定制太多,跟进麻烦,使用复杂 但新写一个能解决这个问题吗? |
How Rockset Separates Compute and Storage Using RocksDB https://rockset.com/blog/separate-compute-storage-rocksdb/ Rockset 将计算与存储分离。虚拟实例(VIs)是计算和内存资源的分配,负责数据摄取、转换和查询。Rockset 的热存储层由许多附加 SSD 的存储节点组成,以提高性能。 在底层,Rockset 使用 RocksDB 作为其嵌入式存储引擎,该引擎设计用于可变性。Rockset 在 RocksDB 之上创建了 RocksDB-Cloud 库,以利用新的云架构。RocksDB-Cloud 通过与 Amazon S3 等云服务集成,即使在机器故障时也能提供数据持久性。这使 Rockset 可以拥有分层存储架构,其中一份热数据存储在 SSD 上以提高性能,副本存储在 S3 中以增强持久性。这个分层存储架构为 Rockset 客户带来了更好的性价比。 在设计热存储层时,我们牢记以下设计原则: 类似于紧耦合计算存储架构的查询性能 RocksDB 是一种流行的日志结构合并 (LSM) 树存储引擎,设计用于处理高写入速率。在 LSM 树架构中,新写入会写入内存表 (memtable),并在内存表填满后将其刷入不可变的排序字符串表 (SST) 文件。Rockset 执行 RocksDB memtable 的细粒度复制,以确保实时更新的延迟不依赖于 SST 文件的创建和分发过程。 SST 文件被压缩成统一的存储块以提高存储效率。当数据发生变化时,RocksDB 删除旧的 SST 文件并创建一个包含更新数据的新文件。这种压缩过程类似于语言运行时中的垃圾收集,定期运行以删除过时的数据版本,防止数据库膨胀。 新的 SST 文件会上传到 S3 以确保持久性。然后热存储层从 S3 提取文件以提高性能。这些文件是不可变的,这简化了热存储层的角色:它只需要发现和存储新创建的 SST 文件,并逐出旧的 SST 文件。 在执行查询时,RocksDB 从热存储层请求数据块,每个块由文件中的偏移量和大小表示。RocksDB 还会在计算节点缓存最近访问的块,以便快速检索。 除了数据文件外,RocksDB 还将元数据信息存储在 MANIFEST 文件中,这些文件跟踪表示当前数据库版本的数据文件。这些元数据文件每个数据库实例固定数量且体积较小。元数据文件是可变的,在创建新 SST 文件时会更新,但查询执行时很少读取。 与 SST 文件不同,元数据文件存储在计算节点和 S3 上以确保持久性,但不存储在热存储层上。由于元数据文件体积小且很少从 S3 读取,将它们存储在计算节点上不会影响可扩展性或性能。此外,这简化了存储层,因为它只需要支持不可变文件。 Rockset 将数据写入 S3 并从 SSD 中读取以实现快速查询性能。 数据在热存储层中的放置 从高层次来说,Rockset 的热存储层是一个 S3 缓存。一旦文件被写入 S3 就认为是持久的,并且会根据需求从 S3 下载到热存储层。然而,Rockset 的热存储层使用了广泛的技术来实现 99.9999% 的缓存命中率。 在热存储层分配 RocksDB 数据 每个 Rockset 集合(或关系世界中的表)被分成多个切片,每个切片包含一组 SST 文件。切片由属于这些 SST 文件的所有块组成。热存储层在切片粒度上做出数据放置决策。 Rendezvous 哈希用于将切片映射到其对应的存储节点,一个主要节点和一个次要节点。哈希值还被计算节点用于识别从哪个存储节点获取数据。Rendezvous 哈希算法的工作原理如下: 为每个集合切片和存储节点分配一个 ID。这些 ID 是静态的,永远不会改变。 当存储节点数量变化时,它会产生最小的移位。添加或移除热存储层中的节点时,更改所有者的集合切片数量将与节点数量 (N) 成正比,即 (1/N)。这使热存储层实现快速扩展。 设计可靠性、性能和存储效率 所有关键分布式系统的重要目标是始终可用并有良好性能。构建在 Rockset 上的实时分析具有严苛的可靠性和延迟目标,这直接转化为对热存储层的严格要求。因为我们始终可以从 S3 读取数据,所以我们将热存储层的可靠性视为我们能够以磁盘级延迟提供读取服务的能力。 计算-存储分离性能的维护 最小化通过网络请求数据块的开销 为了确保 Rockset 的计算-存储分离具有良好性能,其架构设计尽量减少了网络调用和数据从磁盘提取所需的时间。因为通过网络请求块可能比本地磁盘读取更慢。许多实时系统的计算节点将数据集保留在附加存储中,以避免这种负面性能影响。Rockset 采用了缓存、预读取和并行化技术来限制网络调用的影响。 Rockset 通过增加一个额外的缓存层,即以 SSD 为支撑的持久性次级缓存 (PSC),来扩展计算节点上可用的缓存空间,以支持大型工作数据集。计算节点包含内存块缓存和 PSC。PSC 在计算节点上有固定的存储空间,用于存储从内存块缓存中最近逐出的 RocksDB 块。与内存块缓存不同,PSC 中的数据在处理重启之间是持久的,从而确保可预测的性能并减少从热存储层请求缓存数据的需求。 避免查询时从 S3 读取数据 从热存储层检索的块比从 S3 的读取未命中快 100 倍,时间差异从小于 1 毫秒到 100 毫秒。因此,避免在查询路径中下载 S3 数据对于像 Rockset 这样的实时系统至关重要。 如果某个计算节点请求一个热存储层中不存在的文件块,则存储节点必须在将请求块发送回计算节点之前从 S3 下载 SST 文件。为了满足客户的延迟要求,我们必须确保查询时需要的所有块在计算节点请求之前都在热存储层中可用。热存储层通过三种机制实现这一点: 每当创建新 SST 文件时,计算节点都会向热存储层发送同步预取请求。这发生在 memtable 刷新和压缩过程中。RocksDB 在热存储层下载文件后提交 memtable 刷新或压缩操作,确保计算节点在请求块之前文件可用。 为了确保可靠性,Rockset 在热存储层的不同存储节点上存储了最多两份文件副本。Rendezvous 哈希用于确定数据切片的主要和次要所有者存储节点。主要所有者通过计算节点发出的预取 RPC 和扫描 S3,积极下载每个切片的文件。次要所有者仅在计算节点读取文件后才下载该文件。为了在扩展事件中保持可靠性,前一个所有者会在新所有者下载数据之前保留一个副本。在此期间,计算节点将前一个所有者用作块请求的备用目标。 在设计热存储层时,我们意识到可以通过只存储部分副本来节省存储成本,同时实现弹性。我们使用 LRU 数据结构来确保即使丢失其中一个副本,查询所需的数据仍然可用。我们在热存储层分配固定数量的磁盘空间作为次级副本文件的 LRU 缓存。从生产测试中我们发现,存储大约 30-40% 的数据副本,加上计算节点上的内存块缓存和 PSC,就足以避免从 S3 检索数据,即使在存储节点崩溃的情况下。 pod本身无状态,有secondary cache pvc共享一个盘,然后后端接入S3 PVC等于S3缓存 利用备用缓冲容量提高可靠性 Rockset 通过动态调整 LRU 尺寸来进一步减少磁盘容量需求。在其他数据系统中,缓冲容量被保留用于将新数据引入存储层并下载数据。我们使热存储层在本地磁盘使用上更加高效,通过填充动态调整大小的 LRU 来利用缓冲容量。LRU 的动态性质意味着当对引入和下载数据的需求增加时,我们可以缩小用于次级副本的空间。通过这种存储设计,Rockset 充分利用存储节点的磁盘容量,使用备用缓冲容量来存储数据。 我们还选择在摄取速度快于存储速度的情况下,将主副本存储在 LRU 中。在理论上,所有虚拟实例的累积摄取速率可能超过热存储层扩展容量的速率,此时 Rockset 将耗尽磁盘空间并停止摄取数据。如果没有 LRU,这将导致摄取停止。通过将主副本存储在 LRU 中,Rockset 可以逐出最近未访问的主副本数据,以便为新数据腾出空间,从而继续摄取和服务查询。 通过减少我们存储的数据量以及利用更多可用磁盘空间,我们显著降低了运行热存储层的成本。 单副本世界中的安全代码部署 所有文件的 LRU 顺序持久在磁盘上,以便在部署和进程重启后保持。但是,我们还需要确保在没有第二个完整数据集副本的情况下进行安全部署或扩展集群。 典型的滚动代码部署包括关闭运行旧版本的进程,然后启动运行新版本的进程。这样,在旧进程已排空和新进程已准备好之间会有一段时间的停机,使我们不得不在两个不理想的选项之间进行选择: 接受在此期间存储在存储节点上的文件将不可用。在这种情况下,查询性能可能会受到影响,因为其他存储节点需要按需下载计算节点请求的 SST 文件,直到存储节点重新上线。 在每个存储节点上运行旧版本代码的进程时,同时启动运行新版本代码的第二个进程。由于这个新进程运行在相同的硬件上,因此它也可以访问已存储在该节点上的所有 SST 文件。 除了保证零不可用性之外,这个过程还带来了巨大的操作好处。启动新版本服务和新版本开始处理请求的时间点是截然不同的步骤。这意味着我们可以启动新进程,逐渐增加它们的流量,并在不启动新进程、节点或任何数据移动的情况下立即回滚到旧版本。立即回滚意味着减少问题发生的机会。 热存储层的缩放操作以提高存储效率 增加存储节点以增加容量 热存储层确保有足够的容量来存储每个文件的副本。当系统接近容量时,会自动向集群添加更多节点。现有节点会在新节点获取数据切片后,即刻放弃这些数据切片,使其他文件有空间存放。 搜索协议确保计算节点仍然能够找到数据块,即使数据切片的所有者已更改。如果我们同时添加 N 个存储节点,切片的前一个所有者将在 Rendezvous 哈希算法中的最多第 (N+1) 位。 因此,如果块在热存储层中可用,计算节点可以通过并行联系列表中的第 2、第 3、...(第 N+1)个服务器来始终找到一个块。 减少存储节点以减少容量 如果热存储层检测到资源过度配置,它将减少节点数量以降低成本。简单地缩减一个节点会导致从 S3 的读取未命中,而剩余的存储节点需要下载被移除节点之前拥有的数据。为了避免这种情况,被移除的节点进入“预排空”状态: 被指定删除的存储节点将数据切片发送到下一个存储节点。下一个存储节点由 Rendezvous 哈希确定。 计算和存储节点之间的通信协议 为了避免在查询时访问 S3,计算节点希望从最有可能在本地磁盘上拥有数据的存储节点请求数据块。计算节点通过乐观搜索协议实现这一目标: 计算节点通过 TryReadBlock RPC 向主要所有者发送仅磁盘数据块请求。如果块不在该存储节点的本地磁盘上,该 RPC 将返回空结果。与此同时,计算节点向次要所有者发送 Existence 检查,通过 BlockExists RPC 返回一个布尔标志,指示该块是否在次要所有者处可用。 如果两个所有者都不能立即提供数据,计算节点向数据切片的指定备份目的地发送 BlockExists RPC。该目的地是根据 Rendezvous 哈希确定的下一个存储节点。如果备份指示该块在本地可用,计算节点就从那里读取数据。 如果这些存储节点之一本地拥有文件,则读取可以快速完成(小于 1 毫秒)。在完全缓存未命中的极少数情况下,ReadBlock RPC 同步从 S3 下载数据,耗时 50-100 毫秒。这种情况下查询可用性得到保证,但查询延迟增加。 该协议的目标: 避免同步 S3 下载的需求,如果请求的块在热存储层中的任何地方存在。上文 (3) 中计算节点联系的故障恢复存储节点数量可以大于一个,以增加找到数据块的可能性。 |
https://smalldatum.blogspot.com/2024/07/searching-for-regressions-in-rocksdb.html
The text was updated successfully, but these errors were encountered: