diff --git a/journey/README.md b/journey/README.md index 6c4f3cc..875a645 100644 --- a/journey/README.md +++ b/journey/README.md @@ -49,12 +49,16 @@ - [goosefarminvesting 도메인 DNS전환후 HTTPS 인증서불일치 이슈](./troubleshooting/260311_goosefarminvesting_도메인_DNS전환후_https_인증서불일치_이슈.md) - [Gitea git credential helper 표준화](./troubleshooting/260309_gitea_git_credential_helper_표준화.md) - [23서버 워크스페이스 인프라 구조정리 이슈](./troubleshooting/260307_23서버_워크스페이스_인프라_구조정리_이슈.md) +- [내부 NAS -> 외부 NAS 경로 교정 및 Go 프로브 검증](./troubleshooting/260313_internal_nas_external_nas_route_fix_and_go_probe_verification.md) - [외부 NAS -> 내부 NAS 컴퍼니엑스 파일 동기화 아이디어](./ideas/260307_external_nas_companyx_sync_아이디어.md) - [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간 동기화 아이디어](./ideas/260312_external_nas_companyx_실시간동기화_아이디어.md) +- [내부 NAS 직접 Go 동기화 아이디어](./ideas/260313_internal_nas_direct_go_sync_아이디어.md) - [컴퍼니엑스 직원용 모바일 파일 포털 아이디어](./ideas/260307_companyx_mobile_file_portal_아이디어.md) - [23장애시 24서버 임시진입면승격 아이디어](./ideas/260309_23장애시_24서버_임시진입면승격_아이디어.md) - [외부 NAS -> 내부 NAS 컴퍼니엑스 동기화 리서치](./research/260307_external_nas_companyx_sync_research.md) - [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 리서치](./research/260312_external_nas_companyx_실시간동기화_리서치.md) +- [외부 NAS 동기화 Go/Python/DSM 도구화 리서치](./research/260313_external_nas_sync_go_python_dsm_tooling_리서치.md) +- [내부 NAS 직접 Go 동기화 가능성 리서치](./research/260313_internal_nas_direct_go_sync_feasibility_research.md) - [External NAS -> Internal NAS Sync Probe](./research/260307_external_nas_to_internal_nas_sync_probe.md) - [컴퍼니엑스 직원용 모바일 파일 포털 리서치](./research/260307_companyx_mobile_file_portal_research.md) - [51123 구 IP 하드코딩 실행 경로와 런타임 SSOT 불일치 리서치](./research/260309_51123_구IP하드코딩_실행경로_SSOT불일치_리서치.md) diff --git a/journey/ideas/260313_internal_nas_direct_go_sync_아이디어.md b/journey/ideas/260313_internal_nas_direct_go_sync_아이디어.md new file mode 100644 index 0000000..b7572c9 --- /dev/null +++ b/journey/ideas/260313_internal_nas_direct_go_sync_아이디어.md @@ -0,0 +1,156 @@ +--- +tags: [infra, nas, companyx, sync, go, ideas] +--- + +# 260313 내부 NAS 직접 Go 동기화 아이디어 + +## 상위 원칙 +- [Infra Project Identity](../../00_Philosophy/00_IDENTITY/Infra_Project_Identity.md) +- [Core Infrastructure Principles](../../00_Philosophy/01_PRINCIPLES/Core_Infrastructure_Principles.md) +- 공통 작성 원칙: [0_VALUE Writing Principles](https://github.com/happybell80/0_VALUE/blob/main/02_Governance/writing-principles.md) + +## 관련 문서 +- [내부 NAS -> 외부 NAS 경로 교정 및 Go 프로브 검증](../troubleshooting/260313_internal_nas_external_nas_route_fix_and_go_probe_verification.md) +- [외부 NAS 동기화 Go/Python/DSM 도구화 리서치](../research/260313_external_nas_sync_go_python_dsm_tooling_리서치.md) +- [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 리서치](../research/260312_external_nas_companyx_실시간동기화_리서치.md) + +## 문제 인식 + +- 현재 Company X 동기화의 실행 주체는 23 서버다. +- 하지만 외부 NAS 원격 조회, 내부 NAS 저장, 주기 실행 상태를 보면 실제 데이터 중심은 내부 NAS 쪽에 더 가깝다. +- 이번 검증으로 내부 NAS에서 외부 DSM 응답과 정적 Go 프로브 실행까지 확인됐으므로, 이제는 `23 서버를 거치지 않고 내부 NAS가 직접 동기화 주체가 되는 구조`를 검토할 수 있다. +- 지금 구조는 `외부 NAS 조회`와 `내부 NAS 저장` 사이에 23 서버가 중간 실행자로 끼어 있다. +- 이 중간 실행자는 현재 동작하지만, 장기적으로 보면 데이터가 머무는 곳과 실행 주체가 갈라져 있어 책임 경계가 한 번 더 꺾인다. + +## 현재상태 -> 기대상태 + +### 현재상태 + +- 실행 주체: + - 23 서버 `crontab` +- 실행 파일: + - `/home/admin/infra/scripts/bin/companyx_external_nas_sync.py` + - `/home/admin/infra/scripts/bin/companyx_external_nas_sync_hierarchical.py` + - 래퍼: + - `companyx_external_nas_sync_fullscan_cron.sh` + - `companyx_external_nas_sync_hierarchical_cron.sh` +- 스케줄: + - `*/30 * * * *` 계층형 동기화 + - `0 1 * * *` 하루 1회 전수조사 +- 락: + - `/home/admin/.locks/companyx_external_nas_sync.lock` +- 런로그: + - `/mnt/hdd/logs/companyx/companyx_external_nas_sync_hierarchical.log` + - `/mnt/hdd/logs/companyx/companyx_external_nas_sync_fullscan.log` +- 상태/요약: + - `/mnt/nas/workspace/.sync-logs/` + - `/mnt/nas/workspace/.sync-logs-hierarchical/` +- 저장 구조: + - 외부 NAS DSM API 조회 -> 23 서버 실행 -> 내부 NAS `/mnt/nas/workspace/6.Company X` 저장 +- 구조 해석: + - 외부 원본은 외부 NAS + - 실제 저장 기준은 내부 NAS + - 하지만 동기화 판단과 실행은 23 서버가 맡고 있다. + +### 기대상태 + +- 실행 주체: + - 내부 NAS 자체 스케줄러 또는 내부 NAS cron +- 실행 파일: + - 내부 NAS에 배포한 Go 단일 바이너리 +- 스케줄: + - 현재 23 서버와 같은 `30분 계층형 + 1일 1회 전수조사` + - 또는 같은 의미의 내부 NAS 스케줄 구성 +- 락: + - 내부 NAS 로컬 경로에서 단일 락 파일 관리 +- 런로그: + - 내부 NAS 로컬 로그 경로에 기록 +- 상태/요약: + - 내부 NAS 로컬 저장소 기준 경로에 기록 +- 저장 구조: + - 외부 NAS DSM API 조회 -> 내부 NAS 직접 실행 -> 내부 NAS 로컬 저장소 기록 +- 23 서버 역할: + - 문서화, 상태 확인, 원격 트리거, 결과 수집만 담당 +- 구조 해석: + - 외부 원본은 여전히 외부 NAS + - 저장 기준도 내부 NAS + - 실행 판단과 기록도 내부 NAS가 직접 맡는다. + +## 아이디어 + +- 동기화 프로그램을 Go 단일 바이너리로 만들고, 이를 내부 NAS에서 직접 실행한다. +- 외부 NAS는 DSM API로 읽고, 내부 NAS 로컬 저장소로 바로 기록한다. +- 23 서버는 동기화 본체가 아니라: + - 문서화 + - 결과 수집 + - 경보/상태 모니터링 + - 필요 시 원격 트리거 + 역할로 줄인다. + +핵심 한 줄은 아래와 같다. + +- `저장 기준이 내부 NAS라면, 동기화 실행 주체도 내부 NAS로 맞추는 편이 더 자연스럽다.` + +## 23 서버와 같은 설정으로 갈 수 있는가 + +결론부터 말하면 `운영 의미는 거의 같게`, `구체 경로는 일부 다르게` 가져갈 수 있다. + +### 그대로 가져갈 수 있는 것 + +- `30분 계층형 + 새벽 1시 전수조사`의 이중 스케줄 구조 +- `단일 락 파일로 중복 실행 방지` 원칙 +- `실행 로그`와 `상태/요약 JSON`을 분리하는 방식 +- `mtime + size` 기반 증분 판정 방향 +- `계층형 캐시 + 전수조사 보정`이라는 운영 개념 + +### 이름은 같게 가져갈 수 있지만 경로는 바뀌는 것 + +- 현재 23 서버 경로: + - `/home/admin/infra/scripts/bin/...` + - `/home/admin/.locks/...` + - `/mnt/hdd/logs/companyx/...` + - `/mnt/nas/workspace/.sync-logs...` +- 내부 NAS 직접 실행 시: + - NAS 로컬 실행 경로 + - NAS 로컬 락 경로 + - NAS 로컬 로그 경로 + - NAS 로컬 상태/요약 경로 + 로 재정의해야 한다. + +### 그대로 가져가면 안 되는 것 + +- `/mnt/nas`를 실행 경로로 쓰는 방식 + - 현재 CIFS 마운트 경로 직접 실행은 `Permission denied`였다. +- 23 서버의 `crontab` 자체 + - 내부 NAS에서는 DSM 작업 스케줄러 또는 NAS 측 cron에 맞춰 다시 정의해야 한다. +- 23 서버의 `workspace-config` 파일 경로 하드코딩 + - 내부 NAS는 별도 런타임/시크릿 주입 방식이 필요하다. + +즉 이 아이디어는 `23 서버 설정을 그대로 복사`하는 것이 아니라, `운영 패턴은 동일하게 유지하고 실행 위치와 경로만 내부 NAS 기준으로 치환`하는 방향이 맞다. + +## 기대 효과 + +- 외부 NAS 조회와 내부 NAS 저장 사이에 23 서버를 중간 실행자로 두지 않아 구조가 단순해진다. +- 저장 기준 장비와 실행 주체가 같아져서, 실패 위치와 운영 책임 경계가 더 직접적으로 보인다. +- Go 단일 바이너리 기준으로 내부 NAS에 배포·교체하기 쉬운 구조를 만들 수 있다. +- 23 서버 장애가 곧바로 동기화 주체 장애로 이어지지 않는 방향을 만들 수 있다. + +## 검증이 필요한 이유 + +- 현재는 `DSM 로그인 + 목록 조회`까지만 검증됐고, 실제 파일 다운로드/증분 판단/삭제 후보 기록 전체를 내부 NAS Go 바이너리로 옮긴 것은 아니다. +- 내부 NAS DSM 6.2.4 환경에서 재부팅 후 기본 게이트웨이 교정이 유지되는지 아직 별도 검증이 없다. +- 내부 NAS에서 장시간 동기화 프로세스를 어떤 방식으로 스케줄링하고, 로그를 어디에 남기고, 실패 시 누가 복구를 담당할지 운영안이 아직 열려 있다. + +## 이 문서에서 빼야 하는 내용 + +- 실행 순서, 배포 절차, 롤백 절차, 상태 파일 스키마 확정은 `plans`로 보낸다. +- 실제 구현 코드, 빌드 명령, 배포 로그, 검증 결과는 `worklog` 또는 `troubleshooting`으로 보낸다. +- 현재 Python 스크립트를 어떤 범위까지 유지할지, 병행 운영 기간을 둘지는 `plans`에서 정한다. + +## 현재 판단 + +- 이 아이디어는 `불가능한가` 단계는 이미 지났다. +- 현재 남은 질문은 `내부 NAS 직접 실행이 더 자연스러운 구조인가`인데, 지금까지의 검증으로는 `그렇다` 쪽 근거가 더 강하다. +- 따라서 이 문서의 핵심 제안은 아래 한 문장으로 닫을 수 있다. + +`Company X 외부 NAS 동기화는 장기적으로 23 서버 경유 구조보다 내부 NAS 직접 Go 실행 구조가 더 자연스럽다.` diff --git a/journey/research/260313_external_nas_sync_go_python_dsm_tooling_리서치.md b/journey/research/260313_external_nas_sync_go_python_dsm_tooling_리서치.md new file mode 100644 index 0000000..6ea9e94 --- /dev/null +++ b/journey/research/260313_external_nas_sync_go_python_dsm_tooling_리서치.md @@ -0,0 +1,189 @@ +--- +tags: [infra, nas, dsm, sync, go, python, research] +--- + +# 260313 외부 NAS 동기화 Go/Python/DSM 도구화 리서치 + +## 상위 원칙 +- [Infra Project Identity](../../00_Philosophy/00_IDENTITY/Infra_Project_Identity.md) +- [Core Infrastructure Principles](../../00_Philosophy/01_PRINCIPLES/Core_Infrastructure_Principles.md) +- [Operational Guardrails](../../00_Philosophy/02_GUARDRAILS/Operational_Guardrails.md) + +## 관련 문서 +- [외부 NAS -> 내부 NAS 컴퍼니엑스 동기화 리서치](./260307_external_nas_companyx_sync_research.md) +- [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 리서치](./260312_external_nas_companyx_실시간동기화_리서치.md) +- [외부 NAS -> 내부 NAS 컴퍼니엑스 동기화 운영계획](../plans/260311_external_nas_companyx_sync_운영계획.md) +- [Company X 외부 NAS 동기화 스크립트 구현 및 대표 검증](../worklog/260311_companyx_external_nas_sync_스크립트구현_및_대표검증.md) +- [Company X 30분주기 cron 적용 및 예측 검증](../worklog/260312_companyx_sync_30분주기_cron적용_및_예측검증.md) + +## 목적 + +- 사용자가 제공한 Gemini 대화 내용을 기준으로, `Go로 바꾸면 얼마나 빨라지는가`, `어디에 배포해야 하는가`, `DSM 로그인만 가능한 환경에서 어떤 방식이 맞는가`를 현재 검증 근거와 공식 문서 기준으로 다시 좁힙니다. +- 이 문서는 구현 계획을 확정하는 문서가 아니라, 어떤 주장이 근거가 있고 어떤 주장이 과장인지 분리하는 `research` 문서입니다. + +## 분류 판단 + +- 이 주제는 `도구 선택 + 배포 위치 + DSM 접근 방식 + NAS 동기화 병목`을 다루므로 `infra/DOCS/journey/research`가 맞습니다. +- 이유: + - 외부 NAS -> 내부 NAS 동기화는 이미 `infra`가 SSOT입니다. + - 아직 실행 방식을 확정하지 않았으므로 `plans`가 아닙니다. + - 현재 장애 복구 기록이 아니라 선택지 검증이므로 `troubleshooting`도 아닙니다. + +## 입력 질문 + +1. 에이전트가 쓰는 CLI 도구는 어떤 형식이 적합한가 +2. 대량 PostgreSQL 쿼리, 유사도 검색, 파일 메타데이터 스캔은 Go가 Python보다 무조건 빠른가 +3. 현재 주기 실행 중인 외부 NAS 동기화 검사를 Go로 옮기면 어느 정도 이점이 생기는가 +4. 배포 위치는 내부 NAS 직접 실행이 맞는가, 중간 서버가 맞는가 +5. SSH가 아니라 DSM 로그인만 가능한 외부 NAS에서도 브라우저 없이 운영 가능한가 + +## Facts + +### 1. 현재 운영 중인 외부 NAS 동기화 구조는 Python 스크립트 + DSM API pull 방식이다 + +- 기존 리서치와 worklog 기준, 현재 검증된 경로는 `외부 NAS DSM API 조회/다운로드 -> 내부 NAS 저장`이다. +- 외부 NAS에 대한 직접 SMB 마운트나 SSH 실행이 현재 운영 기준은 아니다. +- 내부 NAS 쪽만 우리가 수정 가능하고, 외부 NAS는 읽기 위주 접근 제약이 있다. + +근거: +- [외부 NAS -> 내부 NAS 컴퍼니엑스 동기화 리서치](./260307_external_nas_companyx_sync_research.md) +- [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 리서치](./260312_external_nas_companyx_실시간동기화_리서치.md) + +### 2. 현재 전체 병목은 Python 인터프리터보다 `원격 DSM API 재귀 조회 + 네트워크 전송` 쪽에 더 가깝다 + +- 2026-03-12 실측 기준 전체 루트 전수 조회는 약 `23분대`로 추정됐다. +- 같은 문서에서 루트 1회 조회는 약 `60ms`, 루트 + 1차 폴더 조회는 약 `0.98초`였다. +- 즉 현재 구조에서 가장 큰 비용은 `전체 파일 트리를 원격으로 다시 훑는 것`이지, 프로세스 시작 몇백 ms 자체라고 보기 어렵다. +- 따라서 `Go로 바꾸면 무조건 10배~100배` 같은 문장은 현재 검증 범위를 벗어난다. + +근거: +- [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 리서치](./260312_external_nas_companyx_실시간동기화_리서치.md) + +### 3. 변경 판정은 해시보다 `파일 크기 + 수정시각(stat)`이 훨씬 빠르다 + +- 2026-03-12 표본 측정 기준 같은 파일 집합에서 `sha256`은 `stat`보다 평균 `666.4배` 느렸다. +- 따라서 현재 운영 질문이 `변경 여부를 자주 판정해야 하는가`라면, 언어 선택 이전에 `판정 기준`을 먼저 최적화해야 한다. + +근거: +- [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 리서치](./260312_external_nas_companyx_실시간동기화_리서치.md) + +### 4. DSM 로그인만 가능한 환경에서도 브라우저 자동화가 필수는 아니다 + +- Synology 공식 문서는 `DSM Login Web API`와 `File Station API`를 별도 가이드로 제공한다. +- 즉 DSM 웹 화면을 사람이 브라우저로 여는 구조와, 프로그램이 HTTP 요청으로 로그인/파일 조회를 수행하는 구조는 분리 가능하다. +- 현재 우리 운영 경로도 브라우저 자동화가 아니라 DSM API 기반 검증 쪽에 가깝다. + +공식 출처: +- `DSM Login Web API Guide` + - https://global.download.synology.com/download/Document/Software/DeveloperGuide/Os/DSM/All/enu/DSM_Login_Web_API_Guide_enu.pdf +- `Synology File Station API Guide` + - https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/FileStation/All/enu/Synology_File_Station_API_Guide.pdf + +### 5. Python의 GIL은 `CPU-bound Python bytecode` 병렬성에 제약을 주지만, I/O 대기 중에는 다른 스레드가 진행될 수 있다 + +- Python 공식 문서는 GIL이 Python objects 접근 전 필요하다고 설명한다. +- 같은 문서에서 블로킹 I/O 동안에는 GIL이 해제된다고 설명한다. +- 따라서 `Python은 동시에 실행하는 척만 한다`는 표현은 과장이다. +- 지금 NAS 동기화처럼 원격 HTTP 요청과 파일 저장이 섞인 경로에서는, GIL만으로 전체 성능을 단정하면 안 된다. + +공식 출처: +- https://docs.python.org/3/c-api/threads.html + +### 6. Go 단일 바이너리 배포와 낮은 실행 오버헤드는 실제 장점이 맞다 + +- Go는 정적 컴파일 바이너리 배포가 쉬워서, Python 런타임/패키지 의존성을 줄이기 좋다. +- NAS나 경량 서버에 올릴 때 실행 환경 단순화와 시작 속도 이점이 있다. +- 다만 이것이 곧바로 `원격 DSM API 기반 전체 동기화가 수십 배 빨라진다`는 뜻은 아니다. + +### 7. 에이전트용 CLI 문서는 사람이 읽는 README보다 기계 친화적 스키마가 더 적합하다는 방향은 타당하다 + +- 사용자가 제시한 Gemini 답변 중 `단일 바이너리 + 기계가 읽는 스킬/스펙 파일` 구상은 에이전트용 도구 설계 방향으로 타당하다. +- 다만 현재 infra 운영에는 먼저 `도구 형식`보다 `어디서 실행하고 어떤 API를 쓰는지`가 선결 문제다. + +## Interpretation + +### 1. 이 문서는 `도구/언어 리서치`이면서 동시에 `인프라 리서치`다 + +- 일반적인 Go vs Python 비교 문서라면 `orchestration_tools` 성격도 있지만, +- 이번 케이스는 `외부 NAS`, `내부 NAS`, `DSM`, `주기 동기화`, `배포 위치`가 핵심이므로 `infra`가 1차 SSOT다. +- 따라서 `이것도 리서치인가`에 대한 답은 `그렇다`, 다만 `인프라 리서치`가 더 정확하다. + +### 2. 현재 기준으로는 `언어 전환`보다 `스캔 범위 축소`가 더 큰 효과를 낼 가능성이 높다 + +- 이미 측정된 값만 봐도 전체 전수 조회와 상위 폴더 메타 확인 사이 격차가 매우 크다. +- 따라서 현재 구조에서 먼저 풀어야 할 문제는: + - 전체 트리 재귀 조회를 얼마나 줄일지 + - 어떤 폴더만 더 내려갈지 + - 해시 대신 어떤 증분 기준을 쓸지 +이다. +- 이 최적화 없이 언어만 바꾸면 체감 개선은 제한적일 수 있다. + +### 3. Go 전환의 가장 확실한 이점은 `배포 단순화`, `낮은 메모리`, `병렬 구조 표현`, `장기 데몬화`다 + +- 현 구조를 Go로 옮기면 기대할 수 있는 현실적 이점은 아래에 가깝다. + - 내부 NAS나 51123에서 단일 바이너리 실행 + - 장기 실행 프로세스/데몬 유지 + - 동시 HTTP 요청과 파일 쓰기 구조를 더 단순하게 관리 + - 실행 환경 의존성 감소 +- 반대로 `무조건 10배`, `무조건 50배`, `0.5초 완주` 같은 수치는 현재 근거로는 말할 수 없다. + +### 4. PostgreSQL 대량 쿼리/유사도 검색도 `Go가 무조건 압승`이라고 쓰면 안 된다 + +- DB 왕복, 인덱스, SQL 계획, 네트워크 지연이 지배적인 경우 언어 차이는 제한적일 수 있다. +- Python도 `asyncpg`, NumPy, pgvector, DB-side similarity search를 쓰면 병목 위치가 달라진다. +- 따라서 이 부분은 `CPU-bound 순수 Python 루프`와 `DB-bound/extension-bound 경로`를 분리해서 봐야 한다. +- 지금 Gemini 답변처럼 `최소 10배 이상`으로 일반화하면 SSOT 문장으로는 부정확하다. + +### 5. 배포 위치는 현재 제약상 `내부 NAS 또는 우리가 제어하는 서버`가 맞다 + +- 외부 NAS는 수정 권한이 없고 읽기 중심이다. +- 현재 검증된 구조도 `외부는 원격 조회`, `내부는 저장/관리`다. +- 따라서 Go든 Python이든 실행 주체는 `내부 NAS` 또는 `51123 같은 제어 가능한 서버`가 자연스럽다. +- 다만 `내부 NAS 직접 실행`이 항상 정답이라고 단정하기보다, 아래 조건을 비교해야 한다. + - DSM API 세션 관리 위치 + - 내부 NAS에 배포/로그/재시작 관리가 쉬운가 + - 51123에서 이미 운영 중인 cron/log/문서 체계를 재사용하는 편이 나은가 + +### 6. `DSM 로그인만 가능 = 크롬 필요`는 틀린 해석이다 + +- 현재 확인 범위에서는 DSM 웹 UI가 아니라 Web API를 직접 호출하는 편이 더 보수적이고 검증 가능하다. +- 즉 로그인은 `브라우저 시뮬레이션`보다 `HTTP client + 세션 관리` 문제로 보는 것이 맞다. +- 브라우저 자동화는 API가 막히거나 특정 UI 흐름 검증이 필요할 때의 예외 경로에 가깝다. + +### 7. 에이전트용 도구 형식은 `단일 바이너리 + JSON 출력 + 명시적 오류코드`가 유리하다 + +- 에이전트가 쓴다면 사람이 읽기 좋은 문장보다 아래가 중요하다. + - 입력 플래그 + - 출력 JSON 스키마 + - 종료 코드 + - 재시도 가능 오류와 불가 오류 구분 +- 따라서 향후 Go 전환을 한다면, 문서 형식은 `README 장문`보다 `기계가 읽기 쉬운 계약 + 짧은 운영 설명` 조합이 맞다. + +## Unresolved + +1. 현재 Python 구현에서 실제 CPU 시간과 I/O 시간을 분리 계측한 프로파일이 없다. +2. `51123 실행`과 `내부 NAS 직접 실행` 중 어느 쪽이 운영상 더 나은지 아직 비교 실측이 없다. +3. DSM API 병렬 호출을 어느 수준까지 올려도 외부 NAS가 안정적으로 버티는지 미측정이다. +4. Go 프로토타입을 같은 데이터셋에 대해 돌린 A/B 실측이 없다. +5. PostgreSQL 대량 쿼리/유사도 검색 항목은 현재 Company X NAS 동기화 경로와 다른 병목이므로 별도 리서치로 분리하는 편이 맞다. + +## 결론 + +- 이번 Gemini 대화는 `에이전트용 CLI 형식`, `DSM API 직접 사용`, `Go 단일 바이너리 배포` 같은 방향성에서는 참고 가치가 있다. +- 하지만 `Go가 Python보다 무조건 10~100배 빠르다`는 식의 수치는 현재 infra 문서 기준으로 확정할 수 없다. +- 지금 우선순위는 `언어 교체` 단독이 아니라 `계층형 메타 탐색`, `증분 기준 최적화`, `배포 위치 비교`, `A/B 프로토타입 실측`이다. + +## 다음 단계 제안 + +1. 현재 Python 스크립트에 `I/O 대기`, `DSM API 응답`, `로컬 파일 쓰기`, `메타 비교` 시간을 분리 계측한다. +2. 같은 입력 집합으로 최소 기능 Go 프로토타입을 만들어 A/B 측정한다. +3. 결과가 유의미하면 그때 `plans` 문서에서 `51123 실행` vs `내부 NAS 직접 실행`을 고정한다. + +## 출처 + +- Synology DSM Login Web API Guide + - https://global.download.synology.com/download/Document/Software/DeveloperGuide/Os/DSM/All/enu/DSM_Login_Web_API_Guide_enu.pdf +- Synology File Station API Guide + - https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/FileStation/All/enu/Synology_File_Station_API_Guide.pdf +- Python C API: Thread State and the Global Interpreter Lock + - https://docs.python.org/3/c-api/threads.html diff --git a/journey/research/260313_internal_nas_direct_go_sync_feasibility_research.md b/journey/research/260313_internal_nas_direct_go_sync_feasibility_research.md new file mode 100644 index 0000000..bc6851d --- /dev/null +++ b/journey/research/260313_internal_nas_direct_go_sync_feasibility_research.md @@ -0,0 +1,203 @@ +--- +tags: [infra, nas, companyx, sync, go, research] +--- + +# 260313 내부 NAS 직접 Go 동기화 가능성 리서치 + +## 상위 원칙 +- [Infra Project Identity](../../00_Philosophy/00_IDENTITY/Infra_Project_Identity.md) +- [Core Infrastructure Principles](../../00_Philosophy/01_PRINCIPLES/Core_Infrastructure_Principles.md) +- [Operational Guardrails](../../00_Philosophy/02_GUARDRAILS/Operational_Guardrails.md) +- 공통 작성 원칙: [0_VALUE Writing Principles](https://github.com/happybell80/0_VALUE/blob/main/02_Governance/writing-principles.md) + +## 관련 문서 +- [외부 NAS -> 내부 NAS 컴퍼니엑스 동기화 리서치](./260307_external_nas_companyx_sync_research.md) +- [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 리서치](./260312_external_nas_companyx_실시간동기화_리서치.md) +- [외부 NAS 동기화 Go/Python/DSM 도구화 리서치](./260313_external_nas_sync_go_python_dsm_tooling_리서치.md) +- [내부 NAS -> 외부 NAS 경로 교정 및 Go 프로브 검증](../troubleshooting/260313_internal_nas_external_nas_route_fix_and_go_probe_verification.md) +- [내부 NAS 직접 Go 동기화 아이디어](../ideas/260313_internal_nas_direct_go_sync_아이디어.md) + +## 목적 + +- 지금 풀려는 문제, 즉 `외부 NAS 조회 -> 내부 NAS 직접 실행/저장` 구조가 실제 운영 후보가 되는지 확인한다. +- 이 문서는 아이디어를 확정하는 문서가 아니라, 현재 검증된 사실 기준으로 어디까지 말할 수 있는지 좁히는 `research` 문서다. +- 특히 `내부 NAS가 직접 동기화 실행 주체가 되는 구조`가 infra SSOT의 역할 분리 원칙과 충돌하는지 함께 본다. + +## 리서치 질문 + +1. 현재 23 서버가 맡고 있는 Company X 동기화 역할을 내부 NAS가 기술적으로 대신할 수 있는가 +2. 내부 NAS 직접 실행은 infra SSOT의 `23은 진입과 제어, NAS는 보존과 복구` 원칙과 충돌하는가 +3. 23 서버 운영 패턴을 내부 NAS에서도 같은 의미로 재현할 수 있는가 +4. 지금 시점에서 이미 닫힌 질문과 아직 남아 있는 질문은 무엇인가 + +## Facts + +### 1. 현재 운영 구조는 `23 서버 실행 -> 내부 NAS 저장`이다 + +- 23 서버 `crontab`에는 아래 두 엔트리가 등록돼 있다. + - `*/30 * * * * /home/admin/infra/scripts/bin/companyx_external_nas_sync_hierarchical_cron.sh` + - `0 1 * * * /home/admin/infra/scripts/bin/companyx_external_nas_sync_fullscan_cron.sh` +- 실제 실행 스크립트는 23 서버 `infra/scripts/bin/` 아래 Python 본체와 shell 래퍼로 구성돼 있다. +- 상태/요약은 내부 NAS 마운트 경로인 `/mnt/nas/workspace/.sync-logs*`에 남고, 런로그는 23 서버 `/mnt/hdd/logs/companyx/`에 남는다. + +### 2. 현재 동기화 원본 접근 방식은 DSM API pull이다 + +- 외부 NAS에 대한 직접 SMB 접근은 현재 운영 경로가 아니다. +- 현재 검증된 접근 경로는 `Synology DSM Login Web API + File Station API`다. +- 이 경로는 브라우저 자동화가 아니라 HTTP 요청 기반 로그인/목록 조회/다운로드 방식이다. + +공식 출처: +- https://global.download.synology.com/download/Document/Software/DeveloperGuide/Os/DSM/All/enu/DSM_Login_Web_API_Guide_enu.pdf +- https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/FileStation/All/enu/Synology_File_Station_API_Guide.pdf + +### 3. 내부 NAS는 외부 NAS DSM에 직접 접속할 수 있게 됐다 + +- 최초 검증에서는 내부 NAS `192.168.0.101`에서 외부 NAS `sigongipc.synology.me:5001`로 접속 시 `no route to host`가 발생했다. +- 확인 결과 내부 NAS는 기본 경로를 여전히 `192.168.219.1 dev eth0`로 잡고 있었고, `/etc/iproute2/config/default-gateway`도 `DEVICE="tun0"`로 남아 있었다. +- 이 값을 `eth1` 기준으로 교정한 뒤, 내부 NAS에서 외부 DSM `HTTP/2 200` 응답과 Go 정적 프로브 실행까지 성공했다. + +근거: +- [내부 NAS -> 외부 NAS 경로 교정 및 Go 프로브 검증](../troubleshooting/260313_internal_nas_external_nas_route_fix_and_go_probe_verification.md) + +### 4. 내부 NAS에서 Go 정적 바이너리 자체는 실행 가능하다 + +- 동적 빌드 바이너리는 `GLIBC_2.32`, `GLIBC_2.34` 미충족으로 실패했다. +- `CGO_ENABLED=0` 정적 빌드 바이너리는 내부 NAS 홈 디렉터리에서 정상 실행됐다. +- 실행 결과: + - DSM 로그인 성공 + - `/6.Company X` 루트 목록 조회 성공 + - 대표 사진 폴더 목록 조회 성공 + +즉 내부 NAS는 `Go 실행 불가 장비`가 아니라, `정적 바이너리 형태가 필요한 장비`로 보는 것이 맞다. + +### 5. CIFS 마운트 경로는 실행 경로로 부적합하다 + +- 23 서버의 `/mnt/nas`는 내부 NAS `//192.168.0.101/home`을 CIFS로 마운트한 경로다. +- 해당 마운트는 `file_mode=0664`로 잡혀 있어, 여기에 복사한 바이너리는 `chmod +x` 이후에도 실행이 되지 않았다. +- 실제 결과는 `Permission denied`였다. + +즉 `내부 NAS 직접 실행`을 하더라도 실행 파일은 NAS 로컬 경로에 둬야 하며, 23 서버의 `/mnt/nas` 경로를 실행 기준으로 보면 안 된다. + +### 6. 23 서버 운영 패턴의 핵심 요소는 경로보다 구조에 있다 + +현재 23 서버 운영의 핵심 요소: + +- 이중 스케줄 + - 30분 계층형 동기화 + - 새벽 1시 전수조사 +- 단일 락 파일로 중복 실행 방지 +- 런로그와 상태/요약 JSON 분리 +- `mtime + size` 기반 증분 판단 +- 계층형 캐시 + 일일 전수보정 + +이 요소들은 23 서버에만 고유한 것이 아니라, 내부 NAS 직접 실행으로도 개념상 옮길 수 있다. + +### 7. 다만 `23의 역할`과 `NAS의 역할`은 그대로 두면 긴장이 생긴다 + +- infra SSOT는 `23은 진입과 제어, 24는 실행, NAS는 보존과 복구`를 기본 역할로 둔다. +- 내부 NAS가 동기화 프로세스를 직접 돌리면, NAS가 일부 `실행` 역할을 맡게 된다. +- 따라서 이 구조는 "NAS는 절대 실행하면 안 된다"는 금지선과는 다르지만, 최소한 `예외적 실행 역할`을 문서화하지 않으면 역할 경계가 흐려질 수 있다. + +### 8. 23 서버 1분 벤치마크 기준, 외부 NAS `검토` 성격 작업에서는 Go가 Python보다 소폭 더 효율적이었다 + +- 비교 대상: + - Python: `companyx_external_nas_probe_benchmark.py` + - Go: `companyx_external_nas_probe_benchmark_go` +- 공통 작업: + - DSM 로그인 1회 + - 루트 `/6.Company X` 목록 조회 1회 + - 대표 사진 폴더 목록 조회 1회 + - 이 3단계를 1사이클로 보고 23 서버에서 약 `60초` 동안 반복 +- 실행일: + - `2026-03-13` +- 공통 조건: + - 동일 서버 + - 동일 외부 NAS + - 동일 DSM API + - 동일 경로 + - 다운로드 없이 `검토/목록 조회`만 수행 + +실측값: + +| 항목 | Python | Go | 비교 | +|---|---:|---:|---:| +| 총 실행 시간 | `60.506초` | `60.745초` | 유사 | +| 총 사이클 수 | `66` | `70` | Go `+6.1%` | +| 분당 사이클 수 | `65.45` | `69.14` | Go `+5.6%` | +| 평균 로그인 | `799.109ms` | `786.544ms` | Go `1.6%` 빠름 | +| 평균 루트 목록 조회 | `58.155ms` | `38.795ms` | Go `33.3%` 빠름 | +| 평균 대표 폴더 목록 조회 | `58.809ms` | `42.409ms` | Go `27.9%` 빠름 | + +해석에 필요한 사실: + +- 이 벤치마크는 `전체 동기화`가 아니라 `외부 NAS 상태 검토`에 가까운 작업이다. +- 로그인 시간은 두 언어 차이가 작았고, 목록 조회는 Go 쪽이 더 빨랐다. +- 결과적으로 1분 동안 처리한 총 사이클 수는 Go가 Python보다 약 `5~6%` 높았다. +- 따라서 현재 23 서버 기준에서는 `검토/메타 조회 루프`에서 Go가 더 효율적이라고 말할 수는 있지만, `압도적 차이`라고 말할 수준은 아니다. + +## Interpretation + +### 1. 기술적으로는 이미 운영 후보다 + +- 내부 NAS -> 외부 NAS 네트워크 경로가 열렸고, +- 내부 NAS에서 Go 정적 바이너리 실행도 검증됐으며, +- 외부 DSM 로그인/목록 조회가 끝까지 성공했기 때문에, + +현재 사실 범위에서는 `외부 NAS 조회 -> 내부 NAS 직접 실행/저장` 구조를 단순 아이디어가 아니라 `기술적으로 가능한 운영 후보`로 볼 수 있다. + +### 2. 이 전환의 본질은 성능보다 책임 경계 재배치다 + +- 기존 리서치 기준으로 현재 병목은 Python 언어 자체보다 `전체 DSM 트리 재조회`에 더 가깝다. +- 따라서 내부 NAS 직접 Go 실행의 1차 가치는 "무조건 더 빠르다"가 아니라: + - 저장 기준과 실행 주체를 맞추고 + - 중간 실행자 23 서버를 줄이며 + - 동기화 실패 위치를 더 직접적으로 만드는 것 + 에 있다. +- 이번 1분 벤치마크도 같은 결론을 지지한다. + - Go가 더 효율적이긴 했지만, 개선 폭은 `검토 루프 기준 소폭 우위`에 가까웠다. + - 따라서 이 전환을 `속도만으로 정당화`하는 것은 여전히 과장이다. + - 다만 `짧은 주기 메타 조회`를 자주 수행해야 한다면 Go 쪽이 누적 효율 이점을 줄 가능성은 있다. + +### 3. SSOT 원칙과의 충돌은 `절대 충돌`이 아니라 `예외 역할 문서화 필요`로 해석하는 편이 맞다 + +- SSOT 원칙만 기계적으로 읽으면 NAS는 보존/복구 역할이므로 실행 주체가 되면 안 되는 것처럼 보일 수 있다. +- 하지만 실제 운영 요구를 보면, 여기서 NAS는 "일반 애플리케이션 실행 노드"가 아니라 "자기 저장소를 외부 원본과 맞추는 최소 동기화 실행자" 역할을 맡는 것이다. +- 이 정도 범위의 실행은 `보존과 복구를 위한 보조 실행`으로 해석할 수 있다. +- 다만 이 해석은 자동으로 주어지는 것이 아니라, 이후 구조 문서나 계획 문서에서 예외 역할을 분명히 적어야 한다. + +### 4. `23 서버와 같은 설정`은 `같은 경로 복제`가 아니라 `같은 운영 패턴 복제`로 보는 것이 정확하다 + +- 23 서버와 완전히 같은 경로를 내부 NAS에 복제할 수는 없다. +- 하지만 아래는 거의 같은 의미로 옮길 수 있다. + - 30분 + 1일 1회 이중 스케줄 + - 락 파일 + - 로그/상태/요약 분리 + - 계층형 캐시 + - `mtime + size` 증분 기준 + +따라서 질문은 "경로를 그대로 복사할 수 있느냐"보다 "운영 패턴을 내부 NAS 기준으로 치환할 수 있느냐"로 바꾸는 편이 맞다. + +### 5. 지금 시점에서 가장 정확한 결론은 아래 한 문장이다 + +`Company X 외부 NAS 동기화는 23 서버 경유 구조보다 내부 NAS 직접 Go 실행 구조가 더 자연스러운 운영 후보이며, 현재 근거로도 기술적 가능성은 이미 확인됐다.` + +## Unresolved + +1. 내부 NAS에서 실제 전체 다운로드/증분/삭제 후보 기록까지 포함한 Go 구현은 아직 없다. +2. 내부 NAS 로컬 로그 경로, 상태 경로, 락 경로를 어디로 둘지 아직 확정되지 않았다. +3. 내부 NAS 재부팅 후 `eth1` 기본 게이트웨이 교정이 지속되는지 아직 장기 검증이 없다. +4. DSM 작업 스케줄러와 NAS 측 cron 중 어떤 실행 방식이 더 적합한지 아직 미확정이다. +5. 23 서버가 완전히 빠질지, 문서화/원격 트리거/관찰 경로로 일부 남을지 운영 경계가 아직 열려 있다. +6. 1분 벤치마크는 `로그인 + 목록 조회`만 비교했으므로, 실제 다운로드/증분/삭제 후보 기록까지 포함한 end-to-end 차이는 아직 미측정이다. + +## 결론 + +- `외부 NAS 조회 -> 내부 NAS 직접 실행/저장`은 현재 기준으로 기술적 가능성이 검증된 구조다. +- 이 구조의 핵심 가치는 속도 과장보다 `책임 경계 단순화`와 `저장 기준-실행 주체 일치`에 있다. +- 다만 SSOT 원칙상 NAS의 기본 역할을 넘는 부분이 있으므로, 이후 문서에서는 `보존을 위한 최소 실행 예외`를 분명히 적어야 한다. + +## 다음 단계 제안 + +1. 내부 NAS 직접 Go 동기화의 경로/로그/락/스케줄러를 고정하는 계획 문서 작성 +2. 정적 Go 바이너리로 `계층형 동기화` 최소 구현 프로토타입 작성 +3. 재부팅 후 기본 게이트웨이와 외부 DSM 접속이 유지되는지 검증 diff --git a/journey/troubleshooting/260313_internal_nas_external_nas_route_fix_and_go_probe_verification.md b/journey/troubleshooting/260313_internal_nas_external_nas_route_fix_and_go_probe_verification.md new file mode 100644 index 0000000..5953094 --- /dev/null +++ b/journey/troubleshooting/260313_internal_nas_external_nas_route_fix_and_go_probe_verification.md @@ -0,0 +1,129 @@ +--- +tags: [infra, nas, companyx, sync, go, troubleshooting] +--- + +# 260313 내부 NAS -> 외부 NAS 경로 교정 및 Go 프로브 검증 + +**상태**: 해결 및 종료 + +## 상위 원칙 +- [Infra Project Identity](../../00_Philosophy/00_IDENTITY/Infra_Project_Identity.md) +- [Core Infrastructure Principles](../../00_Philosophy/01_PRINCIPLES/Core_Infrastructure_Principles.md) +- [Operational Guardrails](../../00_Philosophy/02_GUARDRAILS/Operational_Guardrails.md) +- 공통 작성 원칙: [0_VALUE Writing Principles](https://github.com/happybell80/0_VALUE/blob/main/02_Governance/writing-principles.md) + +## 관련 문서 +- [외부 NAS 동기화 Go/Python/DSM 도구화 리서치](../research/260313_external_nas_sync_go_python_dsm_tooling_리서치.md) +- [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 리서치](../research/260312_external_nas_companyx_실시간동기화_리서치.md) +- [외부 NAS -> 내부 NAS 컴퍼니엑스 동기화 운영계획](../plans/260311_external_nas_companyx_sync_운영계획.md) +- [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간 동기화 아이디어](../ideas/260312_external_nas_companyx_실시간동기화_아이디어.md) + +## 문제 정의 + +- 내부 NAS `192.168.0.101`에서 외부 NAS `sigongipc.synology.me:5001`로 직접 접속하는 Go 프로브를 실행하자 `no route to host`가 발생했다. +- 같은 외부 DSM 경로는 23 서버 `192.168.0.100`에서는 정상 응답했기 때문에, 문제는 외부 NAS 자체가 아니라 내부 NAS의 네트워크 경로 쪽에 있었다. +- 이 상태에서는 `23 서버를 거치지 않고 내부 NAS가 직접 외부 NAS 동기화 주체가 되는 구조`를 검증할 수 없다. + +## 재현 조건 + +- 23 서버: `192.168.0.100` +- 내부 NAS: + - `eth0 = 192.168.219.51` + - `eth1 = 192.168.0.101` +- 외부 NAS 호스트: `sigongipc.synology.me` +- 테스트 바이너리: + - 동적 빌드: `companyx_external_nas_sync_probe_go` + - 정적 빌드: `companyx_external_nas_sync_probe_go_static` + +## 확인된 사실 + +### 1. 23 서버에서는 외부 DSM 접속이 정상이다 + +- 23 서버에서 `getent hosts sigongipc.synology.me`는 `112.218.113.4`를 반환했다. +- 같은 서버에서 `curl -Iks https://sigongipc.synology.me:5001`은 `HTTP/2 200`을 반환했다. +- 즉 외부 NAS DNS와 외부 DSM 서비스 자체는 살아 있었다. + +### 2. 내부 NAS의 현재 기본 경로는 내부망 기준과 어긋나 있었다 + +- 내부 NAS 라우팅 테이블 확인 결과 기본 경로는 `default via 192.168.219.1 dev eth0 src 192.168.219.51`였다. +- 같은 시각 `eth1`은 `192.168.0.101`로 살아 있었고, DHCP 정보에는 `GATEWAY=192.168.0.1`이 남아 있었다. +- `ip route get 112.218.113.4`도 실제로 `via 192.168.219.1 dev eth0`를 가리켰다. +- 즉 외부 NAS 트래픽이 현재 운영망이 아닌 구 경로 쪽으로 빠지고 있었다. + +### 3. 내부 NAS 기본 게이트웨이 장치 설정에도 구 흔적이 남아 있었다 + +- `/etc/iproute2/config/default-gateway` 값은 `DEVICE="tun0"`였다. +- 이는 현재 실제 외부 경로로 써야 할 `eth1`과 맞지 않았다. +- 내부 NAS는 DSM 6.2.4였고, `synonet`은 없었지만 `/usr/syno/bin/synogetkeyvalue`, `/usr/syno/bin/synosetkeyvalue`는 존재했다. + +### 4. Go 바이너리 실행성은 네 가지로 나뉘었다 + +1. 23 서버 로컬 실행 +- 정상 실행 +- DSM 로그인 및 두 폴더 목록 조회 성공 + +2. `/mnt/nas` CIFS 마운트 경로 직접 실행 +- 실패 +- `Permission denied` +- 마운트 옵션이 `file_mode=0664`라 실행 비트가 보존되지 않았다. + +3. 내부 NAS 홈 디렉터리에서 동적 빌드 바이너리 실행 +- 실패 +- `GLIBC_2.32`, `GLIBC_2.34` 미충족 + +4. 내부 NAS 홈 디렉터리에서 정적 빌드 바이너리 실행 +- 바이너리 자체는 실행됨 +- 최초 실패 원인은 라이브러리가 아니라 외부 NAS 라우팅 문제였다. + +## 실제 조치 + +### 1. Go 프로브 준비 + +- 23 서버 `admin` 범위에 Go `1.26.1`을 설치했다. +- 외부 DSM 로그인 및 File Station 목록 조회만 수행하는 최소 Go 프로브를 작성했다. +- 내부 NAS 실행 호환성을 위해 `CGO_ENABLED=0` 정적 빌드도 함께 만들었다. + +### 2. 내부 NAS 라이브 라우팅 교정 + +- 우선 테스트용으로 `112.218.113.4`에 대한 호스트 라우트를 `192.168.0.1 dev eth1`로 교정했다. +- 이후 DNS까지 같이 맞추기 위해 기본 경로 자체를 `default via 192.168.0.1 dev eth1`로 교체했다. + +### 3. 기본 게이트웨이 설정 파일 교정 + +- 백업: + - `/etc/iproute2/config/default-gateway.bak_20260313` +- 교정: + - `/etc/iproute2/config/default-gateway` + - `DEVICE="eth1"` +- 적용 후 현재 라우트도 `112.218.113.4 via 192.168.0.1 dev eth1 src 192.168.0.101`으로 확인했다. + +## 검증 결과 + +### 1. 내부 NAS에서 외부 DSM HTTPS 직접 응답 확인 + +- `curl -Iks --connect-timeout 5 https://sigongipc.synology.me:5001` +- 결과: `HTTP/2 200` + +### 2. 내부 NAS에서 정적 Go 프로브 실행 성공 + +내부 NAS 실행 결과: + +- 로그인: + - `{"probe":"login","duration_ms":981,"host":"sigongipc.synology.me","binary":"companyx_external_nas_sync_probe_go_static"}` +- 루트 목록: + - `{"path":"/6.Company X","duration_ms":30,"total":16,"entries_returned":16,"body_bytes":3401}` +- 대표 사진 폴더 목록: + - `{"path":"/6.Company X/7. 사진/220308_X코스_5기 발표 사진","duration_ms":38,"total":20,"entries_returned":20,"body_bytes":5559}` + +즉 `내부 NAS -> 외부 NAS DSM 로그인 -> File Station 목록 조회` 경로가 실제로 닫혔다. + +## 결론 + +- 이번 이슈의 직접 원인은 내부 NAS가 외부 트래픽을 아직 `192.168.219.1 dev eth0` 구 경로로 보내고 있던 점이었다. +- 기본 게이트웨이 장치를 `eth1`로 교정하고 라이브 라우트도 맞춘 뒤, 내부 NAS에서 외부 DSM 응답과 정적 Go 프로브 실행까지 확인했다. +- 따라서 `23 서버를 거치지 않고 내부 NAS가 직접 Go 기반 동기화 주체가 되는 구조`는 네트워크 경로 기준으로는 현재 운영 후보로 볼 수 있다. + +## 전후 관계 문서 + +- 이전 해석: [260313_external_nas_sync_go_python_dsm_tooling_리서치.md](../research/260313_external_nas_sync_go_python_dsm_tooling_리서치.md) +- 다음 아이디어: [260313_internal_nas_direct_go_sync_아이디어.md](../ideas/260313_internal_nas_direct_go_sync_아이디어.md)