目录

  • 1 Ceph概述
  • 2 核心组件
  • 3 IO流程
  • 4 IO顺序性
  • 5 PG一致性协议
    • 5.1 StateMachine
    • 5.2 Failover Overview
    • 5.3 PG Peering
    • 5.4 Recovery/Backfill
  • 6 引擎概述
  • 7 FileStore
    • 7.1 架构设计
    • 7.2 对外接口
    • 7.3 日志类型
    • 7.4 幂等操作
  • 8 BlueStore
    • 8.1 架构设计
    • 8.2 BlockDevice
    • 8.3 磁盘分配器
    • 8.4 BlueFS
    • 8.5 对象IO
  • 9 未来规划

《浅析开源项目之Ceph》地址:浅析开源项目之Ceph - 知乎 --鱼香肉丝没有鱼

1 Ceph概述

Ceph是由学术界(Sage Weil博士论文)在2006年提出的一个开源的分布式存储系统的解决方案,最早致力于下一代高性能分布式文件存储,经过十多年的发展,还提供了块设备、对象存储S3的接口,成为了统一的分布式存储平台,进而成为开源社区存储领域的明星项目,得到了广泛的实际应用。

Ceph是一个可靠的、自治的、可扩展的分布式存储系统,它支持文件存储、块存储、对象存储三种不同类型的存储,满足存储的多样性需求。整体架构如下:

  • 接口层:提供客户端访问存储层的的各种接口,支持POSIX文件接口、块设备接口、对象S3接口,以及用户可以自定义自己的接口。
  • Librados:提供上层访问RADOS集群的各种库函数接口,libcephfs、librbd、librgw都是Librados的客户端。
  • RADOS:可靠的、自治的分布式对象存储,主要包含Monitor、OSD、MDS节点,提供了一个统一的底层分布式存储系统,支持逻辑存储池概念、副本存储和纠删码、自动恢复、自动rebalance、数据一致性校验、分级缓存、基于dmClock的QoS等核心功能。

2 核心组件

  • CephFS:Ceph File System,Ceph对外提供的文件系统服务,MDS来保存CephFS的元数据信息,数据写入Rados集群。
  • RBD:Rados Block Device,Ceph对外提供的块设备服务,Ceph里称为Image,元数据很少,保存在特定的Rados对象和扩展属性中,数据写入Rados集群。
  • RGW:Rados Gateway,Ceph对外提供的对象存储服务,支持S3、Swift协议,元数据保存在特定的Pool里面,数据写入Rados集群。
  • Monitor:保存了MONMap、OSDMap、CRUSHMap、MDSMap等各种Map等集群元数据信息。一个Ceph集群通常需要3个Mon节点,通过Paxos协议同步集群元数据。
  • OSD:Object Storage Device,负责处理客户端读写请求的守护进程。一个Ceph集群包含多个OSD节点,每块磁盘一个OSD进程,通过基于PGLog的一致性协议来同步数据。
  • MDS:Ceph Metadata Server,文件存储的元数据管理进程,CephFS依赖的元数据服务,对外提供POSIX文件接口,不是Rados集群必须的。
  • MGR:Ceph Manager,负责跟踪运行时指标以及集群的运行状态,减轻Mon负担,不是Rados集群必须的。
  • Message:网络模块,目前支持Epoll、DPDK(剥离了seastar的网络模块,不使用其share-nothing的框架)、RDMA,默认Epoll。
  • ObjectStore:存储引擎,目前支持FileStore、BlueStore、KVStore、MemStore,提供类POSIX接口、支持事务,默认BlueStore。
  • CRUSH:数据分布算法,秉承着无需查表,算算就好的理念,极大的减轻了元数据负担(但是感觉过于执着减少元数据了,参考意义并不是很大),但同时数据分布不均,不过已有CRUSH优化Paper。
  • SCRUB:一致性检查机制,提供scrub(只扫描元数据)、deep_scrub(元数据和数据都扫描)两种方式。
  • Pool:抽象的存储池,可以配置不同的故障域也即CRUSH规则,包含多个PG,目前类型支持副本池和纠删池。
  • PG:Placement Group,对象的集合,可以更好的分配和管理数据,同一个PG的读写是串行的,一个OSD上一般承载200个PG,目前类型支持副本PG和纠删PG。
  • PGLog:PG对应的多个OSD通过基于PGLog的一致性协议来同步数据,仅保存部分操作的oplog,扩缩容、宕机引起的数据迁移过程无需Mon干预,通过PG的Peering、Recovery、Backfill机制来自动处理。
  • Object:Ceph-Rados存储集群的基本单元,类似文件系统的文件,包含元数据和数据,支持条带化、稀疏写、随机读写等和文件系统文件差不多的功能,默认4MB。

3 IO流程

此处以RBD块设备为例简要介绍Ceph的IO流程。

  1. 用户创建一个Pool,并指定PG的数量。
  2. 创建Pool/Image,挂载RBD设备,映射成一块磁盘。
  3. 用户写磁盘,将转换为对librbd的调用。
  4. librbd对用户写入的数据进行切块并调用librados,每个块是一个object,默认4MB。
  5. librados进行stable_hash算法计算object所属的PG,然后再输入pg_id和CRUSHMap,根据CRUSH算法计算出PG归属的OSD集合。
  6. librados将object异步发送到Primary PG,Primary PG将请求发送到Secondary PG。
  7. PG所属的OSD在接收到对应的IO请求之后,调用ObjectStore存储引擎层提供的接口进行IO。
  8. 最终所有副本都写入完成才返回成功。

Ceph的IO通常都是异步的,所以往往伴随着各种回调,以FileStore为例看下ObjectStore层面的回调:

  1. on_journal:数据写入到journal,通常通过DirectIO + Libaio的方式,Journal的数据是sync到磁盘上的。
  2. on_readable:数据写入Journal且写入Pagecache中,返回客户端可读。
  3. on_commit:Pagecache中的数据sync到磁盘上,返回客户端真正写成功。

4 IO顺序性

分布式系统中通常需要考虑对象读写的顺序性和并发性,如果两个对象没有共享资源,那么就可以并发访问,如果有共享资源就需要加锁操作。对于同一个对象的并发读写来说,通常是通过队列、锁、版本控制等机制来进行并发控制,以免数据错乱,Ceph中对象的并发读写也是通过队列和锁机制来保证的。

PG

Ceph引入PG逻辑概念来对对象进行分组,不同PG之间的对象是可以并发读写的,单个PG之间的对象不能并发读写,也即理论上PG越多并发的对象也越多,但对于系统的负载也高。

