Finalize Company X hierarchical sync docs

This commit is contained in:
happybell80 2026-03-12 22:47:38 +09:00
parent 484b1a0226
commit 0fb0e597fb
3 changed files with 82 additions and 46 deletions

View File

@ -4,7 +4,7 @@ tags: [infra, nas, companyx, sync, realtime, plans]
# 260312 외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 계획
**상태**: 완료 (2026-03-12 cron 적용, 중복 실행 방지 검증, 1분 제한 실측 기반 주기 30분으로 보정)
**상태**: 완료 (2026-03-12 30분 계층형 cron, 01:00 전수조사 cron, 수동 검증 완료)
## 상위 원칙
- [Infra Project Identity](../../00_Philosophy/00_IDENTITY/Infra_Project_Identity.md)
@ -28,8 +28,8 @@ tags: [infra, nas, companyx, sync, realtime, plans]
## 구조 결정 고정
- 허용 지연은 `30분 이내`로 고정한다.
- 기본 실행 방식은 `cron 기반 30분 주기 증분 pull`로 고정한다.
- 전체 루트 `/6.Company X`는 기존 `List` 기반 재귀 scan/pull을 유지한다.
- 기본 실행 방식은 `cron 기반 30분 주기 계층형 탐색 + 증분 pull`로 고정한다.
- `30분 루프`는 전체 파일 전수조사가 아니라 `/6.Company X`와 그 아래 1차 폴더들을 non-recursive로 조회해 `2차 폴더까지` 먼저 확인한다.
- Search API는 전체 루트 대체재로 쓰지 않는다.
- Search API는 변화가 잦고 범위가 좁은 일부 상위 폴더에서만 보조 후보로 제한 검토한다.
- 증분 기준은 기존과 동일하게 `수정시각 + 파일 크기`를 유지한다.
@ -37,54 +37,55 @@ tags: [infra, nas, companyx, sync, realtime, plans]
- 내부 NAS DSM webhook/API 제어를 기본 전제로 두지 않는다.
- 외부 삭제는 내부 NAS에 자동 전파하지 않고, 삭제 후보 로그만 남긴다.
- 같은 주기의 중복 실행은 허용하지 않는다.
- 하루 1회는 전체 루트 기준 검증 스캔을 수행해 Search API 누락 가능성과 누적 불일치를 점검한다.
- 하루 1회는 파일 기준 전체 루트 전수조사를 수행해 누락과 정합성을 보정한다.
- SHA256은 표본 무결성 검증과 의심 파일 확인에만 제한적으로 사용한다.
## 실행 순서
### 1. 30분 주기 실행 엔트리를 고정한다
- `companyx_external_nas_sync.py`를 30분마다 실행하는 cron 엔트리를 기준안으로 둔다.
- `companyx_external_nas_sync.py` 또는 후속 계층형 래퍼를 30분마다 실행하는 cron 엔트리를 기준안으로 둔다.
- 실행 겹침 방지를 위해 lock 파일 또는 `flock` 기반 단일 실행 제어를 같이 둔다.
- 로그는 기존 `.sync-logs` 경로를 재사용한다.
### 2. 전체 루트 30분 주기 증분 실행을 먼저 기준안으로 채택한다
### 2. 30분 루프는 2차 폴더까지 먼저 확인한다
- 최초 기준안은 `/6.Company X -> /mnt/nas/workspace/6.Company X` 전체 루트 재귀 조회다.
- 이유는 현재 직접 검증된 방식 중 전체 범위를 안정적으로 설명 가능한 경로가 이것뿐이기 때문이다.
- `/6.Company X` 루트와 그 아래 1차 폴더들을 non-recursive `List`로 먼저 확인한다.
- 이 단계의 목적은 전체 파일을 훑는 것이 아니라 `어느 2차 폴더가 바뀌었는지`를 빠르게 잡는 것이다.
- 2026-03-12 실측 기준 루트 1회 조회 평균은 `60.14ms`, 2차 폴더까지 확인하는 평균은 `983.861ms`였다.
- Search API를 먼저 중심 구조로 승격하지 않는다.
- 내부 NAS나 외부 NAS의 파일 변경 webhook이 있다는 가정을 실행 기준에 넣지 않는다.
### 3. Search API는 일부 상위 폴더 후보에서만 별도 검증한다
### 3. 바뀐 폴더만 3차 이하로 하강한다
- `/6.Company X/7. 사진`처럼 범위가 제한된 상위 폴더를 후보로 둔다.
- 작은 범위에서 `pattern`, `mtime_from`, `mtime_to` 기반 검색이 계속 일관되게 맞는지 확인한다.
- 이 검증이 반복 통과되기 전까지 Search API는 보조 최적화 후보로만 취급한다.
- 30분 루프에서 `mtime`이 바뀐 2차 폴더만 3차, 4차, 파일 레벨까지 내려간다.
- 하강한 경로에서는 파일 단위 `수정시각 + 파일 크기`로 실제 다운로드 여부를 판단한다.
- 바뀌지 않은 2차 폴더는 이번 30분 루프에서 더 내려가지 않는다.
### 4. 하루 1회 전체 검증 스캔을 추가한
### 4. 하루 1회 파일 전수조사로 최종 정합성을 맞춘
- 10분 주기 실행과 별도로 하루 1회 전체 루트 기준 재귀 스캔을 수행한다.
- 목적은 Search API 보조 최적화가 일부 폴더에서 쓰이더라도 누락 파일, 이동 파일, 시간 오차를 다시 맞추기 위함이다.
- 30분 루프와 별도로 하루 1회 전체 루트 파일 전수조사를 수행한다.
- 목적은 `폴더 mtime`만으로는 놓칠 수 있는 `기존 파일 내용 수정`, 누락 파일, 시간 오차를 다시 맞추기 위함이다.
- 이 검증 스캔도 같은 상태 파일과 요약 파일 체계를 사용한다.
### 5. 운영 임계치를 수치로 확인한다
- 30분 주기 실행의 평균 소요 시간, 최장 소요 시간, 겹침 발생 여부를 기록한다.
- `1회 실행 시간이 30분을 반복 초과`하면 주기를 더 늘리거나 상위 폴더 분할로 전환한다.
- `Search API 후보 폴더`는 동일 시점 `List` 결과와 표본 비교해 누락이 없을 때만 다음 단계로 올린다.
- `2차 폴더까지 확인` 단계는 평균 `1초 내외`를 유지하는지 본다.
- 하강 대상 폴더 수가 급격히 늘어 30분 루프가 길어지면 상위 폴더 단위 분리 또는 주기 조정을 검토한다.
- `해시 재계산`은 2026-03-12 실측에서 같은 표본 기준 `stat 0.927ms` 대비 `sha256 617.713ms`, 약 `666.4배` 느렸으므로 운영 기본 루프에 넣지 않는다.
- 전체 루트 `1분 제한` 실측에서는 `directories_seen=436`, `files_seen=2276`이었고, 기존 완주 총량 대비 단순 비례 예상 시간은 약 `23.4분`이었다.
- 따라서 현재 기본안은 `10분`이 아니라 `30분`이 안전한 보수 주기다.
- 따라서 현재 기본안은 `30분 루프는 계층형 탐색`, `하루 1회만 파일 전수조사`다.
## 체크리스트
- 허용 지연 `30분`이 문서와 실행 설정에서 일치한다.
- cron 기준 실행이 중복 없이 유지된다.
- 전체 루트 기준 30분 주기 실행에서 상태 파일과 요약 파일이 남는다.
- 30분 루프가 `2차 폴더까지 확인 -> 바뀐 폴더만 하강`으로 동작한다.
- 1회 실행 시간이 주기를 반복 초과하지 않는다.
- Search API는 전체 루트 대체재가 아니라 일부 상위 폴더 후보로만 사용된다.
- 하루 1회 파일 전수조사가 별도로 남는다.
- 해시는 기본 증분 판정이 아니라 표본 검증에만 남는다.
- 하루 1회 전체 검증 스캔이 별도로 남는다.
- 삭제 전파 없이 삭제 후보 로그만 남는다.
## 검증 기준
@ -92,20 +93,28 @@ tags: [infra, nas, companyx, sync, realtime, plans]
- 30분 주기 실행 3회 이상에서 `failed=0` 또는 원인 설명 가능한 실패 로그가 남는다.
- 각 실행 요약에서 `started_at`, `finished_at`, `downloaded`, `skipped`, `failed`를 확인할 수 있다.
- 같은 시간대 중복 프로세스가 생기지 않는다.
- 하루 1회 전체 검증 스캔 결과와 30분 주기 실행 결과 사이에 설명되지 않는 누락이 없다.
- Search API 후보 폴더는 같은 표본에 대해 `List`와 결과가 일치한다.
- 하루 1회 파일 전수조사 결과와 30분 루프 결과 사이에 설명되지 않는 누락이 없다.
- 30분 루프 로그에서 어떤 2차 폴더가 하강 대상으로 선택됐는지 확인할 수 있다.
## 완료 조건
- `실시간` 대신 `30분 이내 반영`이라는 운영 표현이 문서와 실행 결과에서 일치한다.
- 30분 주기 증분 pull이 재현 가능하고, 중복 실행 없이 안정적으로 돈다.
- Search API는 과장 없이 `일부 상위 폴더 보조 최적화 후보`로만 정리된다.
- 30분 주기 계층형 탐색이 재현 가능하고, 중복 실행 없이 안정적으로 돈다.
- 하루 1회 파일 전수조사와 역할이 겹치지 않는다.
- 이 주제는 더 이상 막연한 실시간 아이디어가 아니라, 측정값에 근거한 운영 기준으로 전환된다.
## 현재 추천 결론
- 현재 근거 기준 1순위는 `cron 30분 주기 + 전체 루트 증분 pull + 하루 1회 전체 검증 스캔`이다.
- Search API는 작은 폴더에서 빠르게 동작했지만 루트 전체에서는 신뢰 가능한 결과를 주지 못했으므로, 일부 상위 폴더에서만 제한 검토한다.
- 현재 근거 기준 1순위는 `cron 30분 주기 2차 폴더 메타 확인 + 바뀐 폴더만 하강 동기화 + 하루 1회 파일 전수조사`다.
- Search API는 작은 폴더에서 빠르게 동작했지만 루트 전체에서는 신뢰 가능한 결과를 주지 못했으므로 기본 경로로 채택하지 않는다.
- 해시는 직접 실측에서 `수정시각 + 파일 크기`보다 현저히 느렸으므로, 운영 루프가 아니라 표본 검증에만 남긴다.
- 내부 NAS 관리자 계정으로 DSM API 로그인 자체는 가능했지만, 현재 확인된 API 목록에는 알림/webhook 제어 항목이 없었으므로 webhook 기반 설계는 채택하지 않는다.
- 전체 루트 1분 제한 실측 기반 예상 시간이 약 `23.4분`이므로, 현재 추천 점수는 `92%`다.
- 루트 1회 조회는 약 `60ms`, 2차 폴더까지 확인은 약 `1초`, 전체 파일 전수조사는 약 `23분대`로 추정되므로, 현재 추천 점수는 `95%`다.
## 2026-03-12 적용 상태
- 사용자 crontab에 `*/30 * * * * /home/admin/infra/scripts/bin/companyx_external_nas_sync_hierarchical_cron.sh`를 적용했다.
- 사용자 crontab에 `0 1 * * * /home/admin/infra/scripts/bin/companyx_external_nas_sync_fullscan_cron.sh`를 적용했다.
- 계층형 스크립트 수동 검증 1회차는 `root_scan_calls=15`, `first_level_dirs=14`, `second_level_dirs=110`, `primed_cache=true`, `downloaded=38`, `failed=0`이었다.
- 계층형 스크립트 수동 검증 2회차는 `candidate_dirs=0`, `downloaded=0`, `skipped=38`, `failed=0`이었다.
- 전수조사 래퍼는 대표 폴더 기준 `downloaded=20`, `failed=0`, `files_seen=20`으로 정상 동작을 확인했다.

