구글 포토 유료화 탈출: 시놀로지 포토(Synology Photos) 4TB 마이그레이션 및 메타데이터 복구 실전 가이드

개발자로서 가장 견디기 힘든 순간은 내 데이터에 대한 통제권을 잃었을 때입니다. 지난 10년, 결혼식부터 아이의 탄생까지 약 5만 장, 4TB에 달하는 고화질 사진을 GooglePhotos(구글 포토)에 의존해왔습니다. 하지만 '무제한 무료' 정책이 종료되고, 스토리지 요금제가 매달 청구서에 찍히기 시작하면서 상황은 달라졌습니다. 단순히 비용 문제가 아니었습니다. 구글의 압축 알고리즘이 원본을 미세하게 훼손한다는 사실과, API 호출 제한으로 인해 내 데이터를 로컬로 백업하는 것조차 까다롭다는 점이 엔지니어로서의 본능을 자극했습니다. 결국 저는 클라우드 종속성에서 벗어나 온프레미스(On-Premise) 환경인 Synology Photos로의 완전한 이주를 결심하게 되었습니다. 이 글은 단순한 리뷰가 아닙니다. 4TB의 데이터를 손실 없이 옮기기 위해 겪었던 파일 시스템의 타임스탬프 오류와 이를 해결하기 위해 작성한 스크립트, 그리고 5년 기준 TCO(총소유비용) 분석을 담은 기술 보고서입니다.

클라우드 vs 로컬 NAS: 아키텍처와 병목 현상 분석

마이그레이션을 시작하기 전, 두 시스템의 근본적인 차이를 이해해야 했습니다. GooglePhotos는 전형적인 객체 스토리지(Object Storage) 기반의 SaaS입니다. 확장성이 뛰어나고 전 세계 어디서나 접근 속도가 빠르지만, 데이터의 '소유' 개념이 희석됩니다. 반면 Synology Photos는 블록 스토리지 위에 구축된 파일 시스템 기반의 애플리케이션입니다. 이는 데이터의 물리적 위치가 명확하다는 장점이 있지만, 네트워크 대역폭과 하드웨어 성능이 병목이 될 수 있음을 의미합니다.

제가 구축한 환경은 다음과 같습니다.

  • NAS 모델: Synology DS920+ (4 Bay)
  • HDD: IronWolf 8TB x 4 (RAID 5 구성, 가용 용량 약 21TB)
  • Network: 내부망 1Gbps, 외부망 500Mbps (KT GiGA)
  • Source Data: Google Takeout으로 내려받은 54,302개의 파일 (HEIC, JPG, MOV 혼합)
Critical Error: Google Takeout을 통해 내려받은 압축 파일(ZIP)을 해제하자, 모든 사진의 '생성 날짜(Created Date)'가 촬영일이 아닌 압축 해제 시점(오늘 날짜)으로 변경되는 참사가 발생했습니다.

이 현상은 파일 시스템(File System) 레벨의 메타데이터와 파일 내부의 EXIF(Exchangeable Image File Format) 메타데이터가 불일치하기 때문에 발생합니다. 윈도우 탐색기나 맥의 Finder는 파일 시스템의 날짜를 우선적으로 보여주는 경우가 많고, 일부 레거시 뷰어들은 EXIF가 깨진 경우 파일 생성일을 기준으로 정렬해버립니다. 결과적으로 2015년에 찍은 사진이 2024년 타임라인에 섞여 들어가는 '타임라인 붕괴' 현상이 발생했습니다.

실패한 접근: 단순 복사와 SMB 전송

처음에는 단순히 Google Drive와 NAS를 동기화하는 'Cloud Sync' 기능을 사용하려 했습니다. 이론상으로는 완벽해 보였습니다. 하지만 구글은 Google Photos의 원본 파일에 대한 직접적인 파일 시스템 접근 권한을 더 이상 제공하지 않습니다. 'Google Drive 내의 Google Photos 폴더' 기능이 삭제되었기 때문입니다.

