티스토리 뷰

The Story

  • AWS S3 비싸요 (GCS나 Azure나 네이버나 토스트나 다 비슷한 가격)
  • STORJ-DCS 가 wasabi 보다 살짝 싸요 근데 블록체인 기반코인 기반/30조각 분산형이라 느려요
  • minio 를 중계서버로 두면 비빌만 한 거 같아요
    -> STORJ DCS 게이트웨이에서 퍼블릭으로 공개하는 기능이 미지원이라 실패

STORJ

암호화폐 "스토리지 코인(STORJ, 업비트에서 거래됨, 이더리움 ERC-20 기반 토큰)" 을 말합니다.

이 코인은 캐는 방식이 독특한데, 하드에 남는 저장공간을 대여해주는 걸로 코인을 캘 수 있습니다. 파일을 암호화한 뒤 대충 30개 정도로 쪼개서 각각의 채굴자에게 나눠줘서 저장하게 했다가, 고객이 파일을 요청하면 그 중 20개정도였나? 만 받아와서 복원하는 방식입니다. (*정확히는 캐는 게 아니고 월급을 받는 것 같은 개념이라고 합니다.)

sia 코인과는 다르게 중앙통제식라 가격이 고정이고 항상 storj-labs가 운영하는 새틀라이트를 거쳐서 파일을 받아올 노드를 발견하는 것으로 알고있습니다.

STORJ-DCS

storj-dcs (구 tardigrade) 는 이 블록체인(아니래요)/코인을 사용한 파일 호스팅 서비스입니다. AWS S3 와 유사한 서비스죠. 이걸 API로 접근하려면 3가지 방법이 있습니다.

  • uplink 및 uplink CLI - 망에 네이티브로 연결하는 자체 구현체, S3 비호환
  • minio 의 개조판인 gateway-st 혹은 gateway-mt 를 직접 설치해서 구동
  • storj-DCS 측이 제공하는 gateway-mt 서버를 S3 호환 API로 사용
    -> ap1.storj.io 를 쓰면 됩니다.

1, 2번은 연산량에 의한 요구사양 때문에 관심이 없고, 3번 방법을 쓸겁니다. 아래 같은 구조로 구성할 겁니다.