ceph 引入PG的意义:https://blog.csdn.net/bandaoyu/article/details/121847874 

不同对象的并发控制

落在不同PG的不同对象是可以并发读写的,落在统一PG的不同对象,在OSD处理线程中会对PG加锁,放进PG队列里,一直等到调用queue_transactions把OSD的事务提交到ObjectStore层才释放PG的锁,也即对于同一个PG里的不同对象,是通过PG锁来进行并发控制,不过这个过程中不会涉及到对象的IO,所以不太会影响效率。

同一对象的并发控制

同一对象的并发控制是通过PG锁实现的,但是在使用场景上要分为单客户端、多客户端。

  1. 单客户端:单客户端对同一个对象的更新操作是串行的,客户端发送更新请求的顺序和服务端收到请求的顺序是一致的。
  2. 多客户端:多客户端对同一个对象的并发访问类似于NFS的场景,RADOS以及RBD是不能保证的,CephFS理论上应该可以。

所以接下来主要讨论单客户端下同一对象的异步并发更新。

Message层顺序性

  1. TCP层是通过消息序列号来保证一条连接上消息的顺序性。
  2. Ceph Message层也是通过全局唯一的tid来保证消息的顺序性。

PG层顺序性

从Message层取到消息进行处理时,OSD处理OP时划分了多个shard,每个shard可以配置多个线程,PG通过哈希的方式映射到不同的shard里面。OSD在处理PG时,从拿到消息就会PG加了写锁,放入到PG的OpSequencer队列,等到把OP请求下发到ObjectStore端才释放写锁。对于同一个对象的并发读写通过对象锁来控制。

对同一个对象进行写操作会加write_lock,对同一个对象的读操作会加read_lock,也就是读写锁,读写是互斥的。写锁从queue_transactions开始到数据写入到Pagecache结束。

对同一个对象上的并发写操作,实际上并不会发生,因为放入PG队列是有序的,第一次写从PG取出放到ObjectStore层之后就会释放锁,然后再把第二次写从PG取出放入到ObjectStore层,取出写OP放到ObjectStore层都是调的异步写的接口,这就需要ObjectStore层来保证两次写的顺序性了。

ObjectStore层顺序性

ObjectStore支持FileStore、BlueStore,也都需要保证IO顺序性。对于写请求,到达ObjectStore层之后,会获取OpSequencer(每个PG一个,用来保证PG内OP顺序)。

FileStore:对于写事务OP来说(都有一个唯一递增的seq),会按照顺序放进writeq队列,然后write_thread线程通过Libaio将数据写入到Journal里面,此时数据已经是on_disk但不可读,已完成OP的seq序号按序放到journal的finisher队列里(因为Libaio并不保证顺序,会出现先提交的IO后完成,因此采用op的seq序号来保证完成后处理的顺序),如果某个op之前的op还未完成,那么这个op会等到它之前的op都完成后才一起放到finisher队列里,然后把数据写入到Pagecache和sync到数据盘上。

BlueStore:bluestore在拿到写OP时会先通过BlockDevice提供的异步写(Libaio/SPDK/io_uring)接口先把数据写到数据盘,然后再通过RocksDB的WriteBatch接口批量的写元数据和磁盘分配器信息到RocksDB。由于也是通过异步写接口写的,也需要等待该OP之前的OP都完成,才能写元数据到RocksDB。

5 PG一致性协议

在Ceph的设计和实现中,自动数据迁移、自动数据均衡等各种特性都是以PG为基础实现的,PG是最复杂和最难理解的概念,Ceph也基于PG实现了数据的多副本和纠删码存储。基于PG LOG的一致性协议也类似于Raft实现了强一致性。

ceph 引入PG的意义:https://blog.csdn.net/bandaoyu/article/details/121847874 

5.1 StateMachine

PG有20多种状态,状态的多样性也反映了功能的多样性和复杂性。PG状态的变化通过事件驱动的状态机来驱动,比如集群状态的变化,OSD加入、删除、宕机、恢复 、创建Pool等,最终都会转换为一系列的状态机事件,从而驱动状态机在不同状态之间跳转和执行处理。

  • Active:活跃态,PG可以正常处理来自客户端的读写请求,PG正常的状态应该是Active+Clean的。
  • Unactive:非活跃态,PG不能处理读写请求。
  • Clean:干净态,PG当前不存在修复对象,Acting Set和Up Set内容一致,并且大小等于存储池的副本数。
  • Peering:类似Raft的Leader选举使一个PG内的OSD达成一致,不涉及数据迁移等操作。
  • Recovering:正在恢复态,集群正在执行迁移或恢复某些对象的副本。
  • Backfilling:正在后台填充态,backfill是recovery的一种特殊场景,指peering完成后,如果基于当前权威日志无法对Peers内的OSD实施增量同步(OSD离线太久,新的OSD加入) ,则通过完全拷贝当前Primary所有对象的方式进行全量同步。
  • Degraded:降级状态,Peering完成后,PG检测到有OSD有需要被同步或修复的对象,或者当前ActingSet 小于存储池副本数。
  • Undersized:PG当前Acting Set小于存储池副本数。ceph默认3副本,min_size参数通常为2,即副本数>=2时就可以进行IO,否则阻塞IO。
  • Scrubing:PG正在进行对象的一致性扫描。
  • 只有Active状态的PG才能进行IO,可能会有active+clean(最佳)、active+unclean(小毛病)、active+degraded(小毛病)等状态,小毛病不影响IO。

为了避免全是文字,网上找了张图,如有侵权,联系删除。

更多的PG 状态:https://blog.csdn.net/bandaoyu/article/details/120348914

5.2 Failover Overview 

故障检测:Ceph分为MON集群和OSD集群两部分,MON集群管理者整个集群的成员状态,将OSD的信息存放在OSDMap中,OSD定期向MON和Peer OSD 发送心跳包,声明自己处于在线状态。MON接收来自OSD的心跳信息确认OSD在线,同时也接收来自OSD对于Peer OSD的故障检测。当MON判断某个OSD节点离线后,便将最新的OSDMap通过心跳随机的发送给OSD,当Client或者OSD处理IO请求时发现自身的OSDMap版本低于对方,便会向MON请求最新的OSDMap,这种Lasy的更新方式,经过一段时间的传播之后,整个集群都会收到最新的OSDMap。