그다음 시도한 것은 웹 브라우저 다운로드였습니다. 하지만 500장씩 선택해서 다운로드해야 하는 UI의 한계는 5만 장의 사진 앞에서는 불가능에 가까웠습니다. 결국 공식 데이터 반출 도구인 Google Takeout을 사용해야 했는데, 여기서 또 다른 문제가 발생했습니다. 구글은 메타데이터(설명, 위치 정보, 날짜 수정 내역)를 이미지 파일에 덮어쓰지 않고, 별도의 .json 사이드카(Sidecar) 파일로 분리해서 제공합니다. 즉, IMG_1234.JPGIMG_1234.JPG.json이 쌍으로 존재하게 되는데, 시놀로지 포토는 이 JSON 파일을 자동으로 읽어들이지 못합니다. 이대로 업로드하면 사진의 GPS 태그와 사용자가 구글 포토에서 수정한 날짜 정보가 모두 증발합니다.

해결책: Python과 ExifTool을 이용한 메타데이터 병합

이 문제를 해결하기 위해서는 분리된 JSON 파일의 정보를 읽어, 원본 이미지 파일의 EXIF 헤더에 다시 주입(Inject)하는 전처리 과정이 필수적입니다. 저는 exiftool이라는 강력한 CLI 도구와 이를 제어하는 Python 스크립트를 작성하여 이 문제를 해결했습니다.

아래 코드는 폴더를 순회하며 JSON 사이드카 파일이 있는 경우, 해당 메타데이터(촬영 일시, GPS 좌표)를 원본 이미지에 강제로 덮어씌우는 스크립트의 핵심 로직입니다.

import os
import subprocess
import json
from datetime import datetime

# 설정: 구글 테이크아웃 데이터 경로
SOURCE_DIR = "/volume1/homes/user/drive/Takeout/Google Photos"

def merge_metadata(root, filename):
    base_name = filename
    # JSON 파일명 추론 (Google Takeout의 파일명 패턴 대응)
    json_name = base_name + ".json" 
    
    image_path = os.path.join(root, filename)
    json_path = os.path.join(root, json_name)

    if not os.path.exists(json_path):
        # 이름 뒤에 숫자가 붙는 중복 파일 케이스 처리 (예: IMG(1).jpg -> IMG.jpg(1).json)
        # 실제 환경에서는 정규식으로 더 정교하게 처리해야 함
        return

    try:
        with open(json_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
            
            # JSON에서 타임스탬프 추출 (String -> Unix Timestamp)
            photo_taken_time = data.get('photoTakenTime', {}).get('timestamp')
            geo_data = data.get('geoData', {})
            
            if photo_taken_time:
                # ExifTool 명령어 생성
                # -AllDates: 촬영일, 생성일, 수정일 모두 동기화
                # -overwrite_original: 원본 덮어쓰기 (백업 필수)
                cmd = [
                    "exiftool",
                    f"-AllDates={datetime.fromtimestamp(int(photo_taken_time))}",
                    "-overwrite_original",
                    image_path
                ]
                
                # GPS 정보가 있다면 추가
                if geo_data.get('latitude') and geo_data.get('longitude'):
                    lat = geo_data['latitude']
                    lon = geo_data['longitude']
                    cmd.insert(1, f"-GPSLatitude={lat}")
                    cmd.insert(2, f"-GPSLongitude={lon}")
                
                # 서브프로세스 실행
                subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL)
                print(f"[SUCCESS] Processed: {filename}")

    except Exception as e:
        print(f"[ERROR] Failed {filename}: {str(e)}")

# 메인 실행 루프
for root, dirs, files in os.walk(SOURCE_DIR):
    for file in files:
        if file.lower().endswith(('.jpg', '.jpeg', '.heic', '.png')):
            merge_metadata(root, file)

위 스크립트에서 가장 중요한 부분은 -AllDates 옵션을 사용하는 것입니다. 이는 DateTimeOriginal(촬영일), CreateDate(생성일), ModifyDate(수정일)을 한 번에 통일시켜 시놀로지 포토가 타임라인을 구성할 때 혼선을 빚지 않도록 강제합니다. 특히 subprocess.run을 통해 exiftool을 직접 호출하는 방식은 Python 라이브러리(Pillow 등)를 사용하는 것보다 훨씬 더 광범위한 포맷(HEIC, MOV 등)을 안정적으로 지원합니다.

이 전처리 과정을 거친 후 NAS의 /photo 폴더로 데이터를 이동시키면, Synology Photos의 인덱싱 서비스가 백그라운드에서 돌아가며 썸네일을 생성하고 얼굴 인식을 시작합니다.

