DogPic 개발일지 (1) 아키텍처 구성을 위한 기술 스택 조사

서경·2022년 2월 12일
1

DogPic

목록 보기
2/2

2022/02/12
DogPic(가제) notion을 생성했다. 그리고 아키텍처와 기술 스택을 정하고 대략적인 고민거리 등을 적어봤다. 가제는 아마 반려동물 전체를 포괄하는 PetPic, Petroud(Pet + Proud) 등으로 바꿀 수도 있을 것 같다.

MySQL vs PostgreSQL

DB는 크게 의존도가 높은 것 같진 않고, 성능에 크게 영향을 끼치진 않을 것 같아 오픈소스를 사용할 예정이다. 그리고 관계형 테이블을 사용할 예정이라 RDBMS를 택했다. 대상으로는 보편적으로 많이 사용하며 예상 후보로는 MySQL과 PostgreSQL을 올렸다.

서비스의 주 기능이 사진 보기, 사진 업로드하기이기 때문에 예상 쿼리는 SELECT문과 INSERT가 주가 될 것 같다. 따라서 JOIN을 사용한 복잡한 쿼리는 거의 존재하지 않을 것 같으니 일단은 MySQL을 선택할 예정이다. 테이블 정의를 마친 후에 결정할 것 같다.

예상 데이터 유형 중 하나는 업로드를 여러 장 하면 한꺼번에 row를 insert할 것이다. 그런데 보편적으로 반려 동물을 업로드할 때는 다수의 사진을 업로드한다. 그 경우 insert가 한 번에 여럿 발생할 것이다. insert는 상대적으로 느린 연산이기 때문에 몰아서 실행되면 그리 좋은 퍼포먼스를 기대할 수 없을 것 같기 때문에 row를 효율적으로 관리할 방법을 생각해 봐야할 것 같다.

이미지 수가 얼마나 될지는 모르겠지만 이미지마다 저장 정보가 필요하다. 100명이 100장을 올린다고 생각하면 10,000개의 row, 1,000명이 1,000장을 올린다고 생각하면 1,000,000개의 row가 필요하다. 아직 해당 경험이 없어 모르겠는데 막상 봤을 때는 많은 것 같다. (아닐 수도 있다.) 조금 더 조사해야 할 것 같다.

참고한 글 :

https://velog.io/@jisoo1170/Oracle-MySQL-PostgreSQL-차이점은

https://smoh.tistory.com/369?category=706280

https://smoh.tistory.com/370

Sequelize vs TypeORM

ORM 선정에서는 후보에 Sequelize와 TypeORM을 정했다. Sequelize는 기존에 사용한 경험이 있는 데에 점수를 줬고, TypeORM은 TS에 적합하고 최근 Nest와 궁합이 좋다고 해서 나중에 Nest로 이전할 가능성도 있고 배워 두면 괜찮을 것 같아 리스트에 올렸다.

[ORM] Node.js에서 ORM 사용하기글을 참고했을 때, 속도는 TypeORM이 더 좋지만 Sequelize가 더 선언적이라고 해야 할까? 아무튼 TypeORM은 더 raw한 느낌이 든다고 한다. 딱 봤을 땐 TypeORM은 체이닝으로 조금 더 함수형인 느낌이 들어서 보기 좋다는 느낌이 든다. 그러나, 쿼리 자체가 길어지면 객체로 관리하는 Sequelize가 더 인지하기 좋을 수 있겠다는 생각이 든다.

그러나 쿼리가 길어질 일이 거의 없을 것 같고, 속도도 더 빠르며, TS/Nest와 궁합이 좋다는 점에서 TypeORM을 사용해 보기로 결정했다.(나중에 Nest로 마이그레이션할 수도 있기 때문에)

참고한 글 :

https://stackshare.io/stackups/sequelize-vs-typeorm

https://medium.com/enlear-academy/best-orm-libraries-for-javascript-8674c4d49119

Github Actions vs Jenkins

Jenkins의 경우 설정에 자신이 있고, 제어를 할 자신이 있는 경우 추천된다고 한다. 문서도 많고 다양하게 커스터마이징할 수 있다는 장점이 있지만, 호스팅을 모두 직접 관리해야 하기 때문에 모든 문서를 관리하는 비용이 발생한다고 한다.

그러나, Github Actions 같은 경우 많은 부분에서 추상화가 잘 되어있어 쉽게 익힐 수 있고, 별도의 설치도 필요 없기 때문에 작은 환경에서 추천된다고 한다.

일정 규모 이상의 회사들에서 Jenkins를 사용하기 때문에 이번 기회에 사용해보는 것도 좋겠다라고 생각했지만, 아키텍처적으로 Github Actions가 더 적합하다고 판단되어 Github Actions를 선택했다.

참고한 글 :

https://choseongho93.tistory.com/295

  • Winston vs Morgan vs Pino
    • Winston — Fully flexible universal logging library.
    • Morgan — HTTP request logger middleware.
    • Pino — Superfast (very low overhead), all-natural JSON logger.

Winston이 가장 보편적인 것 같다. Morgan도 종종 쓰이는 것 같지만, Winston의 경우 multi destination의 경우에도 좋다고 하고 여러 기능도 지원한다고 한다.

로그는 아마 로그용 mongodb, s3, ec2 환경 중 하나를 파서 그곳에 저장할 예정이다. 배포 환경에는 정확히 배포용 파일만 올리고 싶기 때문이다.

너무 과한 생각일지도 모르겠지만, 예를 들어 누군가 디도스 공격을 한다고 하면 트래픽이 엄청나게 많이 발생할 것이고 그러면 로그 파일 규모가 커질 것이고 로그 파일의 규모도 점점 불어날 것이다. 그리고 관리하지 않는다면 어느새 디스크 잔여량이 부족해 서버가 죽을 수도 있을 것 같다라는 시나리오가 발생할 수도 있을 것 같기 때문에 분리하는 것이 좋다고 생각된다.

대신, rolling rotation을 적용해서 하루 동안의 로그를 누적한 뒤 매일 12시에 로그를 저장하거나 하는 방향으로 수행하면 트래픽 관리도 되고 좋을 것 같다.

그러나, 앱이 죽었을 경우를 대비한 수단도 생각해야할 것 같다.

로그를 굳이 몽고디비에 넣을 필요가 있나? ES에 넣어서 LK로 확인하는 것도 괜찮을 듯

참조한 글 :

https://medium.com/better-programming/a-complete-guide-to-node-js-logging-1ba70a4a346d

→ 내용이 좋았어서 로그 설정할 때 또 읽어봐야겠다.

시스템 아키텍처 스케치

그냥 생각나는 대로 임시로 그려본 것이라 대대적인 수정이 필요하다.


피드백은 언제나 환영합니다!

profile
Happy Hacking!

0개의 댓글