如何在R中通过AWS CloudFront访问Amazon S3存储桶数据
核心概念澄清(解决S3/EC2/CloudFront关系误解)
- EC2是承载你R Shiny应用的云服务器,仅提供计算运行环境,你之前的逻辑是跑在EC2上的Shiny应用直接调用S3 API拉取存储数据
- S3是对象存储服务,是你数据的原始存储端,默认访问S3私有资源需要有效的AWS身份凭证,也就是你当前通过
Sys.setenv()配置的访问密钥、秘密访问密钥等信息 - CloudFront是CDN分发服务,属于S3源站和请求端(你的Shiny应用)之间的缓存层,配置分发后会生成专属的CloudFront域名,请求该域名的资源时,CloudFront优先返回本地缓存内容,缓存未命中时才会回源到S3拉取,不需要请求端提供S3访问凭证
切换为CloudFront拉取数据的操作步骤
- 先确认CloudFront分发配置有效
- 需要拉取的S3对象路径已经纳入CloudFront缓存行为的允许访问范围
- 如果S3桶为私有桶,已经配置源访问控制(OAC) 并为CloudFront授予S3桶访问权限,避免请求返回403错误
- 记录你的CloudFront分发域名,格式为
xxxxxx.cloudfront.net
- 修改Shiny应用的数据拉取逻辑
- 原有拉取S3数据的逻辑一般是调用
aws.s3包的s3read_using()、get_object()等S3 API类函数,指定桶名和对象键拉取 - 替换为普通HTTP请求即可,比如用
httr包发起请求,拼接请求地址为https://<CloudFront分发域名>/<S3对象键>,示例代码如下:
library(httr) # 示例:S3对象键为data/user_data.csv,CloudFront域名为d123456abcdef.cloudfront.net resp <- GET("https://d123456abcdef.cloudfront.net/data/user_data.csv") # 解析返回的CSV数据 user_data <- read.csv(text = content(resp, "text"))- 原有EC2上配置的S3访问密钥相关环境变量可以直接删除,请求CloudFront无需该类凭证
- 原有拉取S3数据的逻辑一般是调用
- 验证请求来源
两种方式可以确认数据确实从CloudFront返回:- 查看HTTP请求的响应头,CloudFront返回的响应会携带
x-cache、x-amz-cf-id专属字段,x-cache值为Hit from cloudfront代表缓存命中,Miss from cloudfront代表回源拉取 - 到AWS CloudFront控制台查看对应分发的监控指标,访问后会有请求数、缓存命中率等数据更新,有对应数据即可证明请求已经接入CloudFront
- 查看HTTP请求的响应头,CloudFront返回的响应会携带
常见注意事项
- 如果S3对象更新后需要即时生效,可以到CloudFront控制台执行缓存无效化操作,清除对应路径的旧缓存
- 如果数据不允许公开访问,可以为CloudFront配置签名URL/签名Cookie,在Shiny应用内生成有效签名地址后再发起请求,避免未授权访问
- 同区域EC2直接拉取S3数据无流量费用,走CloudFront会产生CDN流量费用,同时会降低S3的请求频次,可根据自身访问量评估成本变化
内容的提问来源于stack exchange,提问作者Alex DaSilva
相关产品推荐
相关产品推荐