성능 및 비용 효율성 검증 (TCO 분석)

마이그레이션 완료 후 3개월간 운영하며 수집한 데이터를 바탕으로 구글 포토 유지 시와 시놀로지 구축 시의 비용과 성능을 비교해보았습니다.

비교 항목 Google Photos (2TB 요금제) Synology Photos (DS920+ 40TB)
초기 구축 비용 0원 약 1,200,000원 (본체 + HDD)
5년 유지 비용 약 894,000원 (월 14,900원 기준) 약 1,350,000원 (전기세 포함)
저장 용량 2TB (확장 시 비용 급증) 20TB (RAID 5) - 10배 용량
사진 로딩 속도 매우 빠름 (WebP 최적화) 빠름 (로컬), 보통 (외부 LTE 접속 시)
AI 얼굴 인식 최상 (마스크 쓴 얼굴도 인식) 상 (정면 위주 인식, 학습 시간 필요)

비용 측면에서만 본다면 초기 5년 구간에서는 GooglePhotos가 더 저렴해 보일 수 있습니다. 하지만 용량 대비 단가를 계산해보면 이야기가 달라집니다. 구글 포토에서 20TB를 사용하려면 월 수십만 원의 엔터프라이즈급 비용이 발생하지만, NAS는 초기 투자비용 외에 추가되는 비용이 미미합니다. 특히 데이터 주권 측면에서, 내 사진이 AI 학습 데이터로 쓰일지도 모른다는 불안감 없이 ExifTool로 검증된 원본 데이터를 내가 통제하는 하드웨어에 보관한다는 심리적 안정감은 돈으로 환산하기 어렵습니다.

Synology Photos 공식 스펙 확인하기

주의사항 및 잠재적 부작용

물론 시놀로지 포토가 만능은 아닙니다. 엔지니어로서 반드시 고려해야 할 엣지 케이스(Edge Cases)들이 존재합니다.

  1. 인덱싱 부하: 사진 5만 장을 한 번에 업로드하면, NAS의 CPU 사용률이 며칠간 99%를 찍습니다. 이 기간 동안 다른 서비스(Docker, Plex 등)가 느려질 수 있으므로, Synology Photos 설정에서 '변환 작업 일시 중지' 기능을 활용하거나 야간에만 돌리도록 스케줄링해야 합니다.
  2. HEIC/HEVC 코덱 문제: 시놀로지는 라이선스 문제로 인해 기본 상태에서는 일부 아이폰 촬영 영상(HEVC)의 썸네일을 생성하지 못합니다. 이를 해결하려면 시놀로지 패키지 센터에서 'Advanced Media Extensions'를 설치하고 시놀로지 계정으로 로그인하여 코덱을 활성화해야 합니다.
  3. 백업의 책임: 클라우드는 구글이 백업을 책임지지만, NAS는 내가 책임져야 합니다. RAID는 백업이 아닙니다. 반드시 Hyper Backup을 통해 외장 하드나 또 다른 클라우드(B2, S3 Glacier 등)로 2차 백업을 설정해야 랜섬웨어나 화재로부터 데이터를 보호할 수 있습니다.
Best Practice: 가장 이상적인 구성은 Synology Photos를 메인으로 사용하되, Google Photos의 '저용량(Storage Saver)' 무제한 옵션(과거 픽셀폰 사용자 등)이나 최소 요금제를 유지하며 2차 백업 용도로 병행하는 하이브리드 전략입니다.

결론

GooglePhotos에서 Synology Photos로의 이전은 단순한 데이터 이동이 아니라, 디지털 자산 관리의 패러다임을 '대여'에서 '소유'로 바꾸는 과정이었습니다. 초기 설정의 번거로움과 메타데이터 복구라는 기술적 장벽이 있었지만, Python 스크립트와 적절한 구성을 통해 이를 극복할 수 있었습니다. 이제 저는 매달 결제 문자를 걱정하지 않고도 수십 테라바이트의 추억을 안전하게, 그리고 원본 그대로 보관하고 있습니다. 만약 여러분도 늘어나는 구독료와 데이터 프라이버시 문제로 고민하고 있다면, 이번 주말 NAS 구축에 도전해 보시길 강력히 권장합니다. 기술적 자유는 그만한 가치가 충분히 있으니까요.

Post a Comment