b站离线缓存删了还能找回来吗,b站卸载后缓存不见了怎么找回

首页 > 实用技巧 > 作者:YD1662023-11-01 15:21:33

方案一

  1. 进度信息持久化在MySQL中
  2. 接入层
  3. 对外提供RPC接口
  4. 由后端线程去MySQL中进行预分配(incr操作)。再从分配后的空间,对外提供ID分配操作。
  5. 每次重启后,先去MySQL中进行预分配,再对外提供服务
  6. 所有的接入层均对外提供分配操作(即上图中的取号器0、取号器1、取号器2都对外提供服务)

问题

方案一的缺点在于,MySQL仍然是单点。

方案二

  1. 方案二可以认为是方案一的改进版, 使用RAFT实现一个简单的KV
  2. 此KV对外提供INCR 操作。每次操作返回incr前后的值,作为接入层的安全分配区间
  3. 这样实现简单,也避免了MySQL的单点。
  4. 以braft单个raft group约5000 QPS的性能计算,每次预分配10000作为分配空间,分配性能足够。

问题

RAFT异常宕机时,约有5s左右的不可写入时间,因此需要计算(评估)合理的预分配范围,确保这段时间有足够的key可用。

新架构

新的架构如下所示:

b站离线缓存删了还能找回来吗,b站卸载后缓存不见了怎么找回(25)

Day10

对象存储系统,由于整体规模庞大,存储成本会有比较大的压力,这点与计算型系统有较大差别。到目前这个系统还是使用3副本的方式来保证数据的可靠性和服务的可用性。今天我们来降低副本数。Erase code(纠删码/EC)是目前比较常见的降副本的方式。其具体原理的细节这里不再赘述,一言以蔽之就是"时间换空间/CPU换存储"。

EC的基础功能

  1. 将原始数据切分为等长的数据块
  2. 通过对数据块进行矩阵计算,生成编码块(也称校验块)
  3. 数据块的数量用k表示,编码块的数量用m表示
  4. 所有的数据块和编码块的长度相等(先忽略数据块的padding问题)
  5. 从这(k m)个块中,任意取出其中的k个,可以通过矩阵运算的方式还原出(k m)个
  6. eg:
  7. 假设原始数据为(a,b,c,d,e,f), 使用k=6,m=3的方式,生成3个编码块(g,h,j),总共9个块
  8. 任意取其中的 b,c,e,f,h,j 则可以还原出a,d,g

如下图所示,编码的具体过程,由6个数据块生成3个编码块。

b站离线缓存删了还能找回来吗,b站卸载后缓存不见了怎么找回(26)

纠删码空间占用

  1. 副本数 = (k m)/m, 以k=6, m=3为例,则副本数为 1.5副本
  2. 3副本模式,可以理解为k=1,m=2的特殊场景

读写过程

b站离线缓存删了还能找回来吗,b站卸载后缓存不见了怎么找回(27)

如上图所示,我们可以对比下EC模式和3副本模式的写入过程。

副本模式时写入过程

  1. 根据key进行计算,得到数据应该存放到哪个shard上
  2. 由shard的信息,定位到对应的3个Replica的地址信息
  3. 将请求发送给Replica所在的节点进行写入即可(这3个节点位于不同的可用区中)

EC模式时写入过程

  1. 与副本模式的差别在于不再将原始数据发送给后端存储节点
  2. 而是先进行编码,然后将编码后的k m个块,发送给后端的节点
  3. 此时要求后端的Replica的数量等于 k m,而不是原来的3副本
  4. 这k m个Replica位于k m个节点,并且这些节点处于不同的可用区中
  5. 理论有k个实际写入成功即可(实际上会根据k和m的数量进行处理)

数据块和编码块间的顺序关系

  1. 由于这k m个Replica之间的数据是不一样的(可以观察图上数据块的颜色),而且数据块和编码块的之间也有顺序关系(比如返回给用户的时候,一定是按照(数据块0数据块1数据块2)的顺序),因此需要有地方来描述这些数据块之间的关系。
  2. 我们希望在读取之前就能确定这些块的关系,否则需要读取k个以上的块进行解码才能得知
  3. 这里我们在Replica的元数据中加入sn_in_shard 用来标识对应的k m个replica的先后关系(可以再查阅Day7时ReplicaModel的定义)

