rgw:lifecycle功能理解


title: rgw:lifecycle功能理解

1、介绍

rgw lifecycle功能,也叫rgw生命周期功能,简单的理解就是我们对rgw bucket设置一个策略,这个策略规定bucket里面的数据何时过期,从而将过期的对象删掉或转移到其他地方。

目前12版本只支持将到期的数据对象删除掉,后面可能会增加把到期的数据对象转移到其他地方(比如N版里面加入的STORAGE CLASS功能)。

2、配置

重点:目前只能通过在rgw客户端使用api针对bucket设置(lifecycle规则作用在bucket上),只对该bucket里面的数据对象生效。管理侧(比如radosgw-admin)不支持设置bucket lc。

下面使用python3的boto3库来设置(使用s3cmd setlifecycle命令也可以),提前准备好一个rgw用户,并使用这个用户创建一个名为bk01的bucket。

设置lifecycle脚本内容:

[root@ceph01 ~]# cat lc.py 
import boto3

endpoint = "http://192.168.10.31:9001"  # rgw的访问地址
key = "NJ2VSBLRJ8Q7S0UYCWXE"    # rgw用户的access key
secret = "ElqXBaBsGOGDfzhRv4jBg9CXhY6xRAsv6A0A0Ru8" # rgw用户的secret key
bucket = "bk01" # rgw bucket名称
    
s3 = boto3.client('s3', aws_access_key_id=key, aws_secret_access_key=secret, endpoint_url=endpoint)
rule = {
          'Rules': [{                   #  设置过期规则部分
               'Expiration': {      
                    'Days': 1               # 过期时间,只能以天为单位
                },
                'ID': 'delete-anythings-after-one-day',     # 唯一的id,也可以使用一些字符串来说明此规则的大致含义
                'Status': 'Enabled',    
                'Prefix': ''                    # 对象的前缀,空字符串表示对所有对象起作用
         }],
}
s3.put_bucket_lifecycle(Bucket=bucket, LifecycleConfiguration=rule)
print(s3.get_bucket_lifecycle(Bucket=dev_bucket))

执行脚本:

