鲲鹏社区首页
中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

EC元数据缩减

Ceph对象存储场景下为了能够提升磁盘利用率,data pool会设置成EC模式来减小数据,元数据的放大倍数为EC副本数,在大比例EC的场景下元数据放大严重,EC元数据缩减特性通过把桶和桶内对象设定为不同的存储类,实现了应用对象数据和元数据分离。这样可以有效地降低元数据的存储开销,从而减少因EC副本数带来的元数据放大效应,提高存储效率。

Ceph软件编译部署

原生桶和桶内对象存储类不同时,分段上传逻辑存在异常,每段首对象的元数据也会存到桶存储类中,删除桶存储类时这部分元数据也会删除,产生内存泄漏,因此需要先合入如下patch,再重新出包。

  1. 获取ceph-14.2.8源码,并放置到“/home”目录下。
  2. 获取元数据缩减patch,并放置到“/home”目录下,patch下载地址:https://gitee.com/kunpengcompute/ceph/releases/download/storage_class_bug_fix/storage_class_bug_fix.patch
  3. 进入“/home”目录,解压Ceph源码包,进入Ceph源码目录,合入补丁。
    cd /home && tar -zxvf ceph-14.2.8.tar.gz && cd ceph-14.2.8
    patch -p1 < ../storage_class_bug_fix.patch
  4. 合入补丁后需要重新编译Ceph,具体请参见《Ceph 14.2.8 编译指南(CentOS 7.6&openEuler 20.03&openEuler 22.03)》的“配置编译环境”和“编译Ceph”章节。
  5. 完成Ceph软件安装,具体请参见《Ceph对象存储 部署指南(CentOS 7.6&openEuler 20.03&openEuler 22.03)》的“安装Ceph”章节。
  6. 部署RGW节点,具体请参见《Ceph对象存储 部署指南(CentOS 7.6&openEuler 20.03&openEuler 22.03)》的“部署RGW节点”章节。

部署对象存储功能

创建存储池和对象类
  • 创建桶时需要绑定placement/storage_class,桶中应用对象的placement和桶一样,应用对象的storage_class可以和桶不一样,在上传应用对象时可以指定。
  • 如下图,RGW网关创建好后,初始会有一个default-placement,其内部自带一个标准存储类STANDARD,如果不指定placement默认使用default-placement,不指定storage_class默认使用STANDARD,default-placement的index_pool、data_pool、data_extra_pool名称是固定的。

  • 这里桶绑定default-placement/head,head类对应data_pool命名为default.rgw.buckets.head,策略设置成三副本。
  • 桶内应用对象绑定default-placement/STANDARD,STANDARD类对应data_pool策略设置为EC。
  1. 创建Ec profile。
    1
    ceph osd erasure-code-profile set myprofile k=4 m=2 crush-failure-domain=osd
    
  2. 创建需要的存储池。
    1
    2
    3
    4
    5
    6
    7
    8
    ceph osd pool create default.rgw.buckets.data 2048 2048 erasure myprofile
    ceph osd pool create default.rgw.buckets.index 256 256
    ceph osd pool create default.rgw.buckets.head 2048 2048
    ceph osd pool create default.rgw.buckets.non-ec 256 256
    ceph osd pool application enable default.rgw.buckets.data rgw
    ceph osd pool application enable default.rgw.buckets.index rgw
    ceph osd pool application enable default.rgw.buckets.head rgw
    ceph osd pool application enable default.rgw.buckets.non-ec rgw
    
    创建存储池命令最后的两个数字,比如ceph osd pool create default.rgw.buckets.data 2048 2048 erasure myprofile中的两个2048分别代表存储池的pg_num和pgp_num,即存储池对应的pg数量。
    • Ceph官方文档建议整个集群所有存储池的pg数量之和大约为:(OSD数量 * 100)/ 数据冗余因数,数据冗余因数对副本模式而言是副本数,对EC模式而言是数据块+校验块之和。例如,三副本模式下数据冗余因数是3,EC4+2模式下数据冗余因数是6。
    • 举个例子,在EC4+2模式下,假设整个集群3台服务器,每台服务器36个OSD,总共108个OSD,按照上述公式计算应为1800,一般建议pg数取2的整数次幂。由于default.rgw.buckets.data存放的数据量远大于其他几个存储池的数据量,因此该存储池也成比例的分配更多的pg。
    • default.rgw.buckets.head的pg数一般设置为和default.rgw.buckets.data一样或者两倍。
    • default.rgw.buckets.non-ecdefault.rgw.buckets.index中rados对象不会太多,可以按default.rgw.buckets.data中数量的1/8进行配置。
  3. 向default区域组添加名为head的存储策略。
    1
    radosgw-admin zonegroup placement add --rgw-zonegroup default --placement-id default-placement --storage-class head
    
    • --rgw-zonegroup:指定要操作的区域组为default。
    • --placement-id:指定要添加的存储策略为default-placement。
    • --storage-class:指定存储策略的存储类别为hea
  4. 向default区域组添加名为head的存储策略,数据池为default.rgw.buckets.head。
    1
    radosgw-admin zonegroup placement add --rgw-zonegroup default --placement-id default-placement --storage-class head --data-pool default.rgw.buckets.head
    

    --data-pool:指定存储策略的数据池为default.rgw.buckets.head。

创建RGW账户

  1. 在任一节点上创建RGW账户。
    1
    radosgw-admin user create --uid="admin" --display-name="admin user"
    
  2. 创建账户完成后查询账户信息。
    1
    radosgw-admin user info --uid=admin
    

创建桶

  1. 创建桶时指定storage class使用如下python脚本。根据实际情况调整RGW账户信息字段aws_access_keyaws_srcret_key和RGW进程信息字段host
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    import requests
    import time
    import threading
    import sys
    from aws_requests_auth.aws_auth import AWSRequestsAuth
    
    def str_generator(n):
        import string
        import random
        chars = string.ascii_letters + string.digits
        return "".join(random.choice(chars) for _ in range(n))
    
    aws_access_key = 'xxxxxxxxxxxxxxxxxxxx'                          # rgw账户access_key
    aws_secret_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'      # rgw账户secret_key
    host = '192.168.xx.xxx:10001'                                    # rgw进程所在节点的ip + 监听端口
    region_name = 'default'
    service_name = 's3'
    
    aws_auth = AWSRequestsAuth(aws_access_key=aws_access_key,
                               aws_secret_access_key=aws_secret_key,
                               aws_host=host,
                               aws_region=region_name,
                               aws_service=service_name)
    
    headers = {
        "x-amz-storage-class": "STANDARD"                                        # 桶的存储类
    }
    
    
    url = f'http://{host}/mybucket'
    response = requests.put(url, auth=aws_auth, headers=headers)
    if response.status_code == 200: 
        print("请求成功")
    else: 
        print(f"请求失败,状态码: {response.status_code}")
    

    x-amz-storage-class字段用于指定存储桶中对象的存储类。常见的存储类包括如下三种分类。

    • STANDARD:标准存储类,用于频繁访问的数据。
    • INTELLIGENT_TIERING:智能分层存储,根据访问模式自动选择最优的存储层。
    • GLACIER:用于归档存储的低成本存储类,适用于长期不常访问的数据。