zoukankan      html  css  js  c++  java
  • OpenStack+Ceph存储空间回收《转》

    转自:http://blog.csdn.net/wytdahu/article/details/48288681

    问题描述

      在OpenStack云环境的部署中,存储通常具备Thin provision的功能,这项功能实现了存储按需分配的能力。现在有这样一种场景,用户在文件系统中创建了大文件,使用完之后进行了删除。但实际上,该文件在存储系统上占用的空间并没有释放。

    当用户在文件系统中删除一个文件,并不会在块设备上的对应空间填0,而仅仅在磁盘的元数据结构中将这些block标记为未使用。因此,虽然文件系统知道这些block是未使用或者说可用的,但是底层的存储系统并不知道文件系统做的操作,会认为这些block仍在使用。以RBD image为例,它本身是稀疏格式的,也就是说它所占用objects会随着用户写入数据的增加而增加(Thin provision)。当用户删除数据以后,这些obejct不再使用,但并没有被释放。因为从Ceph的角度讲,它并不知道文件系统中发生的事情。

    解决办法

    比较理想的解决办法就是,提供一种空间回收机制,文件系统可以通知块设备释放掉不再使用的block。Linux的Trim/Discard机制正是这样一种机制。从Ceph 0.46,Ceph的块设备开始支持Trim/Discard操作。这意味着,从Guest虚拟机中可以发出Trim请求,Ceph块设备就可以释放掉不再使用的空间。

      需要注意的是,当前只有主流的文件系统,比如Ext4、XFS、Btrfs,支持Trim/Discard操作。

    触发Trim/Discard请求

      有两种方式可以触发Trim/Discard请求,一种是由文件系统自动完成,一种是用户通过执行命令来完成。

    一、文件系统自动完成

      只要在挂载文件系统时指定discard参数即可,比如 mount -t ext4 -o discard  device mountpoint,这样在文件系统中删除文件后会自动触发Trim/Discard操作,在块设备上释放占用的空间。

    二、用户执行命令

      用户可以执行命令fstrim来触发Trim/Discard操作,采用这种方式mount文件系统时不需要discard参数。比如,fstrim -v mountpoint,就会释放对应块设备上不用的空间。

      需要注意的是,mount的discard参数会导致文件系统性能下降,在并发删除大量小文件时变得很慢,因此需要根据具体场景选择合适的长发方式。

    版本要求

      Qemu: 1.5

      Libvirt: 1.0.6

      Ceph: 0.46

      Linux kernel: 3.1

    OpenStack中该功能的通用实现

      在虚拟机平台中,IDE或者SCSI磁盘支持Trim,VirtIO不支持Trim操作。OpenStack在Icehouse中引入下面两个commit,支持了virtio-scsi,也就是说可以使用Trim/Discard。

    https://review.openstack.org/#/c/70262/

    https://review.openstack.org/#/c/70263/

    需要配置Nova和Glance支持virtio-scsi和discard。

    1、glance image-update --property hw_scsi_model=virtio-scsi --property hw_disk_bus=scsi

    其中,hw_scsi_model=virtio-scsi 是指libvirt要使用virtio-scsi控制器,hs_disk_bus=scsi是指libvirt使用scsi总线连接磁盘到控制器。

    2、编辑nova.conf

    [libvirt]

    hw_disk_discard = unmap

    其中,有效的hw_disk_discard参数包括:

    unmap: it unmaps aligned group of sectors

    ignore: it ignores the discard request

    上述操作其实就是确保磁盘挂载到虚拟机中使用了scsi,最终的libvirt xml描述文件如下:

     <disk type='network' device='disk' >

    <driver name='qemu' type='raw'cache='none' discard='unmap'/>

    <auth username='compute'>

    <secret type='ceph'uuid='a5d0dd94-57c4-ae55-ffe0-7e3732a24455'/>

    </auth>

    <source protocol='rbd'name='volumes/vdisk1'>

    <host name='192.168.1.2'port='6789'/>

    </source>

    <target dev='sdb' bus='scsi'/>

    </disk>

    在AWcloud云平台使用该功能

     1、创建云硬盘

    2、挂载云硬盘总线类型选择scsi

    3、虚拟机里将挂载的磁盘创建分区并挂载

    4、删除大文件后执行fstrim -v mountpoint

    或者

    挂载时使用-o discard参数,那么删除文件时会自动触发Discard/Trim操作,不需要执行fstrim命令。

    实验验证

    1、创建一个RBD image

    2、将创建好的RBD image以scsi的方式挂载到虚拟机中,分区创建文件系统

    3、统计该RBD image占用的object数量

     [root@node-4 gc]# rados -p volumes ls |grep 3232ae8944a | wc -l

    135

    4、在虚拟机的文件系统中创建文件

     ddif=/dev/zero of=image bs=1M count=10000

    5、统计该RBD image占用的object数量

     [root@node-4 gc]# rados -p volumes ls |grep 3232ae8944a | wc -l

    382

    注:(382-135)*4M ~ 1G,和创建的文件大小相符

    6、虚拟机中删除创建的文件,并执行fstrim命令

    rm -rf image;fstrim –v mountpoint

    7、统计该RBD image占用的object数量

     [root@node-4 gc]# rados -p volumes ls |grep 3232ae8944a | wc -l

    196

    注:(382-196)*4M ~ 800M, 绝大部分空间得到回收

     参考:

      http://www.sebastien-han.fr/blog/2015/02/02/openstack-and-ceph-rbd-discard/

      http://ceph.com/docs/master/rbd/qemu-rbd/#enabling-discard-trim

      http://cephnotes.ksperis.com/blog/2014/12/18/use-discard-with-krbd-client-since-kernel-3-dot-18/

  • 相关阅读:
    Spring Boot中的JSON技术
    Spring Boot中编写单元测试
    如何保证事务方法的幂等
    定时重试线程池
    多线程导致事务失效-记一次性能优化
    自己实现一个简单的数据库事务
    服务器错误码国际化
    spring自定义自动配置注解
    springboot中如何启动tomcat
    用grep来查询日志
  • 原文地址:https://www.cnblogs.com/chris-cp/p/6272696.html
Copyright © 2011-2022 走看看