[root@ceph01 ~]# python3 lc.py 
{'ResponseMetadata': {'RequestId': 'tx00000000000000000004e-005ebb6bad-3729-default', 'HostId': '', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amz-request-id': 'tx00000000000000000004e-005ebb6bad-3729-default', 'content-type': 'application/xml', 'content-length': '250', 'date': 'Wed, 13 May 2020 03:38:21 GMT'}, 'RetryAttempts': 0}, 'Rules': [{'Expiration': {'Days': 1}, 'ID': 'delete-anythings-after-one-day', 'Prefix': '', 'Status': 'Enabled'}]}

其中 'HTTPStatusCode': 200表示设置成功。

注意:一个bucket对于相同的规则只支持设置一次,比如:

[   #  设置过期规则部分
    {                   
                   'Expiration': {      
                        'Days': 1                               # 过期时间,只能以天为单位
                    },
                    'ID': 'delete-anythings-after-one-day',     # 唯一的id,也可以使用一些字符串来说明此规则的大致含义
                    'Status': 'Enabled',    
                    'Prefix': ''                                # 对象的前缀,空字符串表示对所有对象起作用
    },
    {                   
                   'Expiration': {      
                        'Days': 2                               # 过期时间,只能以天为单位
                    },
                    'ID': 'delete-anythings-after-two-day',     # 唯一的id,也可以使用一些字符串来说明此规则的大致含义
                    'Status': 'Enabled',    
                    'Prefix': ''                                # 对象的前缀,空字符串表示对所有对象起作用
    },
]

这个rule就是有问题的,因为该rule要求1天之后对象过期,又要求对象两天之后过期,冲突了。

增加筛选对象过滤条件

通过Filter字段来实现:

rule = {
         'Rules': [{
            'Expiration': {     
                    'Days': 1
               },
            'ID': 'delete-anythings-after-one-day', 
            'Filter': { // 筛选对象的过滤条件
                    'Tag': {    
                            // 这里的tag表示rgw数据对象的tagging,也可以通过api去设置和获取,存储在其head对象的xattr中
                            // 后续lc进程执行的时候,就会结合Prefix和Tag的设置,来判断对象是否符合该条件,不符合就会跳过
                            'Key': 'color',
                            'Value': 'red'
                         }
                   },
              'Status': 'Enabled',    
              'Prefix': ''
        }],
}

在N版之前使用tagging来筛选对象有个问题:比如有两个rule,rule1规定包含tag1:val1的对象在1天之后被删除,rule2规定包含tag2:val2的对象在2天之后被转移到其他地方。如果有一个对象同时包含tag1:val1和tag2:val2这两个tagging,那lc线程的行为会让人比较迷惑,这个pr:https://github.com/ceph/ceph/pull/35002/files,规定了只有full match tagging时才执行对应的操作(删除或转移)。

3、查看/删除

查看lifecycle接口:

s3.get_bucket_lifecycle(Bucket=dev_bucket)

删除lifecycle接口:

s3.delete_bucket_lifecycle(Bucket=dev_bucket)

**注意:因为lifecycle删除对象是周期行执行的,删除后,则在下一个周期生效。
**

下面说明从rados层面如何查看bucket lifecycle:

1、查看bucket对应的rados对象:

[root@ceph06 ~]# rados -p default.rgw.meta --namespace=root ls
.bucket.meta.bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1

2、bucket的lc信息存在其rados对象的xattr中,key值为user.rgw.lc:

[root@ceph06 ~]# rados -p default.rgw.meta --namespace root listxattr .bucket.meta.bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1
user.rgw.lc

3、从bucket的rados对象中获取其lc信息:

[root@ceph06 ~]# rados -p default.rgw.meta --namespace root getxattr .bucket.meta.bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1 user.rgw.lc > lc

4、解码lc信息:

[root@ceph06 ~]# ceph-dencoder type RGWLifecycleConfiguration import lc decode dump_json
{
    "prefix_map": {
        "": {
            "status": true,
            "dm_expiration": false,
            "expiration": 1,
            "noncur_expiration": 0,
            "mp_expiration": 0
        }
    },
    "rule_map": [
        {
            "id": "delete-anythings-after-one-day",
            "rule": {
                "id": "delete-anythings-after-one-day",
                "prefix": "",
                "status": "Enabled",
                "expiration": {
                    "days": "1",
                    "date": ""
                },
                "noncur_expiration": {
                    "days": "",
                    "date": ""
                },
                "mp_expiration": {
                    "days": "",
                    "date": ""
                },
                "filter": {
                    "prefix": "",
                    "obj_tags": {}
                },
                "dm_expiration": false
            }
        }
    ]
}

看到bucket的lifecycle已经设置成功。上面是设置和查看bucket lc的过程,其中从rados层面去查看某个bucket的lifecycle配置步骤还是有点麻烦的。从管理层面现在貌似没法直接查看,因为radosgw-admin只提供了两个相关命令:

lc list                     list all bucket lifecycle progress
lc process                  manually process lifecycle

4、执行原理

在default.rgw.log池里面有N个lc相关的rados对象,N由配置rgw_lc_max_objs指定,默认值是32。

[root@ceph06 ~]# rados -p default.rgw.log --namespace=lc ls
lc.6
···
lc.1
lc.0

所有设置了lifecycle的bucket,会保存在这些rados对象的omap中。分配的规则是bucket名称hash和lc对象数取模。bk01被分配到了lc.10这个rados对象中,注意每个lc rados对象可以被分别多个bucket。

[root@ceph06 ~]# rados -p default.rgw.log --namespace=lc listomapkeys lc.10
:bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1

每个lc rados对象的omap header中记录了自己负责的,将要执行的lifecycle的bucket信息:

[root@ceph06 ~]# rados -p default.rgw.log --namespace=lc getomapheader lc.10
header (0 bytes) :

看到当前没有正在执行lc的bucket。

手动执行lc process:

[root@ceph06 ~]# radosgw-admin lc process

lifecycle执行过程:

  1. 设置lc执行线程最大运行时间,由配置rgw_lc_lock_max_time指定,默认60s。
  2. 给所选的lc对象上锁,这个lc对象是随机选择的。
  3. 从lc对象里面获取需要执行lifecycle的bucket。
  4. 更新bucket的lc状态为lc_processing。
  5. 更新lc对象的omap header。
  6. 开始遍历bucket中的所有对象的元数据,把符合条件的对象删除或转移。
  7. 计算下一次进入lc的时间。

查看bucket lc的状态:

[root@ceph06 ~]# radosgw-admin lc list
[
    {
        "bucket": ":bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1",
        "status": "UNINITIAL"
    },
    {
        "bucket": ":bk02:d9498785-8e81-41bb-aee5-312670bc75a9.14130.2",
        "status": "UNINITIAL"
    }
]

其中bucket的lc状态有四种:

UNINITIAL 未初始化
PROCESSING 进行中
FAILED 失败
COMPLETE 完成

lifecycle相关的参数:

rgw_lifecycle_work_time = "00:00-6:00"      执行lc时间窗口
rgw_enable_lc_threads = true                允许启动lc线程,设置false表示关闭lc功能
rgw_lc_lock_max_time = 60               某个lc线程每次可以执行的总时间,超过该时间没执行完,就等下次执行
rgw_lc_max_objs = 32                    lc rados对象个数
rgw_lc_max_rules = 1000             一个bucket可以设置的rule数
rgw_lc_debug_interval = -1              这个参数很关键,>0时,会忽略设置的时间窗口去执行,立即执行,并且此时设置的过期天数,1天等于1s,也就是说你设置7天后过期,此时表示7s后过期。<=0时,则按照正常的来执行。该配置主要为了方便调试lc。

注:
当数据量非常大的时候,上面说了因为是随机选择lc对象,遍历对比,所以可能有的对象没有在规定时间内删除完成,比如设置1天后过期的对象,可能会在2、3天后才删除,这个是正常的。在就是lifecycle执行过程中会对index pool的读取流量非常高,lc对系统资源消耗也比较大。

参考:

https://medium.com/@spaz_44123/creating-an-intelligent-object-storage-system-with-cephs-object-lifecycle-management-112e2e46d490

https://www.dovefi.com/post/ceph_rgw_bucket_lifecycle/

你可能感兴趣的:(rgw:lifecycle功能理解)