본 문서에서는 Python 기반 뉴스 추천 시스템 개발 프로젝트의 주요 기술 개요, 개발 환경 설정 방법, 그리고 데이터베이스 설계의 기본 원칙을 다룹니다.
프로젝트 개요
본 프로젝트는 뉴스 추천 서비스를 개발하는 과정을 통해 다음과 같은 핵심 기술 및 개념을 학습하는 것을 목표로 합니다.
- 데이터베이스 설계 및 ORM (SQLAlchemy) 활용
- 분산 환경에서의 고유 ID 생성 (예: 스노우플레이크 알고리즘)
- Redis를 이용한 데이터 캐싱 및 관리
- Gitflow 워크플로우를 통한 효율적인 버전 관리
- JWT (JSON Web Token) 기반 인증 시스템 구현
- 객체 스토리지 (예: Qiniu Cloud Storage) 활용
- 다중 계층 캐싱 전략 및 캐시 문제 해결 방안
- RPC (Remote Procedure Call) 통신 메커니즘 (예: gRPC)
- Elasticsearch를 이용한 전문 검색 시스템 구축
- Socket.IO를 활용한 실시간 통신
- APScheduler를 이용한 정기 작업 스케줄링
- Supervisor를 이용한 프로세스 관리
- 단위 테스트의 중요성 및 작성 방법
학습 목표
- 뉴스 추천 서비스 사례를 통해 특정 비즈니스 로직 구현보다는 다양한 기술 스택 및 솔루션 이해에 중점.
- 발생 가능한 기술적 문제에 대한 효과적인 해결 방안 습득.
- 이전에 학습한 개발 지식의 심화 이해 및 강화.
제품 구성
이 프로젝트는 크게 세 가지 유형의 클라이언트로 구성됩니다.
- 사용자 클라이언트: 개인화된 뉴스 콘텐츠를 제공받는 최종 사용자용 플랫폼으로, 모바일 웹, iOS 및 Android 앱으로 구성됩니다. 독서, 팔로우, 댓글, 지능형 챗봇(대화 로봇) 등의 기능을 포함합니다.
- 미디어 제작자 클라이언트: 자가 미디어 작성자가 기사를 편집, 발행하고 운영 데이터를 확인할 수 있는 플랫폼입니다.
- MIS 관리자 백엔드: 시스템 운영 관리를 위한 관리자 페이지로, 사용자 관리, 기사 검토 및 관리, 댓글 관리 등의 기능을 제공합니다.
개발 환경 설정: 가상 머신 활용
프로젝트 개발 환경은 가상 머신을 통해 구축됩니다. 실제 기업 서버 환경을 시뮬레이션하기 위해 GNOME 없는 텍스트 기반의 CentOS 7.2 환경을 사용합니다.
- 가상 머신 설정:
- 시작 전 NAT 모드로 네트워크 설정.
- 기본 메모리 4GB, 호스트 메모리가 부족할 경우 2GB로 조정 가능.
- SSH 접속:
- Windows 환경에서는 Termius, Xshell과 같은 SSH 클라이언트를 사용하여 접속.
- 접속 명령어:
ssh python@자신의_IP주소 - 시스템 사용자: root (비밀번호: chuanzhi), python (비밀번호: chuanzhi)
- MySQL 사용자: root (비밀번호: mysql)
- 주요 서비스 포트:
- MySQL (MariaDB): 마스터 (3306), 슬레이브 (8306)
- Redis 클러스터: 7000-7005
- Redis 마스터/슬레이브: 6380, 6381
- Redis Sentinel: 26380, 26381, 26382
- Elasticsearch 5: 9200
- Python 가상 환경:
workon toutiao명령어를 사용하여 가상 환경 활성화.
- 기본 명령:
- 가상 머신 종료:
sudo shutdown now - 가상 머신 재시작:
reboot
- 가상 머신 종료:
PyCharm 원격 개발 환경 설정
로컬 Windows 환경의 PyCharm에서 코드를 작성하고, 원격 서버의 Python 인터프리터를 사용하여 코드를 디버깅하고 실행할 수 있도록 설정합니다.
- PyCharm에서 프로젝트를 열고,
Tools메뉴에서Deployment>Configuration...을 선택합니다. - 좌측 상단의
+버튼을 눌러 새로운 서버를 추가하고,SFTP타입을 선택합니다. - 서버 이름을 설정하고 (예: Toutiao-VM),
OK를 클릭합니다. Connection탭에서 서버 정보를 입력합니다:Host:가상 머신의 IP 주소Port:22 (기본 SSH 포트)Username:pythonPassword:chuanzhi
Test Connection버튼을 클릭하여 서버 연결을 확인합니다.Mappings탭으로 이동하여 로컬 경로와 배포 경로를 설정합니다.Local path:로컬 프로젝트의 최상위 경로Deployment path:원격 서버의 프로젝트 경로 (예:/home/python/toutiao-backend)
Settings(Preferences) >Project: [프로젝트명]>Python Interpreter로 이동합니다.- 우측 상단의 톱니바퀴 아이콘을 클릭하고
Add...를 선택합니다. SSH Interpreter를 선택하고,Existing configuration을 사용하여 방금 설정한 배포 서버를 선택하거나, 새로운 SSH 연결 정보를 입력합니다.Interpreter:필드에 원격 가상 환경 내의 Python 인터프리터 경로를 지정합니다 (예:/home/python/.virtualenvs/toutiao/bin/python).Path mappings섹션에서 로컬 프로젝트 경로와 원격 서버의 프로젝트 경로가 올바르게 매핑되었는지 확인합니다.- (선택 사항)
Automatic Upload옵션을 활성화하여 코드를 저장할 때마다 자동으로 원격 서버에 업로드되도록 설정할 수 있습니다.
참고: 초기 설정 후 PyCharm이 원격 환경을 로드하는 데 시간이 다소 소요될 수 있습니다.
제품 및 개발 프로세스
1. 제품 소개
이 프로젝트는 개인화 추천 기술을 기반으로 하는 뉴스 및 정보 제공 서비스입니다. 사용자는 모바일 웹, iOS 및 Android 애플리케이션을 통해 뉴스를 구독하고, 미디어 제작자는 콘텐츠를 게시하며, 관리자는 전체 시스템을 운영하는 구조를 가집니다.
2. 프로토타입 및 UI 설계
- 제품 프로토타입: 제품 관리자가 제작하며, 제품의 기능적 구성과 사용자 흐름을 정의합니다. (예: Axure RP를 통해 제작된
index.html파일로 기능 확인) - UI 효과 다이어그램: UI/UX 디자이너가 제작하며, 제품의 최종 시각적 디자인과 사용자 경험을 표현합니다.
3. 기술 아키텍처
본 프로젝트는 프론트엔드-백엔드 분리(SPA: Single Page Application) 아키텍처를 채택하여 개발됩니다.
4. 개발 팀 및 플랫폼
- 최소 개발 팀 구성:
- 제품 관리자 1명
- UI 디자이너 1명
- 프론트엔드 개발자 2~3명 (Flutter, Vue 등)
- 백엔드 개발자 2~3명
- 추천 시스템 개발자 2~3명
- 챗봇 개발자 1~2명
- 테스트 엔지니어 1~2명
- 주요 개발 플랫폼:
- GitLab: 소스 코드 버전 관리 및 협업을 위해 사용됩니다.
- YApi: API 문서화 및 관리 도구로 활용됩니다.
데이터베이스 설계
효율적이고 견고한 데이터베이스 시스템은 프로젝트의 핵심 기반입니다. 다음은 데이터베이스 설계 시 고려할 사항들입니다.
1. 데이터베이스 설계 요구사항
뉴스 추천 서비스의 사용자 클라이언트 프로토타입을 기반으로 데이터베이스를 설계합니다. 다음 요소들을 상세하게 정의해야 합니다.
- 테이블 구조
- 각 필드의 데이터 타입, NULL 허용 여부, 기본값
- 색인(Index) 설계
- 데이터베이스 엔진 선택
2. 주요 고려사항
- 필드 중복 설계 (공간-시간 트레이드오프): 쿼리 성능 향상을 위해 일부 필드를 중복하여 저장하는 비정규화 전략을 고려할 수 있습니다. 이는 저장 공간을 더 사용하는 대신 쿼리 속도를 높이는 방식입니다.
- 필드 타입 선택:
- 정수형 필드 크기:
INT(M)에서M은 표시 너비를 의미하며, 저장 가능한 값의 범위와는 관계가 없습니다. 숫자가 지정된 너비보다 작을 경우ZEROFILL속성을 사용하면 앞에 0이 채워집니다.CREATE TABLE `test_int_display` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `val_3` INT(3) UNSIGNED ZEROFILL DEFAULT NULL, `val_6` INT(6) UNSIGNED ZEROFILL DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT INTO `test_int_display` (`val_3`, `val_6`) VALUES (1, 1); INSERT INTO `test_int_display` (`val_3`, `val_6`) VALUES (12345, 12345); -- 결과: val_3은 '001', '12345' (3자리 초과 시 잘림 없이 표시) -- val_6은 '000001', '012345' (6자리 미만 시 0으로 채워짐)INT(M)의M값은 표시 너비에 영향을 주지만, 필드가 저장할 수 있는 실제 값의 범위는 변경하지 않습니다. - CHAR vs. VARCHAR:
CHAR: 고정 길이 문자열로, 조회 성능이 빠르지만 공간 낭비가 발생할 수 있습니다.VARCHAR: 가변 길이 문자열로, 공간을 절약할 수 있지만CHAR에 비해 조회 성능이 약간 떨어질 수 있습니다.
- 주요 MySQL 데이터 타입:
타입 크기 설명 CHAR(L)L바이트고정 길이 문자열 (0~255 문자) VARCHAR(L)문자열 길이 + 1 또는 2 바이트 가변 길이 문자열 (0~65535 문자) TINYINT(L)1 바이트 정수 (-128~127 또는 0~255 UNSIGNED) SMALLINT(L)2 바이트 정수 (-32768~32767 또는 0~65535 UNSIGNED) MEDIUMINT(L)3 바이트 정수 (-8388608~8388607 또는 0~16777215 UNSIGNED) INT(L)4 바이트 정수 (-2147483648~2147483647 또는 0~4294967295 UNSIGNED) BIGINT(L)8 바이트 정수 (매우 큰 범위) FLOAT4 바이트 단정밀도 부동 소수점 수 DOUBLE8 바이트 배정밀도 부동 소수점 수 DECIMAL(L, D)가변 정확한 고정 소수점 수 DATE3 바이트 날짜 (YYYY-MM-DD) DATETIME8 바이트 날짜 및 시간 (YYYY-MM-DD HH:MM:SS) TIMESTAMP4 바이트 타임스탬프 (YYYYMMDDHHMMSS, 2037년까지) TIME3 바이트 시간 (HH:MM:SS) TEXT문자열 길이 + 2 바이트 최대 65535자 문자열
- 정수형 필드 크기:
- 색인 (Index): 조회 성능을 크게 향상시키지만, 데이터 삽입, 삭제, 수정 작업의 속도를 저하시킬 수 있습니다.
- 고유 제약 (Unique Constraint): 특정 컬럼의 모든 값이 중복되지 않도록 보장하여 데이터 무결성을 유지합니다.
- 외래 키 (Foreign Key):
테이블 간의 관계를 설정하여 데이터의 참조 무결성을 보장합니다. 외래 키 제약을 추가하는 SQL 구문은 다음과 같습니다.
ALTER TABLE 자식_테이블_이름 ADD CONSTRAINT [제약_이름] FOREIGN KEY (자식_테이블_컬럼, ...) REFERENCES 부모_테이블_이름 (부모_테이블_컬럼, ...) ON DELETE 참조_옵션 ON UPDATE 참조_옵션;ON DELETE및ON UPDATE참조 옵션의 동작 방식:- CASCADE: 부모 테이블의 레코드가 업데이트/삭제될 때, 자식 테이블의 관련 레코드도 함께 업데이트/삭제됩니다.
- SET NULL: 부모 테이블의 레코드가 업데이트/삭제될 때, 자식 테이블의 외래 키 필드 값이 NULL로 설정됩니다. (외래 키 필드가 NULL을 허용해야 합니다.)
- NO ACTION / RESTRICT: 자식 테이블에 관련 레코드가 존재할 경우, 부모 테이블의 레코드 업데이트/삭제를 허용하지 않습니다.
RESTRICT는 즉시 제약을 확인합니다. - SET DEFAULT: 부모 테이블의 변경 시 자식 테이블의 외래 키를 기본값으로 설정합니다. (InnoDB 엔진은 현재 이 옵션을 지원하지 않습니다.)
- MySQL 데이터베이스 엔진 선택:
MySQL은 다양한 스토리지 엔진을 제공하며, 각 엔진은 특정 사용 사례에 최적화된 특징을 가집니다. 현재 MySQL에서 사용 가능한 엔진을 확인하려면
SHOW ENGINES;명령을, 기본 엔진을 확인하려면SHOW VARIABLES LIKE 'storage_engine';명령을 사용할 수 있습니다.- InnoDB:
- ACID 준수 트랜잭션 지원, 커밋, 롤백, 크래시 복구 기능 제공.
- 행(row) 레벨 잠금 지원, 다중 사용자 환경에서 높은 동시성 및 성능 제공.
- 외래 키 제약 조건 지원.
- 주로 높은 데이터 무결성과 트랜잭션이 요구되는 애플리케이션에 적합하며, MySQL의 기본 엔진입니다.
- MyISAM:
- 트랜잭션을 지원하지 않음.
- 테이블 레벨 잠금을 사용하며, 읽기 작업이 많은 환경에서 빠른 삽입 및 조회 성능을 보임.
- `.frm` (테이블 정의), `.MYD` (데이터), `.MYI` (인덱스) 세 가지 파일로 구성됨.
- 주로 단순한 웹 애플리케이션, 데이터 웨어하우스, 읽기 전용 작업에 적합합니다.
- MEMORY:
- 모든 데이터를 메모리에 저장하여 매우 빠른 데이터 접근 속도를 제공.
- HASH 및 BTREE 인덱스 지원.
- 서버 재시작 시 데이터가 소실되므로, 임시 데이터 저장이나 캐싱 목적으로 주로 사용됩니다.
스토리지 엔진 선택 전략: 데이터베이스 내의 각 테이블은 요구사항에 따라 다른 스토리지 엔진을 사용할 수 있습니다. 트랜잭션과 데이터 무결성이 중요한 테이블에는 InnoDB를, 읽기 작업이 많고 트랜잭션이 필요 없는 로그 또는 아카이브 테이블에는 MyISAM이나 Archive를, 임시 데이터 저장에는 MEMORY 엔진을 사용하는 등 유연하게 선택하는 것이 전체 데이터베이스 시스템의 성능을 최적화하는 데 중요합니다.
- InnoDB:
프로젝트 데이터베이스 이해
GitLab 프로젝트 그룹에 참여하여 toutiao-backend 저장소를 클론하고, 프로젝트의 SQL 파일을 분석하여 데이터베이스 스키마와 구조를 이해하는 것이 중요합니다.