码迷,mamicode.com
首页 > 其他好文 > 详细

ceph bluefs

时间:2020-09-17 18:07:45      阅读:29      评论:0      收藏:0      [点我收藏+]

标签:thread   并且   http   bsp   参数   man   ram   磁盘空间   idt   

                                                           一场由 mon_osd_full_ratio参数引发的辛酸史!!

【背       景】 :

  在ceph 12.2.XXX集群中把mon_osd_full_ratio设置为99%以后,当磁盘空间使用率达到此报停水位后,集群并没有报停,而是由于磁盘空间消耗殆尽,BlueFS::_allocate分配不到磁盘空间导致整个池中的osd全部挂掉,此后osd再也无法拉起。

此时想到的是通过扩容bluefs来解决此问题。为此就开始梳理bluefs 扩容,FreelistManager,Allocator。。。。。

 

【日志报错】: 

         首次报错:bluefs _allocate failed to allocate 0x400000 on bdev 1,free 0x200000;fallback ro bdev 2

                        bluefs _allocate failed to allocate 0x400000 on bdev 2

                        FAILED assert(r=0)

         第一次挂掉后,再次启动osd:触发断言:FAILED assert(0 == "bluefs enospc")

               技术图片

 

 

【bluefs 三类磁盘空间】

对于blusfs在逻辑上有3个层次的存储空间:

a)超高速空间-WAL:这类空间主要用于存储RocksdbDB内部产生的.log文件,可由NVME SSD或者NVRAM等延时相较普通SSD更小的设备充当。超高速空间也由BlueFs直接管理。

b)高速空间-DB:这类空间主要用于存储BlueStore内部产生的元数据(例如onode),可以由普通的SSD提供。Bluestore的元数据都交由RocksDB管理,而RocksDB最终通过BlueFs将数据存盘,所有这类空间也由BlueFs直接管理。

c)慢速空间-slow:这类空间主要用于存储对象数据,可由普通大容量机械盘提供,由Bluestore自行管理。

      在生产环境中如果不区分以上3类存储空间,那么默认情况下BlueStore将自身管理的一部分空间拿出来与BlueFs进行共享(默认共享整个磁盘的4%空间),并在运行过程中进行实时监控和动态调整,具体策略是BlueStore通过BlueStore::_kv_sync_thread周期性的被唤醒,实时查询BlueFs的可使用空间,通过函数_balance_bluefs_freespace实现空间均衡,如果BlueFs可使用空间在整个BlueStore可用空间中的占比过小,则从bluestore空间中新分配一定量的空间赠送给BlueFs。反之如果BlueFs的可用空间在整个BlueStore可用空间占比过大,则从BlueFs中回收一部分空间到BlueStore。

    如果划分了WAL和DB空间,对于.log文件以及BlueFs自身产生的日志文件总是优先使用WAL类型的设备空间。对于.sst文件,则优先使用DB类型的设备空间。若此时WAL空间不足,则选择DB空间; 若DB仍然不足,则选择使用SLOW类型的设备空间.

 

 【BlueFs空间管理】

BitmapAllocator主要接口:

接口名称 含义
init_add_free() BluieStore上电时,通过BitmapFreelistManager读取磁盘中的空闲空间,然后使用此接口把空闲标记为空闲
init_rm_free() 将指定范围的空间标记为已经分配
allocate() 分配空间,分配的空间不一定是连续的,可能是一些离散的断。

        关键点:Allocator的使用者包含BlueFS和BlueStore,BlueFS通过文件系统的日志文件固化磁盘空间使用情况,BlueStore通过FreelistManager将磁盘空间信息固化到rocksdb中

BitmapFreelistManager:

接口名称 含义
allocate() 从BitmapFreelistManager中分配指定范围的空间
enumerate_reset() 上电时,bluestore通过这个2个接口遍历BitmapFreelistManager中所有空闲段,并将BlueStore的分配器进行初始化,从而还原上次下电时Allocator对应的内存结构
enumerate_next()

 

以下依据Bluestore创建,上电以及io写入时BitmapFreelistManager和BitmapAllocator的使用进行分析:

mkfs:   

  1. 默认情况下不分区,设置DB空间与Bluestore空间共享。默认共享4%,并把空间起始位置和长度保持在bluefs_extents集合中。

技术图片

     2.在函数_open_fm中把bluefs_extents写入数据库。

技术图片

 

 

 

 mount:上电流程

  1.   依据bluefs 文件系统的日志恢复出bluefs空间的使用情况,分别填充到bluefs的分配器中。

         alloc[id]->init_add_free(offset, length);
         alloc[id]->init_rm_free(offset, length);

  2. 依据日志回放(BlueFS::_replay)构建的文件列表(file_map),在bluefs的分配器中标记已经使用的磁盘空间。
  3. 从数据库中获取bluefs_extents。
  4. 从数据库中获取整个bluestore的空闲空间列表。并且把空闲空间填入bluestore的分配器中。
  5. 在bluestore的空闲空间列表中把bluefs的空间(bluefs_extents代表的空间即为bluefs空间)标记为已经使用。

上电后写流程空间分配:

  1. io到达bluestore层后通过alloc->allocate申请空间,并在BlueStore::_txc_finalize_kv函数中写入数据库,通过fm->allocate落盘。
  2. 元数据使用空间,最终会通过rocksdb中调用bluefs内部的allocate分配器分配空间并记录到对应文件的extent列表里面。

bluestore和bluefs空间数据均衡:

  1. BlueStore 与  BlueFs磁盘空间均衡函数入口:BlueStore::_kv_sync_thread---->_balance_bluefs_freespace
  2. 当bluefs空见不足后会提前从bluestore的分配器中申请一部分空间给bluestore使用。并写入bluefs_extents然后,写入数据库。

 

allocate和freelistmanager相关函数详细如下:

技术图片

 

 

 

 

社区扩容代码参考:

https://github.com/ceph/ceph/commit/69a43efccfd3289a3ffec1d76dc4b4a208e0ec0c

 

ceph bluefs

标签:thread   并且   http   bsp   参数   man   ram   磁盘空间   idt   

原文地址:https://www.cnblogs.com/wx-angel/p/13618457.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!