내 서버
-> 내 서버의 minio gateway (cache 활성화됨)
-> ap1.storj.io (얘가 연산함, storj-labs 에서 설치해놓은 무료 gateway-mt - 주소는 https://gateway.ap1.storjshare.io)
-> storj 새틀라이트
-> 저장소 노드들 (채굴자들)

STORJ-DCS + mastodon SNS의 파일 업로드

mastodon 이라는 설치형 SNS가 있습니다. 생긴건 트위터 같은데, 이건 사실 SNS계의 이메일입니다. 그러니까 한 버서에 가입하면 다른 서버에 설치된 마스토돈 (및 호환 SNS) 의 유저에게도 이메일을 보내듯이 글을 보내거나 구독할 수 있다는 말이죠. 그러다보니 나 홀로 쓰려고 NAS에 설치해도 다른 서버의 유저와 대화하면 되니까 의미가 없지 않습니다. 저도 제 NAS에 설치해서 쓰고있구요. 자세한 건 메인 블로그에 써놓은 간판글을 보시라.

아무래도 마스토돈이 SNS 서버다보니 유저들이 파일을 올리다보면 서버 용량이 꽉 차버리지 않을까 노심초사하게 됩니다. 그래서 오브젝트 스토리지를 쓰는 거겠죠. AWS S3가 제일 편한 옵션이고 지금 거길 연결해서 쓰고있는데 비싸잖아요... 저야 혼자 쓰니까 몇백원밖에 안 나오지만요. 규모가 커지고 회원을 더 많이 받는다면 어떨까요? 제 주 계정을 제가 직접 운영하는 곳으로 옮겨서 하루가 멀다하고 20MB씩 영상을 올린다면 어떨까요? 으악

그래서 가격이 더 싼 STORJ DCS가 눈에 들어오는겁니다. AWS S3 오브젝트 스토리지를 STORJ DCS 로 대체하는거죠. 그럼 S3보다 더 싼 값으로 대용량의 SNS 미디어 파일을 업로드할 수 있겠죠?

예전에 비슷한 짓을 한 적이 있는데 너무 느리고 오류가 많았어요. 그 때에는 minio 게이트웨이 (캐시) 를 두지 않았는데 원래 느리고 오류가 많은가보다 하고 생각했습니다. 그래서 캐시를 두자는 생각을 한 건데요, 하지만 이번에 minio 게이트웨이를 STORJ DCS로 가는 로컬 캐시로 두기 위한 테스트를 하면서 멀티파트 업로드 설정 문제라는 걸 알게 되었고, 업로드 속도는 봐줄만한 정도라는 걸 확인했습니다. 이 문제는 나중에 다시 언급하기로 하구요.

STORJ-DCS 계정 생성 및 버킷 생성

은 생략합니다. 전 이미 예전에 써본다고 다 해놔서요 ㅎㅎ

minio 로 STORJ-DCS 캐싱하기

내 서버의 마스토돈과 STORJ-DCS 사이에 로컬 minio 로 캐싱을 두기로 했으면 방법을 조사해봐야 합니다. 두 가지 방안을 생각해봤습니다.

  1. 로컬 minio 를 S3 호환 게이트웨이 (+ 캐시) 로 열어서 쓰기
  2. 로컬 minio 를 주 저장소로 쓰고 버킷에 lifecycle 을 설정해서 며칠 뒤에 STORJ DCS 로 옮기기
  3. minio 안 쓰고 nginx 에만 캐시 설정

결과적으로 1번을 택했는데, 1번이 나름 나쁘지 않게 동작했고, 2번은 진짜 캐시가 아니므로 용량을 얼마나 쓸지 감이 안 왔기 때문입니다. lifecycle 기능으로는 마지막 액세스를 기준으로 옮겼다가 되돌렸다가 하는 게 설정만으로는 안 되고 별도의 외부 코드가 있어야 한다는 모양이더라구요.

지금 생각해보면 그냥 마스토돈만 멀티파트 업로드 안 쓰게 잘 설정하고 nginx 캐싱만 잘 설정했어도 괜찮았을 것 같습니다. 근데 일단 칼을 빼들었으니 끝까지 가봐야겠습니다.

minio S3 호환 gateway with 캐시 - 테스트

minio 를 다른 저장소의 게이트웨이로 설정해서 실행할 수 있습니다. 저희는 S3가 필요하겠죠. 캐시 기능이 있으므로 그걸 설정해서 켤 겁니다.

문서

https://docs.min.io/docs/minio-gateway-for-s3.html

캐시 없이 게이트웨이 켜기

docker run \
  -p 9000:9000 \
  -p 9001:9001 \
  -e "MINIO_ROOT_USER=STORJ_DCS_액세스_키" \
  -e "MINIO_ROOT_PASSWORD=STORJ_DCS_시크릿_키" \
  minio/minio gateway s3 "https://gateway.ap1.storjshare.io" --console-address ":9001"

캐시 설정하기

https://github.com/minio/minio/blob/master/docs/disk-caching/DESIGN.md

요 부분에서 옵션들이 중요합니다.

먼저 캐싱 기능이 리눅스 파일 시스템의 atime (마지막으로 파일에 접근한 시간) 기능을 사용합니다. 그래서 현재 버전 가이드에는 도커로 실행할거면 별도로 atime 을 켜서 마운트한 경로를 쓰라고 되어있습니다.

# https://github.com/minio/minio/blob/master/docs/disk-caching/DESIGN.md
truncate -s 4G ~/minio_cache_file
mkfs.xfs ~/minio_cache_file
sudo mkdir /mnt/minio_cache_file
# sudo mkdir /mnt/minio_cache && sudo chown ch:ch /mnt/minio_cache
sudo mount -o relatime ~/minio_cache_file /mnt/minio_cache
-v /mnt/minio_cache:/minio_cache

리눅스의 마운트 옵션 atime 에는 찾아보니 strictatime, relatime 이 있고, 요즘 리눅스는 relatime 이 기본이랍니다. strictatime 은 진짜로 접근할 때마다 마지막 접근 시간을 갱신해서 느리고, relatime 은 타협을 좀 본 옵션입니다. 이거면 충분하죠.

로컬 시스템의 atime 도 relatime 으로 죄다 마운트되어있길래 그냥 심플하게 도커 볼륨으로 땡치기로 했습니다. 대신 이렇게 하면 남은 용량 계산의 조회가 전체 디스크를 기준으로 잡아버리는 것 같더라구요. minio 실행할 때 표준 출력에 캐시용 드라이브의 남은 공간 정보가 나옵니다.

docker run \
  -p 9000:9000 \
  -p 9001:9001 \
  -v minio_cache:/cache \
  -e "MINIO_ROOT_USER=STORJ_DCS_엑세스키" \
  -e "MINIO_ROOT_PASSWORD=STORJ_DCS_시크릿" \
  -e "MINIO_CACHE_DRIVES=/cache" \
  -e "MINIO_CACHE_QUOTA=99" \
  -e "MINIO_CACHE_AFTER=0" \
  -e "MINIO_CACHE_WATERMARK_LOW=90" \
  -e "MINIO_CACHE_WATERMARK_HIGH=95" \
  -e "MINIO_CACHE_COMMIT=writethrough" \
  minio/minio gateway s3 "https://gateway.ap1.storjshare.io" --console-address ":9001"

나머지는 대충 문서를 보시면 될 듯 합니다.

귀찮으니 compose 로 바꿔서 굴리고 있습니다. 시크릿은 .env 파일에. (MINIO_ROOT_USER 는 STORJ DCS 엑세스 키이고 MINIO_ROOT_PASSWORD 는 STORJ DCS 시크릿입니다.)

version: '3.3'
services:
    minio:
        ports:
            - '19292:9000'
            - '19293:9001'
        volumes:
            - minio_cache:/cache
        environment:
            - MINIO_ROOT_USER=${MINIO_ROOT_USER}
            - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
            - MINIO_CACHE_DRIVES=/cache
            - MINIO_CACHE_QUOTA=10
            - MINIO_CACHE_AFTER=0
            - MINIO_CACHE_WATERMARK_LOW=80
            - MINIO_CACHE_WATERMARK_HIGH=90
            - MINIO_CACHE_COMMIT=writethrough
        image: minio/minio
        command: gateway s3 'https://gateway.ap1.storjshare.io' --console-address ":9001"
volumes:
    minio_cache:

멀티파트 업/다운 오류

MINIO_CACHE_COMMIT 이 최근에 추가된 옵션인데 (writethrough, writeback) 두 가지 옵션이 있는 것 같습니다. 아마 문서가 나중에 개선되겠죠. 설정 안 하면 추정컨데 writethrough 인 것 같습니다. 아무튼 어느쪽이던 멀티파트로 다운로드하고 업로드하면 둘 중 한 곳에서 오류가 납니다. 그대로 멈춰버리거나 캐싱이 안 되거나...

minio-client로 테스트 시 꼭 --disable-multipart 를 붙여줍시다.

$ mcli alias set storj_gateway http://172.17.0.2:9000 STORJ_DCS_엑세스키 STORJ_DCS_시크릿
$ time mcli cp --disable-multipart storj_gateway/버킷이름/v.mkv ./v_copy.mkv
...wmoe/v.mkv:  294.83 MiB / 294.83 MiB ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 105.68 MiB/s 2s      sss    ┃
real	0m3.363s
user	0m0.198s
sys	0m0.763s

실제 사용은 마스토돈에서 할테니까, 마스토돈에도 설정해야 합니다. Google Cloud Storage 를 쓰더라도 멀티파트 업다운이 안 되므로 꺼야한다고 하네요.

# 이거 말고
S3_MULTIPART_THRESHOLD=52428801 # 50.megabytes

# 이거 - https://github.com/mastodon/mastodon/pull/16866
# (^ 2021년 10월)
# thanks - https://qdon.space/@jarm/107219707542996082
# 최신버전 3.4.1 (2021년 6월) 에서는 안 될 겁니다. 다음버전에서 될 듯
S3_FORCE_SINGLE_REQUEST=true

# 지금으로서는 둘 다 하죠 ㅎㅎ

minio 버킷 공개하기

저는 예전에 테스트해본다고 uplink CLI 로 storj DCS 쪽의 버킷을 아예 퍼블릭으로 만들었었습니다. 근데 minio 로 캐싱할거면 그건 필요없고 대신 minio 쪽 버킷이 퍼블릭 GET이 가능하게 공개되어 있어야 하겠죠.

./mc alias set minio_gateway http://127.0.0.1:19292/
./mc alias set storj_gateway https://gateway.ap1.storjshare.io

./mc --debug policy set download minio_gateway/버킷이름
랑
./mc --debug policy set download storj_gateway/버킷이름
둘 다 해봄

GET /버킷이름/?location= HTTP/1.1
HTTP/1.1 200 OK

GET /버킷이름/?policy= HTTP/1.1
HTTP/1.1 501 Not Implemented
헤더는 다른 거 없음

c: <ERROR> Unable to set policy `download` for `minio_gateway/버킷이름`. A header you provided implies functionality that is not implemented
 (2) policy-main.go:352 cmd.runPolicyCmd(..) Tags: [minio_gateway/버킷이름, download]
 (1) anonymous-main.go:260 cmd.doSetAccess(..) Tags: [minio_gateway/버킷이름, download]
 (0) client-s3.go:1349 cmd.(*S3Client).SetAccess(..)
 Release-Tag:RELEASE.2021-10-07T04-19-58Z | Commit:198bca9cdf23 | Host:호스트명 | OS:linux | Arch:amd64 | Lang:go1.17.1 | Mem:1.9 MB/16 MB | Heap:1.9 MB/7.8 MB.

는 여기서 막힘. 아무래도 minio gateway 모드는 원격에 구현 안 된 거면 똑같이 미제공하나봅니다.

"응 안해줘 DNS 넣어"

https://forum.storj.io/t/storj-public-access-as-aws-s3-bucket/13167

nginx 프록시를 써서 캐싱하는 방법을 다음에 시도해봐야겠습니다.

=> 나중에 프록시 없이 그냥 붙여봤는데, 업로드는 10초씩 막 걸리는데 다운로드는 생각외로 빠르더라구요. 역시 에러나던건 멀티파트가 문제였어

최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함