确定恢复数据:OSD在收到OSDMap的更新消息后,会扫描该OSD下所有的PG,如果发现某些PG已经不属于自己,则会删掉其数据。如果该OSD上的PG是Primary PG的话,将会进行PG Peering操作。在Peering过程中,会根据PGLog检查多个副本的一致性,并计算PG的不同副本的数据缺失情况,PG对应的副本OSD都会得到一份对象缺失列表,然后进行后续的Recovery,如果是新节点加入、不足以根据PGLog来Recovery等情况,则会进行Backfill,来恢复整份数据。

数据恢复:在PG Peering过程中会暂停所有的IO,等Peering完成后,PG会进入Active状态,此时便可以接收数据的IO请求,然后根据Peering的信息来决定进行Recovery还是Backfill。对于Replica PG缺失的数据Primary PG会通过Push来推送,对于Primary PG自身缺少的数据会通过Pull方式从其他Replicate PG拉取。在Recovery过程中,恢复的粒度是4M对象,对于无法通过PGlog来恢复的,则进行Backfill进行数据的全量拷贝,等到数据恢复完成后,PG的状态会标记为Clean即所有副本数据保持一致。

5.3 PG Peering

PG的Peering是使一个PG内的所有OSD达成一致的过程,相关重要概念如下:

  • up set:pg对应的副本列表,也即通过CRUSH算法选出来的3个副本列表,第一个为primary,其他的为replica。
  • active set:对外处理IO的副本列表,通常和up set一致,当恢复时可能会存在临时PG,则active set为临时PG的副本集合,用于对外提供正常IO,当完成恢复后,active set调整为up set。
  • pg_temp:临时的PG,当CRUSH算法产生新的up set的primary无法承担起职责(新加入的OSD或者PGLog过于落后的OSD成为了primary,也即需要backfill的primary需要申请临时PG,recovery的primary不需要申请临时PG),osd就会向mon申请一个临时的PG用于数据正常IO和恢复,Ceph做了优化是在进行CRUSH时就根据集群信息选择是否预填充pg_tmp,从而减少Peering的时间。此时处于Remapped状态,等到数据同步完成,需要取消pg_tmp,再次通过Peering将active_set切回up_set。
  • epoch:每个OSDMap都会有一个递增的版本,值越大版本越新,当集群中OSD发生变化时,就会产生新的OSDMap。
  • pg log:保存操作的记录,是用于数据恢复的重要结构。并不会保存所有的op log,默认3000条,当有数据需要恢复的时候就会保存10000条。
  • Interval:每个PG都有Interval(epoch的操作序列),每次OSD获取到新的OSDMap时,如果发现up set、up primary、active set、active primary没有改变,则Interval不用改变,否则就要生成新的current interval,之前的变成past_interval,只要该PG内部的OSD不发生变化,Interval就不会变化。

主要包含三个步骤:

  1. GetInfo:作用为确定参与peering过程的osd集合。主OSD会获取该PG对应的所有OSD的pg_info信息放入peer_info。
  2. GetLog:作用为选取权威日志。根据各个副本OSD的pg_info信息比较,选取一个具有权威日志的OSD,如果主OSD不具备权威日志,那么就从该具有权威日志的OSD拉取权威日志,拉取完成之后进行合并就具有了权威日志,如果primary自身具有权威日志,则不用合并,否则合并的过程如下:
    1. 拉取过来的日志比primary具有更老的日志条目:追加到primary本地日志尾部即可。
    2. 拉取过来的日志比primary具有更新的日志条目:追加到primary本地日志头部即可。
    3. 合并的过程中,primary如果发现自己有对象需要修复,便会将其加入到missing列表。
  3. GetMissing:获取需要恢复的object集合。主OSD拉取其他从OSD的PGLog,与自身权威日志进行对比,计算该OSD缺失的object集合。

5.4 Recovery/Backfill

Peering进行之后,如果Primary检测到自身或者任意一个Peer需要修复对象,则进入Recovery状态,为了影响外部IO,也会限制恢复的速度以及每个OSD上能够同时恢复的PG数量。Recovery一共有两种状态:

  1. Pull:如果Primary自身存在待恢复对象,则按照missing列表寻找合适的副本拉取修复对象到本地然后修复。
  2. Push:如果Primary检测到其Replica存在待恢复对象,则主动推动待修复对象到Replica,然后由Replica自身修复。

通常总是先执行Pull再执行Push,即先修复Primary再修复Replica,因为Primary承担了客户端的读写,需要优先进行修复,修复情况大致如下:

  1. 客户端IO和内部恢复IO可以同时进行。
  2. 读写的对象不在恢复列表中:按照正常IO即可。
  3. 读取的对象在恢复列表中:如果primary有则可以直接读取,如果没有需要优先恢复该对象,然后读取。
  4. 写入的对象在恢复列表中:优先恢复该对象,然后写入。
  5. backfill则是primary遍历当前所有的对象,将他们全量拷贝到backfill 的PG中。
  6. 恢复完成后,会重新进行Peering,是active set 和up set保持一致,变为active + clean状态。

在恢复对象时,由于PGLog并未记录关于对象修改的详细信息(offset、length等),所以目前对象的修复都是全量对象(4M)拷贝,不过社区已经支持部分对象修复。

同时在恢复对象时,由于ObjectStore支持覆盖写,所以在对象上新的写不能丢弃老的对象,需要等老的对象恢复完之后,才能进行该对象新的写入,不过社区已经支持异步恢复。

6 引擎概述

Ceph提供存储功能的核心组件是RADOS集群,最终都是以对象存储的形式对外提供服务。但在底层的内部实现中,Ceph的后端存储引擎在近十年来经历了许多变化。现如今的Ceph系统中仍然提供的后端存储引擎有FileStore、BlueStore。但该三种存储引擎都是近年来才提出并设计实现的。Ceph的存储引擎也先后经历了EBOFS-->FileStore/btrfs-->FileStore/xfs-->NewStore-->BlueStore。同时Ceph需要支持文件存储,所以其存储引擎提供的接口是类POSIX的,存储引擎操作的对象也具有类似文件系统的语义,也具有其自己的元数据。

7 FileStore

FileStore是Ceph基于文件系统的最早在生成环境比较稳定的单机存储引擎,虽然后来出现了BlueStore,但在一些场景中仍然不能代替FileStore,比如在全是HDD的场景中FileStore可以使用NVME盘做元数据和数据的读写Cache,从而加速IO,BlueStore就只能加速元数据IO。

7.1 架构设计

FileStore是基于文件系统的,为了维护数据的一致性,写入之前数据会先写Journal,然后再写到文件系统,会有一倍的写放大。不过Journal也起到了随机写转换为顺序写、支持事务的作用。

引用网上图片,如有侵权,联系删除。

7.2 对外接口

