HyperAI초신경
Back to Headlines

s3mini: 경량 S3 클라이언트, 엣지 컴퓨팅 지원

한 달 전

GitHub에서 good-lly/s3mini 프로젝트를 소개합니다. 이 프로젝트는 매우 경량화된 TypeScript 클라이언트로, 약 14KB의 크기와 최대 15% 더 빠른 작업 처리 속도를 제공합니다. s3mini는 AWS S3 호환 오브젝트 스토리지에 사용할 수 있으며, Node.js, Bun, Cloudflare Workers 등 다양한 엣지 플랫폼에서 실행됩니다. 또한 Cloudflare R2, Backblaze B2, DigitalOcean Spaces, MinIO, Garage 등의 서비스에서 테스트되었습니다. 웹 브라우저 지원은 제공하지 않습니다. 주요 기능 경량화 및 고속 처리: 약 15% 더 많은 작업 처리 속도를 자랑하며, 압축되지 않은 상태에서도 약 14KB의 크기를 유지합니다. 종속성 제로: AWS SigV4를 지원하되 사전 서명 요청(pre-signed requests)을 사용하지 않습니다. 엣지 컴퓨팅에 적합: Cloudflare Workers, Node.js, Bun 등에서 실행 가능하며, 브라우저 환경에서는 작동하지 않습니다. 필수 S3 API만 포함: 버킷 생성, 객체 업로드, 다운로드, 삭제 등 주요 S3 API를 제공합니다. 사용자 지정 S3 버킷: Cloudflare R2, Backblaze B2, DigitalOcean Spaces, MinIO, Garage 등과 호환되는 S3 버킷을 사용할 수 있습니다. Ceph와 AWS는 아직 테스트 중입니다. 테스트 환경 테스트는 로컬 Minio 인스턴스에서 진행되었습니다. 환경과 네트워크 상태에 따라 성능 테스트 결과가 달라질 수 있으므로 참고용으로만 활용하세요. 설치 방법 이 라이브러리는 Node.js, Bun, Cloudflare Workers와 같은 환경에서 실행하도록 설계되었습니다. 브라우저 환경에서는 Node.js API와 polyfills를 사용하기 때문에 지원하지 않습니다. Cloudflare Workers 설정 Node.js Crypto API를 사용하려면 Wrangler 구성 파일에 nodejs_compat 호환성 플래그를 추가하세요. 이 플래그는 2024년 9월 23일 이후의 호환성 날짜를 사용할 경우 자동으로 nodejs_compat_v2를 활성화합니다. 사용 예제 ```typescript import { s3mini, sanitizeETag } from 's3mini'; const s3client = new s3mini({ accessKeyId: config.accessKeyId, secretAccessKey: config.secretAccessKey, endpoint: config.endpoint, region: config.region, }); // 버킷 존재 확인 let exists: boolean = false; try { exists = await s3client.bucketExists(); } catch (err) { throw new Error(버킷 존재 확인 실패, 자격 증명이 잘못되었을 수도 있습니다: ${err.message}); } if (!exists) { // 버킷 생성 await s3client.createBucket(); } // 객체 존재 확인 및 업로드 const smallObjectKey: string = 'small-object.txt'; const smallObjectContent: string = '안녕, 세상!'; const objectExists: boolean = await s3client.objectExists(smallObjectKey); let etag: string | null = null; if (!objectExists) { const resp: Response = await s3client.putObject(smallObjectKey, smallObjectContent); etag = sanitizeETag(resp.headers.get('etag')); } // 객체 다운로드 const objectData: string | null = await s3client.getObject(smallObjectKey); console.log('객체 데이터:', objectData); // ETag를 사용한 객체 다운로드 const response2: Response = await s3mini.getObject(smallObjectKey, { 'if-none-match': etag }); if (response2) { const etag2: string = sanitizeETag(response2.headers.get('etag')); console.log('ETag를 사용한 객체 데이터:', response2.body, 'ETag:', etag2); } else { console.log('객체를 찾을 수 없거나 ETag가 일치하지 않습니다.'); } // 버킷 내 객체 목록 조회 const list: object[] | null = await s3client.listObjects(); if (list) { console.log('객체 목록:', list); } else { console.log('버킷에 객체가 없습니다.'); } // 객체 삭제 const wasDeleted: boolean = await s3client.deleteObject(smallObjectKey); // 멀티파트 업로드 const multipartKey = 'multipart-object.txt'; const large_buffer = new Uint8Array(1024 * 1024 * 15); // 15MB 버퍼 const partSize = 8 * 1024 * 1024; // 8MB const totalParts = Math.ceil(large_buffer.length / partSize); const uploadId = await s3client.getMultipartUploadId(multipartKey); const uploadPromises = []; for (let i = 0; i < totalParts; i++) { const partBuffer = large_buffer.subarray(i * partSize, (i + 1) * partSize); uploadPromises.push(s3client.uploadPart(multipartKey, uploadId, partBuffer, i + 1)); } const uploadResponses = await Promise.all(uploadPromises); const parts = uploadResponses.map((response, index) => ({ partNumber: index + 1, etag: response.etag, })); const completeResponse = await s3client.completeMultipartUpload(multipartKey, uploadId, parts); const completeEtag = completeResponse.etag; // 멀티파트 업로드 목록 조회 const multipartUploads: object = await s3client.listMultipartUploads(); // 멀티파트 업로드 취소 const abortResponse = await s3client.abortMultipartUpload(multipartUploads.key, multipartUploads.uploadId); // 멀티파트 다운로드 const rangeStart = 2048 * 1024; // 2MB const rangeEnd = 8 * 1024 * 1024 * 2; // 16MB const rangeResponse = await s3client.getObjectRaw(multipartKey, false, rangeStart, rangeEnd); const rangeData = await rangeResponse.arrayBuffer(); ``` 보안 주의사항 이슈 보고: 문제나 새로운 기능 요청이 있으면 GitHub 이슈를 열어주세요. 가능한 많이 세부 정보를 포함하여 환경, 오류 메시지, 로그, 재현 단계 등을 제공하세요. 풀 리퀘스트: 새로운 기능이나 버그 수정을 원한다면 최신 개발 브랜치에 풀 리퀘스트를 제출하세요. 큰 변경 사항은 먼저 이슈로 논의하는 것이 좋습니다. 경량화 철학: s3mini는 경량화와 종속성 제로를 유지하기 위해 노력하고 있으므로, 무거운 종속성을 추가하지 마세요. 새로운 기능은 크기 증가를 정당화할 만큼 중요한 가치를 가져야 합니다. 커뮤니티 행동 규칙: 모든 통신에서 존중과 건설적인 태도를 유지하세요. 자세한 내용은 CODE_OF_CONDUCT.md를 참조하세요. 라이선스 이 프로젝트는 MIT 라이선스 하에 배포됩니다. 자세한 내용은 LICENSE.md 파일을 참조하세요. 후원 s3mini와 다른 오픈 소스 프로젝트의 개발과 유지보수에는 시간과 노력이 필요합니다. 이 라이브러리가 유용하다고 생각된다면, 개발을 후원해 주세요. 여러분의 지원이 s3mini의 지속적인 개선과 발전에 큰 도움이 됩니다. 감사합니다! 업계 전문가들은 s3mini의 경량화와 고속 처리 능력이 엣지 컴퓨팅에서 특히 유용하다고 평가하고 있습니다. 이러한 특징은 리소스 제약이 있는 환경에서 효율적인 S3 작업을 가능하게 해줍니다. 또한, 이 프로젝트의 오픈 소스 성격 덕분에 커뮤니티의 참여와 개발이 활발히 이루어지고 있어, 더욱 다양한 기능과 안정성이 확보되고 있습니다.

Related Links