使用最后一次访问时间的生命周期规则实现数据智能分层

更新时间:2025-02-10 08:43:27

您可以通过最后一次访问时间策略的生命周期规则,自动监测数据访问模式并识别冷数据。然后,将冷数据进行存储类型转换,实现数据智能分层存储,最终降低存储成本。

场景说明

某多媒体网站的数据需要根据最后访问时间来判断冷热。传统方法需要手动分析日志,但使用基于最后访问时间的生命周期规则,可以自动识别并分层存储数据。

根据以上场景描述,将数据分类存储在examplebucket的不同路径下,并且希望将某些数据到达指定时间后转换为更低成本的存储类型。

存储路径

存储场景

生命周期策略

效果

存储路径

存储场景

生命周期策略

效果

data/

存储wmv直播视频,上传后仅前两个月有少量访问,之后基本无访问

距离最后一次访问时间200天后转为低频访问类型(数据被访问后,依旧停留在低频档)

达到指定天数后转换存储类型,未命中数据保留标准存储类型

存储mp4电影视频数据,大部分文件每半年内都会被频繁访问

log/

存储大量的日志数据,少量文件近三个月内有若干次访问记录,所有文件上传半年后基本没有访问记录

  • 距离最后一次访问时间120天后转为低频访问类型(数据被访问后,依旧停留在低频档)

  • 距离最后一次访问时间250天后转为归档类型

说明
  • 基于最后一次访问时间的生命周期策略,OSS会自动识别并分级存储冷热数据。例如,data/路径下频繁访问的mp4视频保留标准存储类型,半年内未访问的mp4视频在200天后转为低频访问类型。如果配置基于最后一次修改时间的生命周期规则,则data/路径下的数据只能基于最后一次修改时间进行存储类型转换或者删除,无法根据文件访问热度实现智能分层存储。

  • 以上场景配置的生命周期策略和建议动作仅供参考,您需要结合自身的业务场景灵活配置生命周期规则。

前提条件

提交工单申请转换为归档、冷归档或深度冷归档类型的权限。

重要

工单申请通过后,如果您基于最后一次访问时间策略将Object从标准存储或低频访问类型转为归档、冷归档或深度冷归档类型,则Bucket中归档、冷归档或深度冷归档类型Object的最后一次访问时间默认为该Bucket开启访问跟踪的时间。

操作步骤

使用OSS控制台

  1. 开启访问跟踪。

    1. 登录OSS管理控制台

    2. 单击Bucket 列表,然后单击目标Bucket名称。

    3. 在左侧导航栏,选择数据管理 > 生命周期

    4. 生命周期页面,打开启用访问跟踪开关。

      说明

      开启访问跟踪后,OSS默认以访问跟踪开启时间作为Bucket中所有Object的最后一次访问时间。

  2. 配置生命周期规则。

    1. 生命周期页面,单击创建规则

    2. 创建生命周期规则面板,按以下说明分别配置基于前缀data/以及前缀log/的生命周期规则。

      基于data/的生命周期规则
      基于log/的生命周期规则

      按以下说明配置基于data/的生命周期规则的必要参数,其他参数保留默认配置。

      配置项

      说明

      状态

      选中启动

      策略

      选中按前缀匹配

      前缀

      输入data/

      文件时间策略

      选中指定天数

      生命周期管理规则

      下拉选择最后一次访问时间,输入200天后,数据自动转换成低频存储类型(数据被访问后,依旧保留在低频档)

      按以下说明配置基于log/的生命周期规则的必要参数,其他参数保留默认配置。

      配置项

      说明

      状态

      选中启动

      策略

      选中按前缀匹配

      前缀

      输入log/

      文件时间策略

      选中指定天数

      生命周期管理规则

      • 下拉选择最后一次访问时间,输入120天后,数据自动转换成低频存储类型(数据被访问后,依旧保留在低频档)

      • 下拉选择最后一次访问时间,输入250天后,数据自动转换成归档类型

    3. 单击确定

使用阿里云SDK

Java SDK、Python SDK、Go SDK支持基于最后一次访问时间创建生命周期规则。创建基于最后一次访问时间的生命周期规则前,您需要为指定Bucket开启访问跟踪功能。

  1. 开启访问跟踪。

    Java
    Python
    Go
    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";
    
            // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
            String region = "cn-hangzhou";
    
            // 创建OSSClient实例。
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
            OSS ossClient = OSSClientBuilder.create()
            .endpoint(endpoint)
            .credentialsProvider(credentialsProvider)
            .clientConfiguration(clientBuilderConfiguration)
            .region(region)               
            .build();
    
            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();
                }
            }
        }
    }
    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    
    # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
    
    # 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
    # 填写Endpoint对应的Region信息,例如cn-hangzhou。注意,v4签名下,必须填写该参数
    region = "cn-hangzhou"
    
    # examplebucket填写存储空间名称。
    bucket = oss2.Bucket(auth, endpoint, "examplebucket", region=region)
    
    # 开启Bucket的访问跟踪状态。Bucket开启访问跟踪状态后,如果需要修改Bucket的访问跟踪状态为Disabled,请确保Bucket不存在基于LastAccessTime匹配规则的生命周期规则。
    bucket.put_bucket_access_monitor("Enabled")
    package main
    
    import (
    	"context"
    	"flag"
    	"log"
    
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
    )
    
    // 定义全局变量
    var (
    	region     string // 存储区域
    	bucketName string // 存储空间名称
    )
    
    // init函数用于初始化命令行参数
    func init() {
    	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
    	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
    }
    
    // 主函数,启用存储桶的访问跟踪
    func main() {
    	// 解析命令行参数
    	flag.Parse()
    
    	// 检查bucket名称是否为空
    	if len(bucketName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("invalid parameters, bucket name required")
    	}
    
    	// 检查region是否为空
    	if len(region) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("invalid parameters, region required")
    	}
    
    	// 加载默认配置并设置凭证提供者和区域
    	cfg := oss.LoadDefaultConfig().
    		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
    		WithRegion(region)
    
    	// 创建OSS客户端
    	client := oss.NewClient(cfg)
    
    	// 创建启用存储空间访问跟踪的请求
    	request := &oss.PutBucketAccessMonitorRequest{
    		Bucket: oss.Ptr(bucketName),
    		AccessMonitorConfiguration: &oss.AccessMonitorConfiguration{
    			Status: oss.AccessMonitorStatusEnabled, // 启用访问跟踪
    		},
    	}
    
    	// 执行启用存储空间访问跟踪的操作
    	putResult, err := client.PutBucketAccessMonitor(context.TODO(), request)
    	if err != nil {
    		log.Fatalf("failed to put bucket access monitor %v", err)
    	}
    
    	// 打印启用存储空间访问跟踪的结果
    	log.Printf("put bucket access monitor result: %#v\n", putResult)
    }
    
  2. 为前缀data/以及前缀log/配置基于最后一次访问时间的生命周期规则。

    Java
    Python
    Go
    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();
                }
            }
        }
    }
    # -*- 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))
    package main
    
    import (
    	"context"
    	"flag"
    	"log"
    
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
    	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
    )
    
    // 定义全局变量
    var (
    	region     string // 存储区域
    	bucketName string // 存储空间名称
    )
    
    // init函数用于初始化命令行参数
    func init() {
    	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
    	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
    }
    
    func main() {
    	// 解析命令行参数
    	flag.Parse()
    
    	// 检查bucket名称是否为空
    	if len(bucketName) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("invalid parameters, bucket name required")
    	}
    
    	// 检查region是否为空
    	if len(region) == 0 {
    		flag.PrintDefaults()
    		log.Fatalf("invalid parameters, region required")
    	}
    
    	// 加载默认配置并设置凭证提供者和区域
    	cfg := oss.LoadDefaultConfig().
    		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
    		WithRegion(region)
    
    	// 创建OSS客户端
    	client := oss.NewClient(cfg)
    
    	// 创建设置存储空间生命周期规则的请求
    	request := &oss.PutBucketLifecycleRequest{
    		Bucket: oss.Ptr(bucketName), // 存储空间名称
    		LifecycleConfiguration: &oss.LifecycleConfiguration{
    			Rules: []oss.LifecycleRule{
    				{
    					// 在生命周期规则1中指定前缀为data/的所有文件在距离最后一次访问时间200天后转为低频访问类型。且再次访问前缀为data/的文件时,这些文件仍保留为低频访问类型
    					ID:     oss.Ptr("rule1"),
    					Status: oss.Ptr("Enabled"),
    					Prefix: oss.Ptr("data/"),
    					Transitions: []oss.LifecycleRuleTransition{
    						{
    							Days:                 oss.Ptr(int32(200)),
    							StorageClass:         oss.StorageClassIA,
    							IsAccessTime:         oss.Ptr(true), // 设置为true,基于最后一次访问时间策略
    							ReturnToStdWhenVisit: oss.Ptr(false),
    						},
    					},
    				},
    				{
    					// 在生命周期规则2中指定前缀为log/的所有文件在距离最后一次访问时间120天后转为低频访问类型。且再次访问前缀为log/的文件时,这些文件仍保留为低频访问类型
    					// 同一规则中指定前缀为log/的所有文件在距离最后一次访问时间250天后转为归档类型。
    					ID:     oss.Ptr("rule2"),
    					Status: oss.Ptr("Enabled"),
    					Prefix: oss.Ptr("log/"),
    					Transitions: []oss.LifecycleRuleTransition{
    						{
    							Days:                 oss.Ptr(int32(120)),
    							StorageClass:         oss.StorageClassIA,
    							IsAccessTime:         oss.Ptr(true), // 设置为true,基于最后一次访问时间策略
    							ReturnToStdWhenVisit: oss.Ptr(false),
    						},
    						{
    							Days:                 oss.Ptr(int32(250)),
    							StorageClass:         oss.StorageClassArchive,
    							IsAccessTime:         oss.Ptr(true),
    							ReturnToStdWhenVisit: oss.Ptr(false),
    						},
    					},
    				},
    			},
    		},
    	}
    
    	// 执行设置存储空间生命周期规则的操作
    	result, err := client.PutBucketLifecycle(context.TODO(), request)
    	if err != nil {
    		log.Fatalf("failed to put bucket lifecycle %v", err)
    	}
    
    	// 打印设置存储空间生命周期规则的结果
    	log.Printf("put bucket lifecycle result:%#v\n", result)
    }
    

使用命令行工具ossutil

  1. 开启访问跟踪。

    1. 在本地config1.xml文件中配置开启访问跟踪。

      <?xml version="1.0" encoding="UTF-8"?>
      <AccessMonitorConfiguration>
          <Status>Enabled</Status>
      </AccessMonitorConfiguration>
    2. 为目标Bucket设置访问跟踪状态。

      ossutil access-monitor --method put oss://examplebucket/ config.xml
  2. 为前缀data/以及前缀/log配置基于最后一次访问时间的生命周期规则。

    1. 在本地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>
    2. 为目标Bucket设置生命周期规则。

      ossutil lifecycle --method put oss://examplebucket config2.xml

使用REST API

如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PutBucketAccessMonitorPutBucketLifecycle

相关文档

  • 本页导读 (1)
  • 场景说明
  • 前提条件
  • 操作步骤
  • 使用OSS控制台
  • 使用阿里云SDK
  • 使用命令行工具ossutil
  • 使用REST API
  • 相关文档

点击开启售前

在线咨询服务