您可以通过基于最后一次访问时间(Last Access Time)策略的生命周期规则来自动监测数据的访问模式并识别冷数据,然后将识别出来的冷数据进行存储类型的转换,从而达到数据的智能分层存储,最终降低存储成本。
场景说明
假设某多媒体网站产生了大量的数据,且数据均以标准存储类型进行存储,而这些数据往往需要根据数据的最后访问时间而非最后修改时间来判断数据的冷热。按以往,用户只能手动通过日志分析或其他方式进行数据冷热的分层管理。但如果选用基于最后一次访问时间的生命周期规则,则可实现由服务端根据最后访问时间来自动识别冷热数据并实现数据分层存储。
根据以上场景描述,将数据分类存储在examplebucket的不同路径下,并且希望将某些数据到达指定时间后转换为更低成本的存储类型。
存储路径 | 存储场景 | 生命周期策略 | 效果 |
data/ | 存储了大量以wmv为后缀的直播视频文件,上传后仅前两个月有少量访问记录,其他时间基本没有访问记录 | 距离最后一次访问时间200天后转为低频访问类型(数据被访问后,依旧停留在低频档) | 生命周期规则命中的数据达到指定天数后,执行相应的存储类型转换操作。未命中的数据将继续保留原有的标准存储类型 |
存储了大量以mp4为后缀的电影视频数据,大部分文件每半年内都会被频繁访问 | |||
log/ | 存储了大量的日志数据,少量文件近三个月内有若干次访问记录,所有文件上传半年后基本没有访问记录 |
|
以上场景选用了基于最后一次访问时间的生命周期策略,该策略下OSS会自动识别相同存储路径下的冷热数据,进而对冷热数据进行分级存储。例如,data/路径下大部分mp4为后缀且被频繁访问的电影视频数据会继续保留原有的标准存储类型,而少部分mp4为后缀半年内没有访问记录的电影视频数据将在距离最后一次访问时间200天后转为低频访问类型。如果配置基于最后一次修改时间的生命周期规则,则data/路径下的数据只能基于最后一次修改时间进行存储类型转换或者删除,无法根据文件访问热度实现智能分层存储。
以上场景配置的生命周期策略和建议动作仅供参考,您需要结合自身的业务场景灵活配置生命周期规则。
前提条件
已提交工单申请转换为归档、冷归档或深度冷归档类型的权限。
工单申请通过后,如果您基于最后一次访问时间策略将Object从标准存储或低频访问类型转为归档、冷归档或深度冷归档类型,则Bucket中归档、冷归档或深度冷归档类型Object的最后一次访问时间默认为该Bucket开启访问跟踪的时间。
操作步骤
使用OSS控制台
开启访问跟踪。
登录OSS管理控制台。
单击Bucket 列表,然后单击目标Bucket名称。
在左侧导航栏,选择数据管理 > 生命周期。
在生命周期页面,打开启用访问跟踪开关。
说明开启访问跟踪后,OSS默认以访问跟踪开启时间作为Bucket中所有Object的最后一次访问时间。
配置生命周期规则。
在生命周期页面,单击创建规则。
在创建生命周期规则面板,按以下说明分别配置基于前缀data/以及前缀log/的生命周期规则。
基于data/的生命周期规则
按以下说明配置基于data/的生命周期规则的必要参数,其他参数保留默认配置。
配置项
说明
状态
选中启动。
策略
选中按前缀匹配。
前缀
输入
data/
。文件时间策略
选中指定天数。
生命周期管理规则
下拉选择最后一次访问时间,输入200天后,数据自动转换成低频存储类型(数据被访问后,依旧保留在低频档)。
基于log/的生命周期规则
按以下说明配置基于log/的生命周期规则的必要参数,其他参数保留默认配置。
配置项
说明
状态
选中启动。
策略
选中按前缀匹配。
前缀
输入
log/
。文件时间策略
选中指定天数。
生命周期管理规则
下拉选择最后一次访问时间,输入120天后,数据自动转换成低频存储类型(数据被访问后,依旧保留在低频档)。
下拉选择最后一次访问时间,输入250天后,数据自动转换成归档类型。
单击确定。
使用阿里云SDK
仅Java SDK、Python SDK、Go SDK支持基于最后一次访问时间创建生命周期规则。创建基于最后一次访问时间的生命周期规则前,您需要为指定Bucket开启访问跟踪功能。
开启访问跟踪。
Java
import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.AccessMonitor; public class Demo { public static void main(String[] args) throws Exception { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称,例如examplebucket。 String bucketName = "examplebucket"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { // 开启Bucket的访问跟踪状态。Bucket开启访问跟踪状态后,如果需要修改Bucket的访问跟踪状态为Disabled,请确保Bucket不存在基于Last Access Time匹配规则的生命周期规则。 ossClient.putBucketAccessMonitor(bucketName, AccessMonitor.AccessMonitorStatus.Enabled.toString()); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } }
Python
# -*- coding: utf-8 -*- import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) # 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。 # 填写Bucket名称,例如examplebucket。 bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket') # 开启Bucket的访问跟踪状态。Bucket开启访问跟踪状态后,如果需要修改Bucket的访问跟踪状态为Disabled,请确保Bucket不存在基于LastAccessTime匹配规则的生命周期规则。 bucket.put_bucket_access_monitor("Enabled")
Go
package main import ( "fmt" "github.com/aliyun/aliyun-oss-go-sdk/oss" "os" ) func main() { /// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 provider, err := oss.NewEnvironmentVariableCredentialsProvider() if err != nil { fmt.Println("Error:", err) os.Exit(-1) } // 创建OSSClient实例。 // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider)) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } // 填写Bucket名称。 bucketName := "examplebucket" // 为examplebucket开启访问跟踪。 access := oss.PutBucketAccessMonitor{ Status: "Enabled", } err = client.PutBucketAccessMonitor(bucketName,access) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Println("put bucket access monitor success!") }
为前缀
data/
以及前缀log/
配置基于最后一次访问时间的生命周期规则。Java
import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.*; import java.util.ArrayList; import java.util.List; public class Lifecycle { public static void main(String[] args) throws Exception { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称,例如examplebucket。 String bucketName = "examplebucket"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { String ruleId1 = "rule1"; String ruleId2 = "rule2"; // 指定前缀为data/。 String matchPrefix = "data/"; // 指定前缀为log/。 String matchPrefix2 = "log/"; SetBucketLifecycleRequest request = new SetBucketLifecycleRequest(bucketName); // 在生命周期规则1中指定前缀为data/的所有文件在距离最后一次访问时间200天后转为低频访问类型。且再次访问前缀为data/的文件时,这些文件仍保留为低频访问类型。 List<LifecycleRule.StorageTransition> storageTransitions = new ArrayList<LifecycleRule.StorageTransition>(); LifecycleRule.StorageTransition storageTransition = new LifecycleRule.StorageTransition(); storageTransition.setStorageClass(StorageClass.IA); storageTransition.setExpirationDays(200); storageTransition.setIsAccessTime(true); storageTransition.setReturnToStdWhenVisit(false); storageTransitions.add(storageTransition); LifecycleRule rule = new LifecycleRule(ruleId1, matchPrefix, LifecycleRule.RuleStatus.Enabled); rule.setStorageTransition(storageTransitions); request.AddLifecycleRule(rule); // 在生命周期规则2中指定前缀为log/的所有文件在距离最后一次访问时间120天后转为低频访问类型。且再次访问前缀为log/的文件时,这些文件仍保留为低频访问类型。 List<LifecycleRule.StorageTransition> storageTransitions2 = new ArrayList<LifecycleRule.StorageTransition>(); LifecycleRule.StorageTransition storageTransition2 = new LifecycleRule.StorageTransition(); storageTransition2.setStorageClass(StorageClass.IA); storageTransition2.setExpirationDays(120); storageTransition2.setIsAccessTime(true); storageTransition2.setReturnToStdWhenVisit(false); storageTransitions2.add(storageTransition2); // 同一规则中指定前缀为log/的所有文件在距离最后一次访问时间250天后转为归档类型。 LifecycleRule.StorageTransition storageTransition3 = new LifecycleRule.StorageTransition(); storageTransition3.setStorageClass(StorageClass.Archive); storageTransition3.setExpirationDays(250); storageTransition3.setIsAccessTime(true); storageTransition3.setReturnToStdWhenVisit(false); storageTransitions2.add(storageTransition3); LifecycleRule rule2 = new LifecycleRule(ruleId2, matchPrefix2, LifecycleRule.RuleStatus.Enabled); rule2.setStorageTransition(storageTransitions2); request.AddLifecycleRule(rule2); VoidResult result = ossClient.setBucketLifecycle(request); System.out.println("返回状态码:"+result.getResponse().getStatusCode()+" set lifecycle succeed"); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } }
Python
# -*- coding: utf-8 -*- import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider from oss2.models import LifecycleRule, BucketLifecycle, StorageTransition # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) # yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。 # 填写Bucket名称,例如examplebucket。 bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket') # 在生命周期规则1中指定前缀为data/的所有文件在距离最后一次访问时间200天后转为低频访问类型。且再次访问前缀为data/的文件时,这些文件仍保留为低频访问类型。 rule1 = LifecycleRule('rule1', 'data/', status=LifecycleRule.ENABLED) rule1.storage_transitions = [StorageTransition(days=200, storage_class=oss2.BUCKET_STORAGE_CLASS_IA, is_access_time=True, return_to_std_when_visit=False)] # 在生命周期规则2中指定前缀为log/的所有文件在距离最后一次访问时间120天后转为低频访问类型。且再次访问前缀为log/的文件时,这些文件仍保留为低频访问类型。 # 同一规则中指定前缀为log/的所有文件在距离最后一次访问时间250天后转为归档类型。 rule2 = LifecycleRule('rule2', 'log/', status=LifecycleRule.ENABLED) rule2.storage_transitions = [StorageTransition(days=120, storage_class=oss2.BUCKET_STORAGE_CLASS_IA, is_access_time=True, return_to_std_when_visit=False), StorageTransition(days=250, storage_class=oss2.BUCKET_STORAGE_CLASS_ARCHIVE, is_access_time=True, return_to_std_when_visit=False)] lifecycle = BucketLifecycle([rule1, rule2]) # 设置生命周期规则。 result = bucket.put_bucket_lifecycle(lifecycle) print('设置生命周期成功,返回状态为:' + str(result.status))
Go
package main import ( "fmt" "github.com/aliyun/aliyun-oss-go-sdk/oss" "os" ) func main() { // yourBucketName填写Bucket名称。 bucketName := "examplebucket" // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 provider, err := oss.NewEnvironmentVariableCredentialsProvider() if err != nil { fmt.Println("Error:", err) os.Exit(-1) } // 创建OSSClient实例。 // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 client, err := oss.New("https://oss-cn-hangzhou.aliyuncs.com", "", "", oss.SetCredentialsProvider(&provider)) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } isTrue := true isFalse := false // 在生命周期规则1中指定前缀为data/的所有文件在距离最后一次访问时间200天后转为低频访问类型。且再次访问前缀为data/的文件时,这些文件仍保留为低频访问类型。 rule1 := oss.LifecycleRule{ ID: "rule1", Prefix: "data/", Status: "Enabled", Transitions: []oss.LifecycleTransition{ { Days: 200, StorageClass: oss.StorageIA, IsAccessTime: &isTrue, ReturnToStdWhenVisit: &isFalse, }, }, } // 在生命周期规则2中指定前缀为log/的所有文件在距离最后一次访问时间120天后转为低频访问类型。且再次访问前缀为log/的文件时,这些文件仍保留为低频访问类型。 rule2 := oss.LifecycleRule{ ID: "rule2", Prefix: "log/", Status: "Enabled", Transitions: []oss.LifecycleTransition{ { Days: 120, StorageClass: oss.StorageIA, IsAccessTime: &isTrue, ReturnToStdWhenVisit: &isFalse, }, { // 同一规则中指定前缀为log/的所有文件在距离最后一次访问时间250天后转为归档类型。 Days: 250, StorageClass: oss.StorageArchive, IsAccessTime: &isTrue, ReturnToStdWhenVisit: &isFalse, }, }, } // 设置生命周期规则。 var rules = []oss.LifecycleRule{rule1, rule2} err = client.SetBucketLifecycle(bucketName, rules) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("%s\n", "set bucket life cycle success") }
使用命令行工具ossutil
开启访问跟踪。
在本地config1.xml文件中配置开启访问跟踪。
<?xml version="1.0" encoding="UTF-8"?> <AccessMonitorConfiguration> <Status>Enabled</Status> </AccessMonitorConfiguration>
为目标Bucket设置访问跟踪状态。
ossutil access-monitor --method put oss://examplebucket/ config.xml
为前缀data/以及前缀/log配置基于最后一次访问时间的生命周期规则。
在本地config2.xml文件中配置以下生命周期规则。
<?xml version="1.0" encoding="UTF-8"?> <LifecycleConfiguration> <Rule> <ID>rule1</ID> <Prefix>data/</Prefix> <Status>Enabled</Status> <Transition> <Days>200</Days> <StorageClass>IA</StorageClass> <IsAccessTime>true</IsAccessTime> <ReturnToStdWhenVisit>false</ReturnToStdWhenVisit> </Transition> </Rule> <Rule> <ID>rule2</ID> <Prefix>log/</Prefix> <Status>Enabled</Status> <Transition> <Days>120</Days> <StorageClass>IA</StorageClass> <IsAccessTime>true</IsAccessTime> <ReturnToStdWhenVisit>false</ReturnToStdWhenVisit> </Transition> <Transition> <Days>250</Days> <StorageClass>Archive</StorageClass> <IsAccessTime>true</IsAccessTime> <ReturnToStdWhenVisit>false</ReturnToStdWhenVisit> </Transition> </Rule> </LifecycleConfiguration>
为目标Bucket设置生命周期规则。
ossutil lifecycle --method put oss://examplebucket config2.xml
使用REST API
如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PutBucketAccessMonitor和PutBucketLifecycle。