EC模式的读取过程

  1. IO服务收到读请求后,计算出key对应的shard
  2. 检查shard对应的k m个replica的信息,得到前k个replica(由sn_in_shard描述),优先将请求发送个给这k个replica。当这k个replica返回结果时,直接拼接原始数据返回即可(读取的时候,尽可能避免走EC解码,EC解码对CPU消耗很大)。
  3. 同时,新建若干个定时器,构造对应批次的backup request,对应剩余的m个replica
  4. 如果第一批次返回,则取消这些定时器,避免浪费后端IO
  5. 如果第一批次的返回值有部分报不存在或者出错,则立即启动上面的定时器
  6. 由于写入的时候,任意k个以上成功就返回,所以有可能写入的时候失败了
  7. 或者此时后端部分节点异常
  8. k m中有任意k个成功后,即可通过矩阵计算还原出原始数据块并返回

对其他模块的影响

修复模块会受影响。3副本模式的修复过程,只需要读取任意一个replica上的数据,就可以进行修复。现在需要读取k个数据,并重新进行EC计算,然后才可以进行修复。

k和m的选择

根据上文的计算k越大, m越小,则副本数(k m)/k=1 m/k越小。那么我们是不是可以把k设置成100,m设置成1呢?这里的k和m 一般受如下几个条件制约

  1. 一个shard的replica数量等于k m,而这些replica是位于不同的node中,这些node是位于不同的可用区中。k=100,m=1要求有101个可用区,一般公司的故障隔离域没有这么多,规模也没有这么大。
  2. 原始数据输入后,会切割成k个数据块,如果原始数据长度为1MB的话,那么切割后到后端存储节点只有10KB了,会造成后端节点的IOPS上升(相当于放大了101倍)。
  3. 读取的时候,需要并行读取100个数据块,长尾和IOPS都会上升。

那么是不是可以在约束k的情况下,降低m的值呢?这里又引入了另外一个话题。

数据可靠性(安全性/持久性)计算

数据可靠性讨论一般指在给定的磁盘故障概率情况下,不发生数据丢失的概率。先不考虑原始写入的时候只写入部分成功的情况。

可靠性相关因数

  1. 磁盘故障概率:直观解释,假设在某鱼购入一批硬盘,某天中午都同时发生了故障,那么一定会丢数据。
  2. 坏盘后的修复速度:假设磁盘故障不是同时发生的,那么只要在连续故障导致数据丢失之前,将数据修复回来,也就是修复速度大于故障速度的话,就不会发生数据丢失。假设有个神器,无论磁盘多大,都能在1秒内修复,那也不会发生数据丢失。
  3. 能够容忍发生连续损坏的盘的数量:假设修复时间恒定(比如1小时修复一块盘),那么此时3副本(可以容忍连续损坏2块盘)的数据可靠性小于10副本的情况(可以连续损坏9块盘)

回顾上文,EC使用k m的策略,任意k个块就可以恢复原始数据,也就是允许m个损坏。所以从数据可靠性考虑,m越多越好。实际环境中k m的策略,需要根据资源(机器数、故障隔离域数)、业务IO特点(比如文件大小)进行具体调整。

Day11

目前从架构层看,我们基本完成了S3的大部分功能(不考虑分段上传和Delete操作)。目前engine层还是使用的Rocksdb,而rocksdb在面对长度比较长的value时(1K以上),会有比较大的写性能问题(compaction导致)。今天我们足够解决这个问题。

优化目标

在讨论这些引擎的差别之前,我们先看下存储层的目标。所有的存储的目标都是为了最终数据的读取操作,如果没有读取的话,也就没有存储的动力。如何有效的满足读取目标是各个存储引擎的优化目标。注意,这里我们使用有效的满足而不是高效的满足,区别在于,不是所有的读需求都要求高性能,有些场景,只要能满足就行了。

假设我们采用最简单的策略:

这种方案如果简单进行测试,发现可以工作,但是是否可以完成目标,该如何进行评估呢?回顾文件系统的实现,我们会发现,本地文件系统,通常也分为元数据存储和数据存储两块。其中元数据主要包括目录树(文件名相关信息)、inode(用于描述文件由哪些数据块组成)、数据块。如下图所示

b站离线缓存删了还能找回来吗,b站卸载后缓存不见了怎么找回(28)

上一页34567下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.