对象的元数据使用KV形式保存,主要有两种保存方式:

  • xattrs:保存在本地文件系统的扩展属性中,一般都有大小的限制。
  • omap:object map,保存在LevelDB/RocksDB中。

有些文件系统不支持扩展属性,或者扩展属性大小有限制。一般情况下xattr保存一些比较小且经常访问的元数据,omap保存一些大的不经常访问的元数据。

同时ObjectStore使用Transaction类来实现相关的操作,将元数据和数据封装到bufferlist里面,然后写Journal。大致包含OP_TOUCH、OP_WRITE、OP_ZERO、OP_CLONE等42种事务操作。提供的对外接口大致有:

ObjectStore本身的接口:mount、umount、fsck、repair、mkfs等。

Object本身的接口:read、write、omap、xattrs、snapshot等。

7.3 日志类型

在FileStore的实现中,根据不同的日志提交方式,有两种不同的日志类型:

  • Journal writeahead:先提交数据到Journal上(通常配置成一块SSD磁盘),然后再写入到Pagecache,最后sync到数据盘上。适用于XFS、EXT4等不支持快照的文件系统,是FileStore默认的实现方式。
  • Journal parallel:数据提交到Journal和sync到数据盘并行进行,没有完成的先后顺序,适用于BTRFS、ZFS等支持快照的文件系统,由于文件系统支持快照,当写数据盘出错,数据不一致时,文件系统只需要回滚到上一次快照,并replay从上次快照开始的日志就可以,性能要比writeahead高,但是Linux下BTRFS和ZFS不稳定,线上生产环境几乎没人用。

日志处理有三个阶段:

  1. 日志提交(journal submit):数据写入到日志盘,通常使用DirectIO+Libaio,一个单独的write_thread不断从队列取任务执行。
  2. 日志应用(journal apply):日志对应的修改更新到文件系统的文件上,此过程仅仅是写入到了Pagecache。
  3. 日志同步(journal commit):将文件系统的Pagecache脏页sync到磁盘上,此时数据已经持久化到数据盘,Journal便可以删除对应的数据,释放空间。

7.4 幂等操作

在机器异常宕机的情况下,Journal中的数据不一定全部都sync到了数据盘上,有可能一部分还在Pagecache,此时便需要在OSD重启时保证数据的一致性,对Journal做replay。FileStore将已经sync到数据盘的序列号记录在commit_op_seq中,replay的时候从commit_op_seq开始即可。

但是在replay的时候,部分op可能已经sync到数据盘中,但是commit_op_seq却没有体现,序列化比其小,此时如果仍然replay,可能会出现非幂等操作,导致数据不一致。

假设一个事务包含如下3个操作:

  1. clone a 到 b。
  2. 更新 a。
  3. 更新 c。

假设上述操作都做完也已经持久化到数据盘上了,然后立马进程或者系统崩溃,此时sync线程还未来得及更新commit_op_seq,重启回放时,第二次执行clone操作就会clone到a新的数据版本,就会发生不一致。

FileStore在对象的属性中记录最后操作的三元组(序列号、事务编号、OP编号),因为journal提交的时候有一个唯一的序列号,通过这个序列号, 就可以找到提交时候的事务,然后根据事务编号和OP编号最终定位出最后操作的OP。对于非幂等的操作,操作前先检查下,如果可以继续执行就执行操作,执行完之后设置一个guard。这样对于非幂等操作,如果上次执行过, 肯定是有记录的,再一次执行的时候check就会失败,就不继续执行。

8 BlueStore

Ceph早期的单机对象存储引擎是FileStore,为了维护数据的一致性,写入之前数据会先写Journal,然后再写到文件系统,会有一倍的写放大,而同时现在的文件系统一般都是日志型文件系统(ext系列、xfs),文件系统本身为了数据的一致性,也会写Journal,此时便相当于维护了两份Journal;另外FileStore是针对HDD的,并没有对SSD作优化,随着SSD的普及,针对SSD优化的单机对象存储也被提上了日程,BlueStore便由此应运而出。

BlueStore最早在Jewel版本中引入,用于在SSD上替代传统的FileStore。作为新一代的高性能对象存储后端,BlueStore在设计中便充分考虑了对SSD以及NVME的适配。针对FileStore的缺陷,BlueStore选择绕过文件系统,直接接管裸设备,直接进行对象数据IO操作,同时元数据存放在RocksDB,大大缩短了整个对象存储的IO路径。BlueStore可以理解为一个支持ACID事物型的本地日志文件系统。

8.1 架构设计

BlueStore是一个事务型的本地日志文件系统。因为面向下一代全闪存阵列的设计,所以BlueStore在保证数据可靠性和一致性的前提下,需要尽可能的减小日志系统中双写带来的影响。全闪存阵列的存储介质的主要开销不再是磁盘寻址时间,而是数据传输时间。因此当一次写入的数据量超过一定规模后,写入Journal盘(SSD)的延时和直接写入数据盘(SSD)的延迟不再有明显优势,所以Journal的存在性便大大减弱了。但是要保证OverWrite(覆盖写)的数据一致性,又不得不借助于Journal,所以针对Journal设计的考量便变得尤为重要了。

一个可行的方式是使用增量日志。针对大范围的覆盖写,只在其前后非磁盘块大小对齐的部分使用Journal,即RMW,其他部分直接重定向写COW即可。

RWM(Read-Modify-Write):指当覆盖写发生时,如果本次改写的内容不足一个BlockSize,那么需要先将对应的块读上来,然后再内存中将原内容和待修改内容合并Merge,最后将新的块写到原来的位置。但是RMW也带来了两个问题:一是需要额外的读开销;二是如果磁盘中途掉电,会有数据损坏的风险。为此我们需要引入Journal,先将待更新数据写入Journal,然后再更新数据,最后再删除Journal对应的空间。

COW(Copy-On-Write):指当覆盖写发生时,不是更新磁盘对应位置已有的内容,而是新分配一块空间,写入本次更新的内容,然后更新对应的地址指针,最后释放原有数据对应的磁盘空间。理论上COW可以解决RMW的两个问题,但是也带来了其他的问题:一是COW机制破坏了数据在磁盘分布的物理连续性。经过多次COW后,读数据的顺序读将会便会随机读。二是针对小于块大小的覆盖写采用COW会得不偿失。是因为一是将新的内容写入新的块后,原有的块仍然保留部分有效内容,不能释放无效空间,而且再次读的时候需要将两个块读出来做Merge操作,才能返回最终需要的数据,将大大影响读性能。二是存储系统一般元数据越多,功能越丰富,元数据越少,功能越简单。而且任何操作必然涉及元数据,所以元数据是系统中的热点数据。COW涉及空间重分配和地址重定向,将会引入更多的元数据,进而导致系统元数据无法全部缓存在内存里面,性能会大打折扣。

