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执行过程:
- 设置lc执行线程最大运行时间,由配置rgw_lc_lock_max_time指定,默认60s。
- 给所选的lc对象上锁,这个lc对象是随机选择的。
- 从lc对象里面获取需要执行lifecycle的bucket。
- 更新bucket的lc状态为lc_processing。
- 更新lc对象的omap header。
- 开始遍历bucket中的所有对象的元数据,把符合条件的对象删除或转移。
- 计算下一次进入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对系统资源消耗也比较大。
参考: