别再傻傻用S3了!用Python+boto3玩转Cloudflare R2,免费额度真香(附完整代码)

张开发
2026/6/1 10:51:49 15 分钟阅读
别再傻傻用S3了!用Python+boto3玩转Cloudflare R2,免费额度真香(附完整代码)
Python开发者必看Cloudflare R2存储的完整实战指南与S3成本优化方案如果你正在使用AWS S3存储数据每月账单是否让你感到压力或者作为个人开发者是否在寻找一个既经济实惠又不牺牲性能的云存储方案Cloudflare R2可能是你一直在等待的解决方案。与S3兼容的API、慷慨的免费额度以及无缝的CDN集成让R2成为开发者的新宠。1. 为什么选择Cloudflare R2而非AWS S3在云存储领域AWS S3长期占据主导地位但成本问题一直困扰着许多开发者。让我们看看R2如何在这些关键指标上脱颖而出成本对比每月指标AWS S3标准存储Cloudflare R2存储费用每GB$0.023$0.015读取请求每千次$0.0004免费写入请求每千次$0.005免费数据传输出站$0.09/GB免费免费额度无10GB存储操作提示R2的免费额度足够个人项目或小型应用使用而S3从第一GB就开始计费性能方面R2与Cloudflare全球CDN网络深度集成这意味着你的数据可以更快地送达终端用户。而S3需要额外配置CloudFront才能达到类似效果这又会增加复杂性和成本。2. 快速搭建你的第一个R2存储桶2.1 准备工作开始前你需要一个Cloudflare账户免费注册验证的支付方式仅用于身份验证不产生费用Python 3.6环境2.2 创建存储桶登录Cloudflare仪表板导航至R2部分点击创建存储桶输入唯一名称如my-app-data选择位置建议自动让Cloudflare优化点击创建# 安装必要的Python库 pip install boto33. 使用Python和boto3操作R2存储R2最吸引人的特性之一是其与S3 API的兼容性。这意味着你可以继续使用熟悉的boto3库只需稍作配置调整。3.1 基础配置首先获取你的API凭证在R2控制台点击管理R2 API令牌创建新令牌选择适当权限记录访问密钥和秘密密钥import boto3 from botocore.config import Config # R2配置 r2_config Config( signature_versions3v4, region_nameauto # R2的特殊区域标识 ) s3 boto3.client( s3, aws_access_key_id你的访问密钥, aws_secret_access_key你的秘密密钥, endpoint_urlhttps://[account-id].r2.cloudflarestorage.com, configr2_config )3.2 文件上传的两种方式方法一简单上传def upload_file(bucket_name, file_path, object_nameNone): 上传文件到R2存储桶 if object_name is None: object_name file_path try: s3.upload_file(file_path, bucket_name, object_name) print(f文件 {file_path} 上传成功) except Exception as e: print(f上传失败: {e}) # 使用示例 upload_file(my-app-data, local-file.txt, remote-file.txt)方法二流式上传适合大文件def upload_large_file(bucket_name, file_path, object_nameNone, chunk_size8*1024*1024): 分块上传大文件 if object_name is None: object_name file_path try: with open(file_path, rb) as data: s3.put_object( Bucketbucket_name, Keyobject_name, Bodydata ) print(f大文件 {file_path} 上传成功) except Exception as e: print(f上传失败: {e}) # 使用示例 upload_large_file(my-app-data, large-video.mp4)4. 高级操作与最佳实践4.1 生成预签名URL分享文件而不暴露凭证的安全方式def generate_presigned_url(bucket_name, object_name, expiration3600): 生成临时访问URL try: url s3.generate_presigned_url( get_object, Params{ Bucket: bucket_name, Key: object_name }, ExpiresInexpiration ) return url except Exception as e: print(f生成URL失败: {e}) return None # 生成1小时有效的URL file_url generate_presigned_url(my-app-data, remote-file.txt) print(f可分享的URL: {file_url})4.2 批量操作与监控列出存储桶内容def list_bucket_contents(bucket_name, prefix): 列出存储桶中的对象 try: contents [] paginator s3.get_paginator(list_objects_v2) for page in paginator.paginate(Bucketbucket_name, Prefixprefix): if Contents in page: for obj in page[Contents]: contents.append(obj[Key]) return contents except Exception as e: print(f列出内容失败: {e}) return [] # 使用示例 files list_bucket_contents(my-app-data) print(存储桶中的文件:, files)批量删除文件def delete_multiple_files(bucket_name, file_keys): 批量删除文件 try: objects [{Key: key} for key in file_keys] s3.delete_objects( Bucketbucket_name, Delete{Objects: objects} ) print(f成功删除 {len(file_keys)} 个文件) except Exception as e: print(f删除失败: {e}) # 使用示例 delete_multiple_files(my-app-data, [file1.txt, file2.txt])4.3 与Cloudflare CDN集成R2与Cloudflare CDN的无缝集成是其一大优势。启用CDN缓存可以显著提高内容分发速度在R2控制台选择你的存储桶点击设置选项卡启用通过Cloudflare CDN提供内容配置缓存规则默认7天启用后你的文件将通过Cloudflare的全球网络分发自动获得边缘缓存DDoS保护智能路由压缩优化5. 从S3迁移到R2的平滑过渡方案如果你已经有S3存储的数据迁移到R2可以分阶段进行5.1 双写策略过渡期def upload_to_both(s3_client, r2_client, file_path, bucket_name, object_nameNone): 同时写入S3和R2 if object_name is None: object_name file_path # 上传到S3 try: s3_client.upload_file(file_path, bucket_name, object_name) print(f文件 {file_path} 上传到S3成功) except Exception as e: print(fS3上传失败: {e}) # 上传到R2 try: r2_client.upload_file(file_path, bucket_name, object_name) print(f文件 {file_path} 上传到R2成功) except Exception as e: print(fR2上传失败: {e}) # 配置两个客户端 s3_client boto3.client(s3) # 默认AWS配置 r2_client ... # 之前的R2配置 # 使用示例 upload_to_both(s3_client, r2_client, data.json, my-bucket)5.2 数据同步工具对于大量现有数据可以使用以下工具自动迁移rclone命令行工具支持S3到R2的同步AWS DataSyncAWS官方迁移服务自定义脚本基于boto3的多线程迁移程序# 使用rclone同步示例 rclone copy s3://source-bucket r2://target-bucket --progress5.3 迁移后验证确保所有数据完整迁移def verify_migration(s3_client, r2_client, bucket_name): 验证S3和R2内容一致 s3_objects set(obj[Key] for obj in s3_client.list_objects_v2(Bucketbucket_name).get(Contents, [])) r2_objects set(obj[Key] for obj in r2_client.list_objects_v2(Bucketbucket_name).get(Contents, [])) only_in_s3 s3_objects - r2_objects only_in_r2 r2_objects - s3_objects if not only_in_s3 and not only_in_r2: print(验证通过所有文件已成功迁移) return True else: if only_in_s3: print(f以下文件仅在S3中存在: {only_in_s3}) if only_in_r2: print(f以下文件仅在R2中存在: {only_in_r2}) return False # 使用示例 verify_migration(s3_client, r2_client, my-bucket)6. 性能优化与成本控制技巧6.1 存储分层策略虽然R2没有像S3那样的存储类别但你可以实现自己的冷热数据分离热数据频繁访问保留在R2冷数据不常访问可考虑压缩后存储或迁移到更经济的方案def archive_cold_data(source_bucket, target_bucket, older_than_days30): 归档超过指定天数的冷数据 from datetime import datetime, timedelta cutoff datetime.now() - timedelta(daysolder_than_days) for obj in s3.list_objects_v2(Bucketsource_bucket).get(Contents, []): if obj[LastModified].replace(tzinfoNone) cutoff: # 复制到归档存储桶 s3.copy_object( Buckettarget_bucket, Keyobj[Key], CopySource{Bucket: source_bucket, Key: obj[Key]} ) # 删除原文件 s3.delete_object(Bucketsource_bucket, Keyobj[Key]) print(f已归档: {obj[Key]}) # 使用示例 archive_cold_data(my-app-data, my-archive-data)6.2 请求优化即使R2的请求费用较低优化API调用仍能提升性能批量操作合并多个小文件缓存结果减少重复列表请求适当分页处理大量对象时def batch_upload(bucket_name, local_folder): 批量上传文件夹内容 from os import listdir from os.path import isfile, join files [f for f in listdir(local_folder) if isfile(join(local_folder, f))] for file in files: file_path join(local_folder, file) s3.upload_file(file_path, bucket_name, file) print(f已上传: {file}) # 使用示例 batch_upload(my-app-data, ./data-files)6.3 监控与告警设置基本监控以避免意外费用def check_storage_usage(bucket_name, warning_threshold_gb9): 检查存储使用量是否接近免费额度 total_size 0 paginator s3.get_paginator(list_objects_v2) for page in paginator.paginate(Bucketbucket_name): if Contents in page: for obj in page[Contents]: total_size obj[Size] total_gb total_size / (1024 ** 3) print(f当前存储使用量: {total_gb:.2f} GB) if total_gb warning_threshold_gb: print(f警告: 存储使用量接近10GB免费额度!) return total_gb # 使用示例 check_storage_usage(my-app-data)在实际项目中我发现R2的API响应速度在亚太地区尤其出色这得益于Cloudflare的全球网络布局。对于需要频繁读写的应用R2相比S3能提供更一致的性能表现特别是在处理大量小文件时。

更多文章