Skip to content

Cloudflare:R2

R2를 이용해 S3와 호환 가능한 개체 스토리지로 원하는 멀티 클라우드 아키텍처를 자유롭게 생성할 수 있습니다.

  • 글로벌 개체 스토리지
  • Cloudflare Workers와의 통합으로 제공되는 동적 기능
  • Cloudflare의 S3 호환 API로 벤더 종속 방지

R2 가격 정책

R2는 저장된 데이터의 총량과 해당 데이터의 두 작업 클래스에 따라 요금이 부과됩니다. 송신료가 없습니다.

-

평생 무료

월 요금

스토리지

10GB/월

$0.015/1GB

클래스 A 작업: 변형 상태

1,000,000/월

$4.50/백만

클래스 B 작업: 기존 상태 읽기

10,000,000/월

$0.36/백만

송신 (인터넷으로 데이터 전송)
Workers API, S3 API 및 r2.dev 도메인을 통하는 것을 포함하여 R2에서 직접 송신하는 경우 데이터 전송(송신) 요금이 발생하지 않으며 무료입니다.
다른 측정 서비스를 R2 버킷에 연결하면 해당 서비스에 따라 요금이 부과될 수 있습니다.

Storage usage

스토리지는 청구 지표로 기가바이트-월(GB-월)을 사용하여 청구됩니다. GB-월은 해당 월의 기간 동안 저장된 총 바이트를 기록하여 계산됩니다. (duration of the month)

예를 들어:

  • 30일 동안 1GB를 저장하면 1GB-월로 요금이 부과됩니다.
  • 15일 동안 2GB를 저장하면 1GB-월로 요금이 부과됩니다.

아마도 다음과 같은 공식이 적용되는 듯 하다.

저장된 총 GB * (저장된 기간 / 30일)

Operation Categories

요금에 영향이 있는 연산들 이다.

Class A operations

Class A Operations include ListBuckets, PutBucket, ListObjects, PutObject, CopyObject, CompleteMultipartUpload, CreateMultipartUpload, ListMultipartUploads, UploadPart, UploadPartCopy and PutBucketEncryption. ​​

Class B operations

Class B Operations include HeadBucket, HeadObject, GetObject, UsageSummary, GetBucketEncryption and GetBucketLocation. ​​

Free operations

Free operations include DeleteObject, DeleteBucket and AbortMultipartUpload.

버킷 만들기 및 API 토큰 만들기

Cloudflare_r2_-_overview.png

R2 에 들어가면 버킷을 만들거나 "Manage R2 API Tokens" 링크가 있다:

Cloudflare_r2_-_create_bucket.png

버킷을 만들때 특별한 경우가 아니면 "자동" (R2는 사용자의 위치를 기준으로 사용 가능한 가장 가까운 지역에 버킷을 자동으로 배치합니다) 을 선택하자.

Cloudflare_r2_-_create_api_token.png

"Manage R2 API Tokens" 링크를 클릭하여 토큰을 만들 수 있다.

Cloudflare_r2_-_create_api_token_result.png

토큰을 생성하면 여러 Access Key ID, Secret Access Key, Endpoint URL 가 출력된다. 그리고 버킷명과 해당 버킷의 region (아시아: apac)을 기억하면 된다.

boto3 example

import boto3

s3 = boto3.client(
    service_name ="s3",
    endpoint_url = 'https://<accountid>.r2.cloudflarestorage.com',
    aws_access_key_id = '<access_key_id>',
    aws_secret_access_key = '<access_key_secret>',
    region_name="<location>", # Must be one of: wnam, enam, weur, eeur, apac, auto
)

# Get object information
object_information = s3.head_object(Bucket=<R2_BUCKET_NAME>, Key=<FILE_KEY_NAME>)

# Upload/Update single file
s3.upload_fileobj(io.BytesIO(file_content), <R2_BUCKET_NAME>, <FILE_KEY_NAME>)

# Delete object
s3.delete_object(Bucket=<R2_BUCKET_NAME>, Key=<FILE_KEY_NAME>)

aws-sdk-js-v3 example

import {
  S3Client,
  ListBucketsCommand,
  ListObjectsV2Command,
  GetObjectCommand,
  PutObjectCommand
} from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const S3 = new S3Client({
  region: "auto",
  endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: ACCESS_KEY_ID,
    secretAccessKey: SECRET_ACCESS_KEY,
  },
});

console.log(
  await S3.send(
    new ListBucketsCommand('')
  )
);
// {
//     '$metadata': {
//     httpStatusCode: 200,
//         requestId: undefined,
//         extendedRequestId: undefined,
//         cfId: undefined,
//         attempts: 1,
//         totalRetryDelay: 0
// },
//     Buckets: [
//     { Name: 'user-uploads', CreationDate: 2022-04-13T21:23:47.102Z },
//     { Name: 'my-bucket-name', CreationDate: 2022-05-07T02:46:49.218Z }
//     ],
//     Owner: {
//         DisplayName: '...',
//         ID: '...'
//     }
// }

console.log(
  await S3.send(
    new ListObjectsV2Command({ Bucket: 'my-bucket-name' })
  )
);
// {
//     '$metadata': {
//       httpStatusCode: 200,
//       requestId: undefined,
//       extendedRequestId: undefined,
//       cfId: undefined,
//       attempts: 1,
//       totalRetryDelay: 0
//     },
//     CommonPrefixes: undefined,
//     Contents: [
//       {
//         Key: 'cat.png',
//         LastModified: 2022-05-07T02:50:45.616Z,
//         ETag: '"c4da329b38467509049e615c11b0c48a"',
//         ChecksumAlgorithm: undefined,
//         Size: 751832,
//         StorageClass: 'STANDARD',
//         Owner: undefined
//       },
//       {
//         Key: 'todos.txt',
//         LastModified: 2022-05-07T21:37:17.150Z,
//         ETag: '"29d911f495d1ba7cb3a4d7d15e63236a"',
//         ChecksumAlgorithm: undefined,
//         Size: 279,
//         StorageClass: 'STANDARD',
//         Owner: undefined
//       }
//     ],
//     ContinuationToken: undefined,
//     Delimiter: undefined,
//     EncodingType: undefined,
//     IsTruncated: false,
//     KeyCount: 8,
//     MaxKeys: 1000,
//     Name: 'my-bucket-name',
//     NextContinuationToken: undefined,
//     Prefix: undefined,
//     StartAfter: undefined
//   }

Presigned URLs

보안에 관련된 내용.

See also

Favorite site