基于以上设计理念,BlueStore的写策略综合运用了COW和RMW策略。非覆盖写直接分配空间写入即可;块大小对齐的覆盖写采用COW策略;小于块大小的覆盖写采用RMW策略。整体架构设计如下图:

  • BlockDevice:物理块设备,使用Libaio、SPDK、io_uring操作裸设备,AsyncIO。
  • RocksDB:存储对象元数据、对象扩展属性Omap、磁盘分配器元数据。
  • BlueRocksEnv:抛弃了传统文件系统,封装RocksDB文件操作的接口。
  • BlueFS:小型的Append文件系统,实现了RocksDB::Env接口,给RocksDB用。
  • Allocator:磁盘分配器,负责高效的分配磁盘空间。
  • Cache:实现了元数据和数据的缓存。

8.2 BlockDevice

Ceph新的存储引擎BlueStore已成为默认的存储引擎,抛弃了对传统文件系统的依赖,直接管理裸设备,通过Libaio的方式进行读写。抽象出了BlockDevice基类,提供统一的操作接口,后端对应不同的设备类型的实现(Kernel、NVME、PMEM)。

  • KernelDevice:通常使用Libaio或者io_uring,适用于HDD和SATA SSD。
  • NVMEDevice:通常使用SPDK用户态IO,提升IOPS缩短延迟,适用于NVME磁盘。
  • PMEMDevice:当做磁盘来用,使用libpmem库来操作。

IO架构图如下所示:

8.3 磁盘分配器

BlueStore直接管理裸设备,那么必然面临着如何高效分配磁盘中的块。BlueStore支持基于Extent和基于BitMap的两种磁盘分配策略,有BitMap分配器(基于Bitmap)和Stupid分配器(基于Extent),原则上都是尽量顺序分配而达到顺序写。

刚开始使用的是BitMap分配器,由于性能问题又切换到了Stupid分配器。之后Igor Fedotov大神重新设计和实现了新版本BitMap分配器,性能也比Stupid要好,默认的磁盘分配器又改回了BitMap。

新版本BitMap分配器以Tree-Like的方式组织数据结构,整体分为L0、L1、L2三层。每一层都包含了完整的磁盘空间映射,只不过是slot以及children的粒度不同,这样可以加快查找,如下图所示:

新版本Bitmap分配器分配空间的大体策略如下:

  1. 循环从L2中找到可以分配空间的slot以及children位置。
  2. 在L2的slot以及children位置的基础上循环找到L1中可以分配空间的slot以及children位置。
  3. 在L1的slot以及children位置的基础上循环找到L0中可以分配空间的slot以及children位置。
  4. 在1-3步骤中保存分配空间的结果以及设置每层对应位置分配的标志位。

新版本Bitmap分配器整体架构设计有以下几点优势:

  1. Allocator避免在内存中使用指针和树形结构,使用vector连续的内存空间。
  2. Allocator充分利用64位机器CPU缓存的特性,最大程序的提高性能。
  3. Allocator操作的单元是64 bit,而不是在单个bit上操作。
  4. Allocator使用3级树状结构,可以更快的查找空闲空间。
  5. Allocator在初始化时L0、L1、L2三级BitMap就占用了固定的内存大小。
  6. Allocator可以支持并发的分配空闲,锁定L2的children(bit)即可,暂未实现。

BlueStore直接管理裸设备,需要自行管理空间的分配和释放。Stupid和Bitmap分配器的结果是保存在内存中的,分配结果的持久化是通过FreelistManager来做的。

FreelistManager最开始有extent和bitmap两种实现,现在默认为bitmap实现,extent的实现已经废弃。空闲空间持久化到磁盘也是通过RocksDB的Batch写入的。FreelistManager将block按一定数量组成段,每个段对应一个k/v键值对,key为第一个block在磁盘物理地址空间的offset,value为段内每个block的状态,即由0/1组成的位图,1为空闲,0为使用,这样可以通过与1进行异或运算,将分配和回收空间两种操作统一起来。

8.4 BlueFS

RocksDB不支持对裸设备的直接操作,文件的读写必须实现rocksdb::EnvWrapper接口,RocksDB默认实现有POSIX文件系统的读写接口。而POSIX文件系统作为通用的文件系统,其很多功能对于RocksDB来说并不是必须的,同时RocksDB文件结构层次比较简单,不需要复杂的目录树,对文件系统的使用也比较简单,只使用追加写以及顺序读随机读。为了进一步提升RocksDB的性能,需要对文件系统的功能进行裁剪,而更彻底的办法就是考虑RocksDB的场景量身定制一套本地文件系统,BlueFS也就应运而生。相对于POSIX文件系统有以下几个优点:

  1. 元数据结构简单,使用两个map(dir_map、file_map)即可管理文件的所有元数据。
  2. 由于RocksDB只需要追加写,所以每次分配物理空间时进行提前预分配,一方面减少空间分配的次数,另一方面做到较好的空间连续性。
  3. 由于RocksDB的文件数量较少,可以将文件的元数据全部加载到内存,从而提高读取性能。
  4. 多设备支持,BlueFS将存储空间划分了3个层次:Slow慢速空间(存放BlueStore数据)、DB高速空间(存放sstable)、WAL超高速空间(存放WAL、自身Journal),空间不足或空间不存在时可自动降级到下一层空间。
  5. 新型硬件支持,抽象出了block_device,可以支持Libaio、io_uring、SPDK、PMEM、NVME-ZNS。

接口功能

RocksDB是通过BlueRocksEnv来使用BlueFS的,BlueRocksEnv实现了文件读写和目录操作,其他的都继承自rocksdb::EnvWrapper。

  • 文件操作:追加写、顺序读(适用于WAL的读,也会进行预读)、随机读(sstable的读,不会进行预读)、重命名、sync、文件锁。
  • 目录操作:目录的创建、删除、遍历,目录只有一级,即 /a 、 /a/b、/a/b/c 为同一级目录,整体元数据map可表示为:map<string(目录名), map<string(文件名), file_info(文件元数据)>>。

磁盘布局