View File

@ -158,6 +158,21 @@ tags: [infra, nas, companyx, sync, realtime, research]
- `termination_signal=SIGTERM`
- 예상 전체 시간: `약 23.2~23.4분`
### 10. 1차 폴더와 2차 폴더 메타만 훑는 비용은 매우 낮다
- 2026-03-12 23:00 KST 기준 `/6.Company X` 루트 1회 조회만 `5회` 반복 측정한 결과 평균은 `60.14ms`였다.
- 같은 시각 `/6.Company X` 루트와 그 아래 1차 폴더 `14개`를 각각 non-recursive로 조회해 `2차 폴더까지` 확인한 결과 평균은 `983.861ms`였다.
- 즉 `전체 파일 전수조회 약 23분대`와 비교하면, `1차 폴더 메타 확인``2차 폴더 메타 확인`은 운영 루프에 넣기 충분히 가볍다.
- 이 경로는 전체 파일을 매번 훑는 방식이 아니라, 상위 폴더 메타를 이용해 `어느 영역을 더 내려가야 할지` 후보를 좁히는 데 적합하다.
2026-03-12 23:00 KST 실측값:
- 루트 1회 조회 `5회` 평균: `60.14ms`
- 루트 엔트리: `16개`
- 1차 폴더 수: `14개`
- 루트 + 1차 폴더 `14개` 조회, 총 `15회 API 호출` 평균: `983.861ms`
- 2차 레벨 확인 결과: `2차 폴더 110개`, `2차 파일 36개`
- 응답 총량: `39,499B`
## Interpretation
### 1. 이 아이디어의 핵심 `why`는 구조 성립이 아니라 최신성 목표 정의다
@ -165,7 +180,7 @@ tags: [infra, nas, companyx, sync, realtime, research]
- 기본 동기화 구조는 이미 검증됐기 때문에, 실시간 아이디어의 초점은 `무엇을 만들 수 있나`가 아니라 `왜 더 빠른 반영이 필요한가`다.
- 즉 다음 단계에서 먼저 닫아야 할 질문은 도구 선택보다 `허용 가능한 반영 지연`이다.
### 2. 현재 근거로 가장 보수적인 해석은 `짧은 주기 pull`이 1차 후보라는 것이다
### 2. 현재 근거로 가장 보수적인 해석은 `계층형 탐색 + 짧은 주기 pull`이 1차 후보라는 것이다
- 현재 검증된 외부 접근이 DSM API pull 방식이고, 이벤트 수신 경로는 확인되지 않았다.
- 따라서 지금 근거만 놓고 보면 `외부 변화 감지 -> 즉시 push`보다 `짧은 주기 재조회 -> 증분 동기화`가 더 직접적인 운영 후보다.
@ -173,10 +188,10 @@ tags: [infra, nas, companyx, sync, realtime, research]
- 다만 2026-03-12 실측 기준 전체 트리 `dry-run``3분 45초`를 넘어도 끝나지 않았으므로, 현재 구조 그대로는 `1분 미만` 같은 촘촘한 polling은 비현실적일 가능성이 높다.
- 반대로 단일 목록 조회가 `0.06~0.08초`, 20MB PDF 1건 다운로드가 `0.73초`였으므로, 범위를 더 좁히거나 상위 폴더를 분할하면 `짧은 주기 후보`를 다시 따져볼 여지는 있다.
- Search API는 작은 폴더에서는 매우 빠르지만, 루트 전체 재귀 검색에서는 실제 존재 파일도 놓쳤으므로 현재 단계에서 전체 스캔 대체재로 가정하면 안 된다.
- 따라서 지금 가장 보수적인 운영 해석은 `전체 루트는 기존 pull/scan`, `변화가 잦은 일부 상위 폴더만 Search API 추가 검토`다.
- 따라서 지금 가장 보수적인 운영 해석은 `30분마다 2차 폴더까지 메타 확인 -> 바뀐 폴더만 3차 이하로 하강 -> 파일까지 내려가 증분 동기화`다.
- 같은 맥락에서 증분 기준도 해시보다 `수정시각 + 파일 크기`가 훨씬 빠르므로, 짧은 주기 운영에서는 해시를 기본 판정 기준으로 올리지 않는 것이 맞다.
- 내부 NAS도 현재 확인 기준으로는 `파일 변경 webhook`을 API로 바로 붙일 근거가 없으므로, 실시간 문제를 webhook 전제로 풀면 안 된다.
- 그리고 현재 1분 제한 실측 기준 전체 루트 전수 조회는 약 `23분대`로 추정되므로, 전체 루트 기준 `10분 주기`는 안전한 기본안이 아니다.
- 그리고 현재 1차 폴더 확인은 약 `60ms`, 2차 폴더 확인은 약 `1초`, 전체 파일 전수조회는 약 `23분대`로 추정되므로, `빠른 계층형 탐색 + 일일 전수보정`이 비용 대비 가장 현실적이다.
### 3. 실시간성 수준을 정하지 않으면 `plans`가 과도하게 넓어진다
@ -202,10 +217,10 @@ tags: [infra, nas, companyx, sync, realtime, research]
- 삭제, 이동, 부분 업로드, 파일 교체가 짧은 주기 동기화에서 어떻게 보일지 미확정
5. 실행 방식
- cron 기반 짧은 주기 실행, 상주 프로세스, 외부 이벤트 트리거 중 무엇이 맞는지 미확정
- 2차 폴더 메타 확인 후 바뀐 폴더만 하강하는 계층형 탐색을 어떤 상태 파일 구조로 남길지 미확정
## 현재 결론
- `외부 NAS -> 내부 NAS` 동기화 자체는 이미 운영 가능 수준으로 검증됐으므로, 실시간 아이디어의 쟁점은 `가능성`이 아니라 `필요한 최신성 수준`이다.
- 현재 직접 검증된 경로는 DSM API 기반 pull이므로, 지금 사실 범위에서 말할 수 있는 가장 강한 결론은 `짧은 주기 증분 동기화 후보를 검토할 수 있다`까지다.
- 이벤트 기반 실시간 동기화는 아직 직접 검증되지 않았고, 전체 루트 전수 조회도 현재 예측상 `23분대`이므로, 다음 단계는 `10분`이 아니라 `30분급 보수 주기`를 기본안으로 두`plans` 문서가 맞다.
- 이벤트 기반 실시간 동기화는 아직 직접 검증되지 않았고, 전체 루트 전수 조회도 현재 예측상 `23분대`이므로, 다음 단계는 `30분마다 2차 폴더 메타 확인 -> 바뀐 폴더만 하강 동기화 -> 하루 1회 파일 전수조회`를 고정하`plans` 문서가 맞다.

