- TECH_STACK.md: Complete technology stack overview - HOMEBREW_SETUP.md: macOS development environment setup guide - SYNOLOGY_SETUP.md: General Synology NAS installation guide - DS1525_OPTIMIZED_SETUP.md: DS1525+ 32GB RAM optimized configuration Features: ✅ Multi-platform deployment options (Mac/NAS) ✅ Performance optimization for different hardware specs ✅ Docker-based containerization ✅ Monitoring and logging setup ✅ Automated backup and maintenance scripts ✅ SSD optimization for longevity
16 KiB
16 KiB
🏠 DS1525+ 최적화 설치 가이드
📋 하드웨어 사양
대상 기기: Synology DS1525+
- CPU: AMD Ryzen R1600 (4코어 2.6GHz)
- 메모리: 32GB RAM (대폭 업그레이드됨!)
- 저장장치: 시놀로지 정품 2.5" SSD 480GB
- 네트워크: 기가비트 이더넷 x4
- DSM: 7.0 이상
성능 특징
- 고성능 CPU: AMD Ryzen으로 NLP 처리 우수
- 대용량 메모리: 32GB로 모든 서비스 여유롭게 운영
- SSD 스토리지: 빠른 I/O, 낮은 지연시간
- 멀티 기가비트: 네트워크 병목 없음
🚀 DS1525+ 32GB 최적화 구성
메모리 할당 계획 (32GB 활용)
총 메모리: 32GB
├── DSM 시스템: 2GB
├── PostgreSQL: 4GB (대폭 증량)
├── Elasticsearch: 8GB (고성능 검색)
├── Redis: 2GB (대용량 캐시)
├── 애플리케이션: 4GB (멀티 워커)
├── NLP 처리: 4GB (동시 처리)
├── 시스템 캐시: 6GB (파일 시스템 캐시)
└── 여유 공간: 2GB
Docker Compose 최적화 (DS1525+ 전용)
# /volume1/docker/industrial-info/docker-compose.yml
version: '3.8'
networks:
industrial-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
services:
postgres:
image: postgres:15-alpine
container_name: industrial-postgres
environment:
POSTGRES_DB: industrial_info
POSTGRES_USER: industrial_user
POSTGRES_PASSWORD: secure_password_here
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C"
volumes:
- /volume1/docker/industrial-info/data/postgres:/var/lib/postgresql/data
- /volume1/docker/industrial-info/config/postgresql.conf:/etc/postgresql/postgresql.conf
ports:
- "5432:5432"
networks:
- industrial-net
restart: unless-stopped
deploy:
resources:
limits:
memory: 4G # 32GB 활용
cpus: '2.0' # Ryzen 4코어 활용
reservations:
memory: 2G
cpus: '1.0'
command: postgres -c config_file=/etc/postgresql/postgresql.conf
elasticsearch:
image: elasticsearch:8.11.0
container_name: industrial-elasticsearch
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms4g -Xmx8g" # 대폭 증량!
- xpack.security.enabled=false
- xpack.security.enrollment.enabled=false
- bootstrap.memory_lock=true
volumes:
- /volume1/docker/industrial-info/data/elasticsearch:/usr/share/elasticsearch/data
- /volume1/docker/industrial-info/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
ports:
- "9200:9200"
- "9300:9300"
networks:
- industrial-net
restart: unless-stopped
deploy:
resources:
limits:
memory: 10G # 8GB JVM + 2GB 시스템
cpus: '2.0'
reservations:
memory: 6G
cpus: '1.0'
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
redis:
image: redis:7-alpine
container_name: industrial-redis
command: redis-server /etc/redis/redis.conf
volumes:
- /volume1/docker/industrial-info/data/redis:/data
- /volume1/docker/industrial-info/config/redis.conf:/etc/redis/redis.conf
ports:
- "6379:6379"
networks:
- industrial-net
restart: unless-stopped
deploy:
resources:
limits:
memory: 2G # 대용량 캐시
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
app:
build: ./app
container_name: industrial-app
environment:
- DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info
- REDIS_URL=redis://redis:6379/0
- ELASTICSEARCH_URL=http://elasticsearch:9200
- PYTHONPATH=/app
- WORKERS=4 # 멀티 워커
volumes:
- /volume1/docker/industrial-info/app:/app
- /volume1/docker/industrial-info/data/logs:/app/logs
ports:
- "8000:8000"
networks:
- industrial-net
depends_on:
- postgres
- redis
- elasticsearch
restart: unless-stopped
deploy:
resources:
limits:
memory: 4G # 멀티 워커 지원
cpus: '2.0'
reservations:
memory: 2G
cpus: '1.0'
# NLP 전용 워커 (고성능)
nlp-worker:
build: ./app
container_name: industrial-nlp-worker
command: celery -A main.celery worker --loglevel=info --concurrency=4 -Q nlp
environment:
- DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info
- REDIS_URL=redis://redis:6379/0
- ELASTICSEARCH_URL=http://elasticsearch:9200
- SPACY_MODEL_PATH=/app/models
volumes:
- /volume1/docker/industrial-info/app:/app
- /volume1/docker/industrial-info/data/logs:/app/logs
- /volume1/docker/industrial-info/data/models:/app/models
networks:
- industrial-net
depends_on:
- postgres
- redis
- elasticsearch
restart: unless-stopped
deploy:
resources:
limits:
memory: 4G # NLP 모델 로딩용
cpus: '2.0'
reservations:
memory: 2G
cpus: '1.0'
# 데이터 수집 워커
collector-worker:
build: ./app
container_name: industrial-collector
command: celery -A main.celery worker --loglevel=info --concurrency=2 -Q collector
environment:
- DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info
- REDIS_URL=redis://redis:6379/0
- ELASTICSEARCH_URL=http://elasticsearch:9200
volumes:
- /volume1/docker/industrial-info/app:/app
- /volume1/docker/industrial-info/data/logs:/app/logs
networks:
- industrial-net
depends_on:
- postgres
- redis
- elasticsearch
restart: unless-stopped
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
# 스케줄러
scheduler:
build: ./app
container_name: industrial-scheduler
command: celery -A main.celery beat --loglevel=info
environment:
- DATABASE_URL=postgresql://industrial_user:secure_password_here@postgres:5432/industrial_info
- REDIS_URL=redis://redis:6379/0
- ELASTICSEARCH_URL=http://elasticsearch:9200
volumes:
- /volume1/docker/industrial-info/app:/app
- /volume1/docker/industrial-info/data/logs:/app/logs
networks:
- industrial-net
depends_on:
- postgres
- redis
- elasticsearch
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
# 모니터링 (Prometheus)
prometheus:
image: prom/prometheus:latest
container_name: industrial-prometheus
volumes:
- /volume1/docker/industrial-info/config/prometheus.yml:/etc/prometheus/prometheus.yml
- /volume1/docker/industrial-info/data/prometheus:/prometheus
ports:
- "9090:9090"
networks:
- industrial-net
restart: unless-stopped
deploy:
resources:
limits:
memory: 1G
cpus: '0.5'
# 모니터링 대시보드 (Grafana)
grafana:
image: grafana/grafana:latest
container_name: industrial-grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
volumes:
- /volume1/docker/industrial-info/data/grafana:/var/lib/grafana
ports:
- "3000:3000"
networks:
- industrial-net
restart: unless-stopped
deploy:
resources:
limits:
memory: 1G
cpus: '0.5'
nginx:
image: nginx:alpine
container_name: industrial-nginx
volumes:
- /volume1/docker/industrial-info/config/nginx.conf:/etc/nginx/nginx.conf
- /volume1/docker/industrial-info/data/logs:/var/log/nginx
ports:
- "80:80"
- "443:443"
networks:
- industrial-net
depends_on:
- app
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
⚙️ 고성능 설정 파일들
PostgreSQL 최적화 (32GB 활용)
# /volume1/docker/industrial-info/config/postgresql.conf
# DS1525+ 32GB RAM 최적화 설정
# 메모리 설정
shared_buffers = 2GB # 32GB의 6.25%
effective_cache_size = 16GB # 32GB의 50%
maintenance_work_mem = 512MB # 대용량 인덱스 작업
work_mem = 64MB # 정렬/해시 작업용
# 체크포인트 설정
checkpoint_completion_target = 0.9
checkpoint_timeout = 15min
max_wal_size = 4GB
min_wal_size = 1GB
# 연결 설정
max_connections = 200
shared_preload_libraries = 'pg_stat_statements'
# 로그 설정
log_destination = 'stderr'
logging_collector = on
log_directory = '/var/lib/postgresql/data/log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB
log_min_duration_statement = 1000 # 1초 이상 쿼리 로깅
# 성능 최적화
random_page_cost = 1.1 # SSD 최적화
effective_io_concurrency = 200 # SSD 동시 I/O
max_worker_processes = 4 # Ryzen 4코어 활용
max_parallel_workers = 4
max_parallel_workers_per_gather = 2
# 자동 VACUUM 최적화
autovacuum = on
autovacuum_max_workers = 2
autovacuum_naptime = 30s
Elasticsearch 최적화 (8GB JVM)
# /volume1/docker/industrial-info/config/elasticsearch.yml
cluster.name: "industrial-cluster"
node.name: "industrial-node-1"
path.data: /usr/share/elasticsearch/data
path.logs: /usr/share/elasticsearch/logs
# 네트워크 설정
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
# 메모리 설정 (32GB 환경)
bootstrap.memory_lock: true
indices.memory.index_buffer_size: 2GB
indices.fielddata.cache.size: 2GB
# 성능 최적화
thread_pool.write.queue_size: 1000
thread_pool.search.queue_size: 1000
indices.queries.cache.size: 1GB
# SSD 최적화
index.store.type: niofs
index.merge.scheduler.max_thread_count: 2
# 한국어 분석 설정
index.analysis.analyzer.nori.type: custom
index.analysis.analyzer.nori.tokenizer: nori_tokenizer
index.analysis.analyzer.nori.filter: [nori_part_of_speech, lowercase]
Redis 최적화 (2GB)
# /volume1/docker/industrial-info/config/redis.conf
# DS1525+ 32GB RAM 최적화
# 메모리 설정
maxmemory 2gb
maxmemory-policy allkeys-lru
# 영속성 설정 (SSD 최적화)
save 900 1
save 300 10
save 60 10000
# AOF 설정
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 네트워크 최적화
tcp-keepalive 300
timeout 0
# 성능 최적화
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
# 로그 설정
loglevel notice
logfile ""
📊 성능 벤치마크 (DS1525+ 32GB)
예상 성능 지표
동시 사용자: 100명 (여유롭게)
검색 응답시간: 50-100ms (매우 빠름)
RSS 수집: 500개 피드/분 (대용량 처리)
NLP 처리: 10,000건/시간 (고속 처리)
데이터베이스: 1,000 TPS (높은 처리량)
리소스 사용률 목표
CPU 사용률: 평균 30-40% (여유)
메모리 사용률: 평균 70-80% (효율적)
디스크 I/O: SSD 성능 최대 활용
네트워크: 기가비트 대역폭 활용
💾 SSD 480GB 최적화
디스크 공간 할당
총 용량: 480GB
├── DSM 시스템: 50GB
├── Docker 이미지: 20GB
├── PostgreSQL 데이터: 100GB
├── Elasticsearch 인덱스: 150GB
├── 애플리케이션 로그: 30GB
├── 백업 공간: 80GB
└── 여유 공간: 50GB (10% 여유)
SSD 수명 연장 설정
# SSD 최적화 스크립트
#!/bin/bash
# TRIM 활성화
echo 'deadline' > /sys/block/sda/queue/scheduler
# 로그 로테이션 최적화
cat > /etc/logrotate.d/docker << EOF
/volume1/docker/industrial-info/data/logs/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 644 root root
}
EOF
# 스왑 사용 최소화
echo 'vm.swappiness=1' >> /etc/sysctl.conf
echo 'vm.vfs_cache_pressure=50' >> /etc/sysctl.conf
자동 정리 스크립트
# /volume1/docker/industrial-info/scripts/cleanup.sh
#!/bin/bash
# Docker 이미지 정리 (주간)
docker system prune -f
# 로그 파일 압축 (일일)
find /volume1/docker/industrial-info/data/logs -name "*.log" -mtime +1 -exec gzip {} \;
# 오래된 백업 삭제 (월간)
find /volume1/docker/industrial-info/backup -name "*.gz" -mtime +30 -delete
# Elasticsearch 인덱스 최적화 (주간)
curl -X POST "localhost:9200/_forcemerge?max_num_segments=1"
echo "Cleanup completed: $(date)"
🔧 모니터링 및 알림
Prometheus 설정
# /volume1/docker/industrial-info/config/prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'industrial-app'
static_configs:
- targets: ['app:8000']
- job_name: 'postgres'
static_configs:
- targets: ['postgres:5432']
- job_name: 'elasticsearch'
static_configs:
- targets: ['elasticsearch:9200']
- job_name: 'redis'
static_configs:
- targets: ['redis:6379']
- job_name: 'node-exporter'
static_configs:
- targets: ['localhost:9100']
알림 규칙
# 메모리 사용률 80% 초과 시 알림
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High memory usage detected"
# 디스크 사용률 85% 초과 시 알림
- alert: HighDiskUsage
expr: (1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100 > 85
for: 5m
labels:
severity: critical
annotations:
summary: "High disk usage detected"
🚀 배포 및 실행
원클릭 설치 스크립트
#!/bin/bash
# /volume1/docker/industrial-info/install.sh
echo "🚀 DS1525+ 산업정보시스템 설치 시작..."
# 디렉토리 생성
mkdir -p /volume1/docker/industrial-info/{app,data/{postgres,elasticsearch,redis,logs,grafana,prometheus},config,backup,scripts}
# 권한 설정
chown -R 1000:1000 /volume1/docker/industrial-info
# Docker 네트워크 생성
docker network create industrial-net 2>/dev/null || true
# 환경 변수 파일 생성
cat > /volume1/docker/industrial-info/.env << EOF
POSTGRES_PASSWORD=$(openssl rand -base64 32)
SECRET_KEY=$(openssl rand -base64 64)
ELASTICSEARCH_PASSWORD=$(openssl rand -base64 32)
EOF
# 컨테이너 시작
cd /volume1/docker/industrial-info
docker-compose up --build -d
echo "✅ 설치 완료! 접속 URL:"
echo " 애플리케이션: http://$(hostname -I | awk '{print $1}'):80"
echo " 모니터링: http://$(hostname -I | awk '{print $1}'):3000"
echo " Elasticsearch: http://$(hostname -I | awk '{print $1}'):9200"
📈 성능 비교 요약
DS1525+ vs 일반 NAS vs Mac
| 항목 | DS1525+ 32GB | 일반 NAS 8GB | Mac Mini M2 |
|---|---|---|---|
| 동시 사용자 | 100명 | 20명 | 50명 |
| 검색 속도 | 50ms | 200ms | 30ms |
| NLP 처리 | 10K건/시간 | 1K건/시간 | 15K건/시간 |
| 전력 소모 | 60W | 40W | 150W |
| 24시간 운영 | ✅ 최적 | ✅ 가능 | ❌ 비효율 |
| 확장성 | ✅ 우수 | ⚠️ 제한적 | ❌ 제한적 |
| 비용 효율 | ✅ 최고 | ✅ 좋음 | ❌ 높음 |
결론: DS1525+ 32GB는 이 프로젝트에 과분할 정도로 좋은 성능을 제공합니다! 🚀
480GB SSD도 충분하고, 32GB RAM으로 모든 서비스를 여유롭게 돌릴 수 있어요. 완벽한 선택입니다! 👍