BlueFS的数据结构比较简单,主要包含三部分,superblock、journal、data。

  • superblock:主要存放BlueFS的全局信息以及日志的信息,其位置固定在BlueFS的头部4K。
  • journal:存放元数据操作的日志记录,一般会预分配一块连续区域,写满以后从剩余空间再进行分配,在程序启动加载的时候逐条回放journal记录,从而将元数据加载到内存。也会对journal进行压缩,防止空间浪费、重放时间长。压缩时会遍历元数据,将元数据重新写到新的日志文件中,最后替换日志文件。
  • data:实际的文件数据存放区域,每次写入时从剩余空间分配一块区域,存放的是一个个sstable文件的数据。

元数据

BlueFS元数据:主要包含:superblock、dir_map、file_map、文件到物理地址的映射关系。

文件数据:每个文件的数据在物理空间上的地址由若干个extents表:一个extent包含bdev、offset和length三个元素,bdev为设备标识,因为BlueFS将存储空间设备划分为三层:慢速(Slow)空间、高速(DB)空间、超高速(WAL),bdev即标识此extent在哪块设备上,offset表示此extent的数据在设备上的物理偏移地址,length表示该块数据的长度。

struct bluefs_extent_t {uint64_t offset = 0;uint32_t length = 0;uint8_t bdev;
}// 一个sstable就是一个fnode
struct bluefs_fnode_t {uint64_t ino;uint64_t size;utime_t mtime;uint8_t prefer_bdev;mempool::bluefs::vector<bluefs_extent_t> extents;uint64_t allocated;
}

按照9T盘、sstable 8MB,文件元数据80B来算,所需内存 9 * 1024 * 1024 / 8 * 80 / 1024 / 1024 = 90MB,说明把元数据全部缓存到内存并不会占用过多的内存。

加载流程

  1. 加载superblock到内存。
  2. 初始化各存储空间的块分配器。
  3. 日志回放建立dir_map、file_map来重建整体元数据。
  4. 标记已分配空间:BlueFS没有像BlueStore那样使用FreelistManager来持久化分配结果,因为sstable大小固定从不修改,所以BlueFS磁盘分配需求都是比较同意和固定的。会遍历每个文件的分配信息,然后移除相应的磁盘分配器中的空闲空间,防止已分配空间的重复分配。

读写数据

读数据:先从dir_map和file_map找到文件的fnode(包含物理的extent),然后从对应设备的物理地址读取即可。

写数据:BlueFS只提供append操作,所有文件都是追加写入。RocksDB调用完append以后,数据并未真正落盘,而是先缓存在内存当中,只有调用sync接口时才会真正落盘。

  1. open file for write
    打开文件句柄,如果文件不存在则创建新的文件,如果文件存在则会更新文件fnode中的mtime,在事务log_t中添加更新操作,此时事务记录还不会持久化到journal中。
  2. append file
    将数据追加到文件当中,此时数据缓存在内存当中,并未落盘,也未分配新的空间。
  3. flush data(写数据)
    判断文件已分配剩余空间(fnode中的 allocated - size)是否足够写入缓存数据,若不够则为文件分配新的空间;如果有新分配空间,将文件标记为dirty加到dirty_files当中,将数据进行磁盘块大小对其后落盘,此时数据已经写到硬盘当中,元数据还未更新,同时BlueFS中的文件都是追加写入,不存在原地覆盖写,就算失败也不会污染原来的数据。
  4. flush_and_sync_log(写元数据)
    从dirty_files中取到dirty的文件,在事务log_t中添加更新操作(即添加OP_FILE_UPDATE类型的记录),将log_t中的内容sync到journal中,然后移除dirty_files中已更新的文件。

第3步是写数据、第4步是写元数据,都涉及到sync落盘,整体一个文件的写入需要两次sync,已经算是很不错了。

8.5 对象IO

BlueStore中的对象非常类似于文件系统中的文件,每个对象在BlueStore中拥有唯一的ID、大小、从0开始逻辑编址、支持扩展属性等,因此对象的组织形式,类似于文件也是基于Extent。

BlueStore的每个对象对应一个Onode结构体,每个Onode包含一张extent-map,extent-map包含多个extent(lextent即逻辑的extent),每个extent负责管理对象内的一个逻辑段数据并且关联一个Blob,Blob包含多个pextent(物理的extent,对应磁盘上的一段连续地址空间的数据),最终将对象的数据映射到磁盘上。具体可参考BlueStore源码分析之对象IO和BlueStore源码分析之事物状态机。

BlueStore中磁盘的最小分配单元是min_alloc_size,HDD默认64K,SSD默认16K,里面有2种磁盘分配的写类型(分配磁盘空间,数据还在内存):

  1. big-write:对齐到min_alloc_size的写我们称为大写(big-write),在处理是会根据实际大小生成lextent、blob,lextent包含的区域是min_alloc_size的整数倍,如果lextent是之前写过的,那么会将之前lextent对应的空间记录下来并回收。
  2. small-write:落在min_alloc_size区间内的写我们称为小写(small-write)。因为最小分配单元min_alloc_size,HDD默认64K,SSD默认16K,所以如果是一个4KB的IO那么只会占用到blob的一部分,剩余的空间还可以存放其他的数据。所以小写会先根据offset查找有没有可复用的blob,如果没有则生成新的blob。

真正写磁盘时,有两种不同的写类型:

1、simple-write:包含对齐覆盖写(COW)和非覆盖写,先把数据写入新的磁盘block,然后更新RocksDB里面的KV元数据,状态转换图如下:

这图话的比较好,拿过来直接用了,如有侵权,联系删除。

2、deferred-write:为非对齐覆盖写,先把数据作为WAL写RocksDB即先写日志,然后会进行RMW操作写数据到磁盘,最后CleanupRocksDB中的deferred-write的数据。

这图话的比较好,拿过来直接用了,如有侵权,联系删除。

3、simple-write + deferred-write:上层的一次IO很有可能同时涉及到simple-write和deferred-write,其状态机就是上面两个加起来,只不过少了deferred-write的写WAL一步,因为可以在simple-write写元数据时就一同把WAL写入RocksDB。

9 未来规划

随着硬件的不断发展,IO的速度越来越快,PMEM和NVME也逐渐成为了存储系统的主流选择,相比之下CPU的速度没有那么快了,反而甚至成为了系统的瓶颈。如何高效合理的利用新型硬件是分布式存储不得不面临的一个重大问题。Ceph传统的线程模型是多线程+队列的模型,一个IO从发起到完成要经历重重队列和不同的线程池,锁竞争、上下文切换和Cache Miss比较严重,也导致IO延迟迟迟降不下来。通过Perf发现CPU主要都耗在了锁竞争和系统调用上,Ceph自身的序列化和反序列化也比较消耗CPU,所以需要一套新的编程框架来解决上述问题。Seastar是一套基于future-promsie现代化高效的share-nothing的网络编程框架,从18年开始,Ceph社区便基于Seastar来重构整个OSD,项目代号Crimson,来更好的解决上述问题。