View File

@ -2,7 +2,7 @@
tags: [infra, nas, companyx, sync, realtime, worklog]
---
# 260312 Company X 30분주기 cron 적용 및 예측 검증
# 260312 Company X 계층형 30분주기 cron 및 01시 전수조사 적용
## 관련 문서
- [외부 NAS -> 내부 NAS 컴퍼니엑스 실시간동기화 리서치](../research/260312_external_nas_companyx_실시간동기화_리서치.md)
@ -11,27 +11,39 @@ tags: [infra, nas, companyx, sync, realtime, worklog]
## 작업
- `/home/admin/infra/scripts/bin/companyx_external_nas_sync_cron.sh`를 추가해 `flock` 기반 중복 실행 방지와 실행 로그 기록을 묶은 cron 래퍼를 만들었다.
- 사용자 crontab에 `*/30 * * * * /home/admin/infra/scripts/bin/companyx_external_nas_sync_cron.sh` 엔트리를 적용했다.
- 대표 폴더 기준 수동 실행 검증과, 전체 루트 `60초` 제한 실행으로 현재 전수 조회 속도를 다시 측정했다.
- `/home/admin/infra/scripts/bin/companyx_external_nas_sync_hierarchical.py`를 추가해 `/6.Company X`와 그 아래 1차 폴더를 먼저 훑고, 바뀐 2차 폴더만 더 내려가는 계층형 동기화 스크립트를 만들었다.
- `/home/admin/infra/scripts/bin/companyx_external_nas_sync_hierarchical_cron.sh`, `/home/admin/infra/scripts/bin/companyx_external_nas_sync_fullscan_cron.sh`를 추가해 `flock` 기반 중복 실행 방지와 실행 로그 기록을 분리했다.
- 사용자 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`를 적용했다.
- 루트 1회 조회, 2차 폴더까지 조회, 전체 루트 `60초` 제한 실행으로 전수 조회와 계층형 탐색 비용을 다시 측정했다.
## 검증
- 대표 폴더 수동 실행:
- 계층형 스크립트 1회차:
- 대상: `/6.Company X`
- 결과: `root_scan_calls=15`, `first_level_dirs=14`, `second_level_dirs=110`, `downloaded=38`, `failed=0`, `primed_cache=true`
- 소요 시간: 약 `12초`
- 산출물:
- `/mnt/nas/workspace/.sync-logs-hier-test/companyx_hierarchical_cache.json`
- `/mnt/nas/workspace/.sync-logs-hier-test/companyx_sync_summary_20260312_224449.json`
- 계층형 스크립트 2회차:
- 결과: `candidate_dirs=0`, `downloaded=0`, `skipped=38`, `failed=0`
- 소요 시간: 약 `2초`
- 1차/2차 메타 조회 실측:
- 루트 1회 조회 평균: `60.14ms`
- 루트 + 1차 폴더 `14개` 조회 평균: `983.861ms`
- 전수조사 래퍼 대표 경로 검증:
- 대상: `/6.Company X/7. 사진/220308_X코스_5기 발표 사진`
- 결과: `downloaded=20`, `failed=0`, `files_seen=20`
- 산출물:
- `/mnt/hdd/logs/companyx/companyx_external_nas_sync_cron.log`
- `/mnt/nas/workspace/.sync-logs-cron-test/companyx_sync_state.json`
- `/mnt/nas/workspace/.sync-logs-cron-test/companyx_sync_summary_20260312_221114.json`
- 중복 실행 방지:
- 전체 루트 실행 중 같은 래퍼를 다시 호출했을 때 로그에 `skip: previous sync still running`이 남았다.
- `/mnt/hdd/logs/companyx/companyx_external_nas_sync_fullscan.log`
- `/mnt/nas/workspace/.sync-logs-fullscan-test/companyx_sync_summary_20260312_224526.json`
- 전체 루트 `60초` 제한 실측:
- 시작: `2026-03-12 22:15:41 KST`
- 종료: `2026-03-12 22:16:41 KST`
- 결과: `directories_seen=436`, `files_seen=2276`, `skipped=2275`, `failed=1`, `termination_signal=SIGTERM`
- 기존 완주 총량(`directories_seen=10549`, `files_seen=52833`) 대비 단순 비례 예상 시간: 약 `23.4분`
- 기존 완주 총량 대비 단순 비례 예상 시간: 약 `23.4분`
- 실제 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`
## 한 줄 결론
- Company X 전체 루트 기준 기본 주기는 `10분`보다 `30분`이 안전하다는 근거가 확보됐고, cron 래퍼와 중복 실행 방지는 실제로 적용 및 검증됐다.
- Company X 실시간 아이디어는 `30분 계층형 탐색 + 01:00 파일 전수조사` 구조로 실제 적용 기준까지 닫혔고, 계층형 루프와 전수조사 래퍼 모두 수동 검증을 통과했다.