Crimson设计目标

  1. 最小化CPU开销。
  2. 减少跨核通信。
  3. 减少数据拷贝。
  4. Bypass Kernel,减少上下文切换。
  5. 支持新硬件:ZNS-NVME、PMEM等。

线程模型

性能对比

测试RBD时,在达到同等iops和延迟时,crimson-osd的cpu比ceph-osd的cpu少了好几倍。

BlueStore适配

BlueStore目前是Ceph里性能比较高的单机存储引擎,从设计研发到稳定差不多持续了3年时间,足以说明研发一个单机存储引擎的时间成本是比较高的。由于BlueStore不符合Seastar的编程模型,所以需要对BlueStore适配,目前有两种方案:

  1. BlueStore-Alien:使用一个Alien Thread,使用Seastar的编程模型专门向Seastar-Reactor提交BlueStore的任务。
  2. BlueStore-Native:使用Seastar-Env来实现RocksDB的Rocksdb-Env,从而更原生的适配。

但是由于RocksDB有自己的线程模型,外部不可控,所以无论怎么适配都不是最好的方案,理论上从0开始用基于Seastar的模型来写一个单机存储引擎是最完美的方案,于是便有了SeaStore,而BlueStore的适配也作为中间过渡方案,最多可用于HDD。

SeaStore

SeaStore是下一代的ObjectStore,适用于Crimson的后端存储,专门为了NVME设计,使用SPDK访问,同时由于Flash设备的特性,重写时必须先要进行擦除操作,也就是内部需要做GC,是不可控的,所以Ceph希望把Flash的GC提到SeaStore中来做:

  1. SeaStore的逻辑段(segment)理想情况下与硬件segment(Flash擦除单位)对齐。
  2. SeaStar是每个线程一个CPU核,所以将底层按照CPU核进行分段,每个核分配指定个数的segment。
  3. 当磁盘利用率达到阈值时,将少量的GC清理工作和正常的写流量一起做。
  4. 元数据使用B+数存储,而不是原来的RocksDB。
  5. 所有segment都是追加顺序写入的。

10 参考资源

  1. https://github.com/ceph/ceph-v13.1.0
  2. https://zhuanlan.zhihu.com/分步试存储
  3. Ceph设计原理与实现-中兴通讯
  4. Ceph十年经验总结:文件系统是否适合做分布式文件系统的后端
  5. Sage: bluestore-a-new-storage-backend-for-ceph
  6. Crimson: a-new-ceph-osd-for-the-age-of-persistent-memory-and-fast-nvme-storage
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 操作系统--输入/输出(I/O)管理(下)

    五、I/O核心子系统 1、知识总览 2、实现层次 3、I/O调度 4、设备保护 六、假脱机技术&#xff08;SPOOLing 技术&#xff09; 1、知识总览 2、什么是脱机技术&#xff1f; 3、假脱机技术&#xff08;输入井、输出井&#xff09; 4、假脱机技术&#xff08;输入进程、输出进程、…...

    2024/4/7 17:38:11
  2. Docker 下 GitLab 安装

    一、Docker 版本 二、查看可安装的版本 docker search gitlab 三、拉取最新版本 gitlab 社区版 docker pull gitlab/gitlab-ce:latest 四、查看本地镜像 docker images 五、创建挂载目录 宿主机位置容器位置作用/usr/local/gitlab/config/etc/gitlab用于存储 GitLab 配置文…...

    2024/4/14 2:51:25
  3. 妙用Stream优化老代码,立马清爽了

    Java8的新特性主要是Lambda表达式和流&#xff0c;当流和Lambda表达式结合起来一起使用时&#xff0c;因为流申明式处理数据集合的特点&#xff0c;可以让代码变得简洁易读 # 放大招&#xff0c;流如何简化代码 如果有一个需求&#xff0c;需要对数据库查询到的菜肴进行一个处…...

    2024/5/2 22:29:06
  4. 经历121,市场情绪极度恐慌,美联储加息对我们有什么影响,币圈人又该何去何从?

    昨天年会&#xff0c;准备了一天&#xff0c;感觉还是有些发挥不好&#xff0c;总有些美中不足&#xff0c;我还喝醉了&#xff0c;有点惨不忍睹。 有时候就是这样&#xff0c;就算做好万全的准备&#xff0c;生活总是会出乎意料的&#xff0c;币圈亦是如此。 经历了121的大跌&…...

    2024/4/20 17:21:00
  5. 从零开始学习C++ Day 006

    本科郑州大学应用化学系&#xff0c;研究生福州大学物理化学&#xff0c;后从事营地教育两年&#xff0c;现在跨专业考研至计算机。 写这个文章记录的初衷是希望通过这样的方式来监督自己每日学习一定量的编程保持练习&#xff0c;虽然初试的成绩还未出。但只要有一线希望自然…...

    2024/4/24 22:09:25
  6. Go语言的创建HTTP客户端(未完成)

    超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff0c;HTTP&#xff09; 理解HTTP 要理解HTTP请求的结构&#xff0c;一种不错的方式是使用curl。输入命令行如下&#xff1a; curl -s -o /dev/null -v http://google.com 运行结果如下&#xff1a; * Tryi…...

    2024/4/16 8:53:27
  7. Kylin Cube 构建优化

    文章目录使用衍生维度&#xff08;derived dimension&#xff09;使用聚合组&#xff08;Aggregation group&#xff09;Row Key 优化使用衍生维度&#xff08;derived dimension&#xff09; 衍生维度用于在有效维度内将维度表上的非主键维度排除掉&#xff0c;并使用维度表的…...

    2024/4/21 6:42:35
  8. 小乐乐与进制转换

    描述小乐乐在课上学习了二进制八进制与十六进制后&#xff0c;对进制转换产生了浓厚的兴趣。因为他的幸运数字是6&#xff0c;所以他想知道一个数表示为六进制后的结果。请你帮助他解决这个问题。 输入描述&#xff1a;输入一个正整数n (1 ≤ n ≤ 10^9) 输出描述&#xff1a;…...

    2024/4/18 7:36:04
  9. 数据结构及算法之异或

    一、概念 概念来自百度百科。 链接如下&#xff1a; 异或 异或也叫半加运算&#xff0c;其运算法则相当于不带进位的二进制加法&#xff1a;二进制下用1表示真&#xff0c;0表示假&#xff0c;则异或的运算法则为&#xff1a;0⊕00&#xff0c;1⊕01&#xff0c;0⊕11&#xff…...

    2024/4/14 2:51:45
  10. 两个子序列(C语言)

    题目 学习了字符串相关知识的王大队长在思考一些问题&#xff1a;现在王大队长有一个字符串 ss &#xff0c;他想找到两个非空字符串 aa and bb &#xff0c;来满足下面的条件&#xff1a; 字符串 aa 和 bb 都是 ss 的子序列&#xff1b; 对于每个索引 ii, 字符串 ss 的字符 …...

    2024/4/20 1:34:09
  11. 对HashMap的一些汇总

    文章目录前言一、HashMap的数据结构和工作原理1.数据结构2.工作原理3.扩容二、底层实现2.代码举例前言 最近复习到JAVA的HashMap这一块&#xff0c;也算是比较重要的内容&#xff1b;写个博客记录一下学习过程中的一些理解。 参考文档&#xff1a; https://blog.csdn.net/weix…...

    2024/4/24 11:41:32
  12. JavaScript高级教程(函数进阶、闭包、正则表达式、ES6新增语法、新增扩展方法)

    目录 函数的定义与调用 严格模式 什么是严格模式 开启严格模式 严格模式中的变化 高阶函数 闭包 正则表达式 ES6新增语法 ES6的内置对象扩展 Array的扩展方法 String的扩展方法 Set数据结构 函数的定义与调用 函数有三种定义方式&#xff1a; 自定义函数&#x…...

    2024/4/14 2:51:25
  13. J1900搭建centos家用服务器

    J1900搭建centos家用nas服务器 这几天在家里用一些渣渣配件装了个小服务器放家里使用啊。效果还是很不错的&#xff0c;在这里贴出我安装用的一些命令。希望可以给有需要的人提供一些思路。 系统使用的是centos7啊&#xff0c;这个装宝塔面板可以安装python项目管理器。然后软…...

    2024/4/14 2:52:41
  14. zabbix[服务端安装]

    zabbix 文章目录zabbix一、配置环境二、安装zabbix提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、配置环境 配置3台虚拟机虚拟机&#xff0c;其中一台做server端 二、安装zabbix yum install -y yum-utils rpm -Uvh https://repo.zabbix.com/z…...

    2024/4/14 2:52:31
  15. 外网用户通过域名访问公司内网某些网页服务

    1.配置防火墙端口映射&#xff0c;将内网服务映射到公司出口 配置了nat server后防火墙的安全策略要放行。我这个默认允许所有流量通行&#xff0c;不做配置。 2.配置外网主机hosts文件&#xff0c;路径为C:\Windows\System32\drivers\etc\hosts。 添加两条域名映射&#xff0…...

    2024/4/14 2:52:11
  16. Java采用案例对开关式Switch的运用进行分析 |CSDN创作

    //根据获奖名次给予奖励 String reward;//给予的奖励 int rank;//获奖名次 Scanner scnew Scanner(System.in); System.out.print("输入获奖的名次:"); ranksc.nextInt(); //处理部分//switch可与if else一起用 也可单用 switch (rank){//打开代码的开关case 1:rewar…...

    2024/4/14 2:52:16
  17. 计算机网络-自顶向下笔记-应用层-Email应用

    计算机网络所有笔记链接 因特网中的电子邮件 和普通的邮件一样&#xff0c;电子邮件是一种 异步通信媒介&#xff0c;就是当我们方便的时候就可以进行邮件的收发&#xff0c;不用和他人商量好了什么时间进行收发工作。特性&#xff1a;包括具有附件、超链接、HTML格式文本和图…...

    2024/4/19 9:59:13
  18. 使用AJAX技术,结合监听器,实现页面中动态显示当前网站在线人数(电子工业出版社《Java Web程序设计》P171第九题)方案Ⅱ

    导航Servlet和Listener集成一个程序为什么有问题前一篇总结最大的问题最终方案1.监听器2.Servlet实现3.实现前端JSP文件&#xff08;集成JS&#xff09;Servlet和Listener集成一个程序为什么有问题 在上一篇总结中我写到我看到这个题目的第一个想法是写出Servlet和Listener集成…...

    2024/4/28 2:33:37
  19. rg.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name

    1、遇到的问题 控制台出现如下错误&#xff0c;具体报错见附件 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name orderController: Unsatisfied dependency expressed through field paymentClient; nested exception is …...

    2024/4/14 2:52:36
  20. (arduino框架)ESP32学习笔记1 如何输出可调频率和占空比的pwm波

    &#xff08;arduino框架&#xff09;ESP32学习笔记1: 如何输出可调频率和占空比的pwm波 &#xff08;1&#xff09;esp32使用pwm波的函数在esp32-hal-ledc.h文件当中定义&#xff0c;其中共有16个通道可配置 //channel 0-15 resolution 1-16bits freq limits depend on reso…...

    2024/4/14 2:52:31

最新文章

  1. 免费开源语音克隆-GPT-SoVITS-WebUI只需 5 秒的声音样本

    语音克隆-GPT-SoVITS-WebUI 强大的少样本语音转换与语音合成Web用户界面。 功能&#xff1a; 零样本文本到语音&#xff08;TTS&#xff09;&#xff1a; 输入 5 秒的声音样本&#xff0c;即刻体验文本到语音转换。 少样本 TTS&#xff1a; 仅需 1 分钟的训练数据即可微调模型…...

    2024/5/3 5:06:48
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Docker Desktop+WSL2安装到自定义路径

    现在大多数软件实在太“流氓”了&#xff0c;在安装过程中&#xff0c;根本不让你选择安装路径&#xff0c;默认安装到$HOME下&#xff08;windows C盘&#xff09;&#xff0c;随着软件的使用增多&#xff0c;可能磁盘空间不够&#xff0c;这个时候就想着&#xff0c;看看某些…...

    2024/5/2 2:42:35
  4. k8s_入门_kubelet安装

    安装 在大致了解了一些k8s的基本概念之后&#xff0c;我们实际部署一个k8s集群&#xff0c;做进一步的了解 1. 裸机安装 采用三台机器&#xff0c;一台机器为Master&#xff08;控制面板组件&#xff09;两台机器为Node&#xff08;工作节点&#xff09; 机器的准备有两种方式…...

    2024/5/2 2:36:57
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/1 17:30:59
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/2 16:16:39
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/2 9:28:15
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/2 15:04:34
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/30 22:21:04
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/1 4:32:01
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/2 9:07:46
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57