데브코스 백엔드 3기 76일차

화수! 외에는 복습 및 휴식으로 강의 없음!
다음주부터 시작될 팀프로젝트를 대비해
프로젝트 시작 전 알고 있으면 좋은 것들에 대해 배웠다


일기(회고)

  • 반성을 좀 하는 1주일 겸 행복했던 1주일이었다
    데브코스 복습겸 휴식이라고 쓰고 방학이라고 읽는다ㅎ
    • 연말이고 해서 보고싶었던 사람들을 많이 만났다
      힐링되었고 행복했다
      추진력을 얻기위한 힘을 누적했다고 생각하고
      이제부터 또 달려야지
    • 그래도 2022를 즐겁게 보내주고 2023년도 즐겁게 맞이해서
      기분은 좋음!
    • 개인적으로 22년은 개발공부를 시작한 해로,
      나에게 새로움 많았던 해기 때문에 한 해 회고를 도전해볼것


  • 계획한 양만큼의 복습을 하지 못했고
    네트워크 공부를 손도 대지 않았다 반성할것
    반성은 하되, 자책은 하지말자 행복했음 되었다 그럴 시간에 움직이자
    그러니까 결론은, 다음주에 조금 더 분주하게 움직일 것!
    • 이번주 게더 사진조차 없다..!


  • kakao tech 영상에서 JVM warm-up 영상을 봤는데 흥미로웠다
    JVM에 대해 공부해볼 것


프로젝트 시작 전 고려할 사항들

Github organization plan

  • free / team / enterprise
  • Member Privileges : Base permissions 미설정된 repo에 어떤 권한 가질지
    • No permission / Read / Write / Admin
    • 보통 Read로 두고 repo 단위로 별도 권한 부여
      • Read : push 안되니까 fork해서 PR
      • Write : push 가능
      • Admin : collaborator 추가 가능
  • Team 설정
    • repo collaborator 추가 시 유저단위보다는 team 만들어 단위로 추가하기
    • Member Base permission을 No permission으로 두고 team에 넣어 권한주기도 함


  • CVCS(Centralized) 중앙집중식 버전관리 시스템 vs DVCS(Distributed Version Control System) 분산 버전관리 시스템
    • Git은 DVCS에 속함



작업관리도구 Issue Tracker

  • JIRA : 자유도 높음(property 추가) / 10명까지 무료 / 관리자가 좋아함
  • Github Projects + Issue
    • 커밋메시지에 이슈번호 남기면 자동으로 링크됨, PR review의 comment를 바로 issue로 만들기 가능
    • 무료
    • 개발자가 좋아함
    • 속도빠름, 직관적
    • 단점 : issue 개별 due date 설정불가 -> milestone 만들어서 due 설정 후 issue가 이걸 설정하게 만들어야함
  • YouTrack : 최근 툴



작업방식 workflow

  • foring workflow : fork한 repo에서 작업하는 것(권한제어 잘하면 feature branch workflow 사용)
  • feature branch workflow : fork하지 않고 원본 repo에서 branch 따서 작업하는 것
    • 1)organization 생성 + Member privileges 설정
    • 2)team 생성
    • 3)repo마다 branch protection rule 설정 + 권한필요한 팀 추가



데이터 직렬화 포맷

  • xml
  • yaml
  • JSON : 자바스크립트에서 객체를 명시하는 문법으로 시작한 개념
    • client -> server : 객체로 만드는 디코딩 비용
    • client <- server : Json 형태의 문자열로 만드는 인코딩 비용
    • 데이터가 많아지면 이것도 병목의 원인이 될 수 있음
  • 요즘 client-side rendering 사용
    • 페이지 일부 변화가 많으니까



클라우드

  • 클라우드 : 서버 컴퓨터 돌리는
    • 쓴 만큼만 과금 + 리소스 무한정 늘릴 수 있음
  • 인프라 구성시 제일 먼저 생각해야 하는거 : 컴퓨터 엔진


  • AWS
    • 얼마나 많은 부분을 추상화 했느냐에 따라
      • EC2
      • ECS
      • ECS + Fargate
      • Lamda
  • Lamda : 1개월당 100만 request 무료(코드 실행시간으로 계산)
    • EC2는 컴퓨터 한대 빌리는 개념 -> 켜져있으면 과금
    • 코드 실행시간을 어떻게 따지지?
      • serverless 개념 사용해서 실행시간이 늘어나지 않으면 과금 안됨
      • 서버 늘리는 것도 CPU사용량 몇퍼센트 넘어가면 자동으로 늘려주는(Auto Scaling)걸로 자동 탑재되어 있음
      • 매우 추상화 되어있음
        • AWS가 서버 많이 띄우고 이사람거 저사람거 다 거기에 돌림



DB (RDB / NoSQL)

  • NoSQL은 RDB의 한계를 극복하기 위해 사용하는 것
    • 대부분의 도메인은 schema가 정해진 데이터 다룸
      • NoSQL의 장점이 schemaless인데, 이 장점을 사용하지 않게되니까 RDB 쓰는편이 좋음


  • MySQL / Oracle / PostgreSQL
    • MySQL과 호환되는 Aurora도 있음(Amazon에서 만든 DBMS)
  • DB도 서버 띄우기 -> DB전용 서버
    • ex) Amazon RDS
      • 사용할 수 있는 DB 한정적 -> Aurora는 Amazon에서 만들었으니 가능


Alter Table문

  • Alter Table문 : 오래걸림 + 테이블 전체에 lock 발생
    => 해결 : Online DDL
    • 테이블에 lock 일으키지않고 alter table문 실행함
    • copy해서 새로운 테이블 만들어서 alter table 동작 후, 참조만 바꿔치기
      • 그동안의 새로운 데이터들은 로그를 따로 모아둠
      • 참조 바꿔칠때만 잠시 lock


index

  • 데이터가 어떻게 저장되는지에 따라
    • clustered : pk 기준으로 정렬해서 저장 - 물리적 저장
    • non-clustered : 별도의 공간에 인덱스내용 저장(fk, uq) - 논리적 저장
  • Where 절에 자주 쓰이는 + 카디널리티 높은(중복 낮은) 컬럼으로 설정하기
  • Tree같은 비선형 자료구조 사용
    • index 타는 쿼리 : select 시 O(1)
  • Like ~%는 인덱스 탐 / Like %~ or Like %~%는 안탐



Table 만들기

  • Table 잘 만들어야함!
    • 쿼리속도가 높아지고, 여기에 붙는 쿼리 작성도 쉬워짐

Data Type

잘못 선택 시 -> 쿼리 느림 + 용량 낭비

1. 문자열 CHAR vs VARCHAR

  • 명시된 최대길이(ex) 100)보다 작은 문자열(ex) 10)이 들어오면
    • CHAR : 100만큼 용량 점유
    • VARCHAR : 10으로 줄이고(resize) 용량아낌
      • resize 과정 -> insert 시간 늘어남
      • resize 된다고 큰값 쓰지말고 가능한 작은거 쓰자
        (너무 크면 index 등록안됨)


  • 길이 편차 작은 주민번호, 핸드폰번호, 비밀번호 암호화 후 -> CHAR(max 255)
  • 길이 편차가 크다 or 256 이상 쓰고 싶다 -> VARCHAR


2. 정수 TinyInt(1) / SmallInt(2) / MediumInt(3) / Int(4) / BigInt(8 byte)

  • 나이 같은거에 TinyInt 쓰면 storage 아낄 수 있음
  • signed
    • type 뒤 unsigned 붙이면 -> 음수표현 위한 비트 아낌 + 양수 범위 2배로 늘어남 = maximum value 확장
      • ex) Auto Increment PK 사용시 유용
  • Int(11) : 괄호안의 숫자는 zerofill(0 어디까지 채울지) option시에만 적용됨


3. boolean
쓸 수 있지만, 사실 DB엔 TinyInt(1)로 치환됨

  • 만약 0,1만 허용 원하면 Bit(1) 쓰는 것 추천


4. 시간 datetime / unix timestamp

  • datetime
    • 저장 시 어느 timezone 따를지 - UTC기준 추천
  • unix timestamp : 2023-01-03 09:00:00 UTC
    • 1970년 이전 못함


  • 표준
    • 이메일 : VARCHAR(320)
    • 주민등록번호 : CHAR(13)



API Specification

  • Web Service에서의 API : Http networking 통해 사용할 수 있는 API = HTTP API
    • end-point 분리해서 많이 사용
    • HTTP API 디자인할 때 사용하는 가이드라인 중 하나 : REST


API 디자인 방법론

  • SOAP
    • legacy
    • Http 위에서 돌아가는 또 하나의 protocol 개념
      • Http 위에서 돌아가니까 Http 생으로 쓰는것보다 훨씬 느림 + 까다로움
      • protocol 개념이라 챙길게 많음
  • REST
    • Http API 디자인 가이드라인 개념
      • 가이드라인 개념이라 챙길게 없음(관련 지식 + web server framework만 있으면 됨)
    • resource마다 CRUD에 맞추어 end-point 하나씩 있음
  • GraphQL
    • end-point 하나 + client는 자신이 원하는 데이터를 query param(GraphQL)에 명시 -> GraphQL에 대응만


Http method semantic

  • 멱동성 idempotence : 2번이상 요청 시 side effect 동일하면(= 데이터의 상태가 동일하면) idempotence하다고 표현
    • idempotent : Get(2번 조회해도 같음), Put(delete 후 insert), Delete
    • not idempotent : Post(2번 생성하면 다름), Patch(update)


  • request
    • Accept-Language : ko
      • value에 해당하는 언어에 맞추어 컨텐츠 제공
    • Accept-Encoding : gzip
      • Client가 해석할줄 아는 압축알고리즘 적어둠
        = 응답 줄 때 이 압축알고리즘 사용해줘 요구
      • (response payload 압축해서 내려받아야 네트워크 비용 아낌)


  • response
    • Location
      • post 성공 시 생성된 resource의 url을 제공하는게 좋음 (+ 201 created code)
    • Content-Disposition : attachment; filename = ""
      • 다운로드되는 파일의 이름을 설정



이번주 영상

kakao tech - JVM warm up / if(kakao) 2022

실제 일어났던 이슈와 그에 대한 해결책을 찾는 과정을 보여줘서 너무 유익했던 영상이었다

  • java : source code -> (compile) byte code -> JVM에서 interprete -> machine code
    • 장점: 독립적 (byte code -> 자바실행 가능한 환경이면 빌드 다시안해도 사용가능)
    • 단점 : compile + interpreter 언어 -> 느림
      • 보완 : JIT(Just In Time) compiler
  • C++ : source code -> (compile + optimization) machine code(program)
    • 장점 : 훨씬 빠름
    • 단점 : 빌드환경 CPU아키텍처에 종속적 -> 다른곳에서 쓰려면 빌드 다시해야함


JIT
적시에 기계어를 만들어냄을 의미

  • byte code -> machine code로 변환 시,
    machine code를 cache에 저장
    -> 반복되는 기계어 변환을 줄임
    -> 성능향상 + 런타임 환경에 맞추어 코드 최적화(또 추가적 성능향상됨)

  • 그럼, application 시작시엔 cache 비어있어 성능 도움 안되겠는데?

    • 그래서 시작 후, 의도적으로 미리 로직 실행
      -> 기계어가 cache에 저장되고 최적화 될 수 있는 warm up 절차 필요


Latency 이슈
카카오 T계정 서버 배포 중 초기응답 지연문제 발생(트래픽이 많지 않은데도)
-> 병목을 찾자!

  • 외부 데이터베이스 지연 없었음
  • application 영역(도메인 로직에 대한)의 지연 없었음
  • Tomcat Web Application의 Thread 개수 : 10~8192로 설정되어 있었음
    • Thread 시작 개수 조정 필요 : 200개로
  • DB연결은 RDB의 connection pool이 20개로 시작되도록 설정되어 있었음 + 서버 시작 이후로도 큰 변화 없었음
    = 문제 없음
  • 계정 API의 JVM warm up이 잘 준비되었는가
    • warm up 동작
      • kubernates liveness/readiness probe 요청
        -> liveness/readiness 요청 처리하는 컨트롤러에서 warmer() 호출
        -> warmer()에서 데이터베이스에 정해진 정보를 지리하도록
    • 실서비스에서 사용하는 API가 아니었음 & 특정 데이터조회 로직에 한정
      = 충분한 warm up과정이 이루어지지 않고있다고 판단

    => 실제 사용하는 API를 localhost로 호출하되, real traffic과 유사한 형태되도록 개선 필요



  • Thread 시작 개수 200개로 조정
  • warm up은 각 pod마다 localhost로 API 요청하도록 변경
  • 실제 API요청과 동일한 응답코드로 처리되도록 호출
  • 대부분의 GET API 포함(특히 서비스에서 자주 사용되는 API들)
  • 이전에는 정해진 시간만큼만 지연시키고 traffic 인입시켰다면
    이제는 warm up이 완료되어야 traffic 인입되게 개선

=> 해결!


2달 후 또 발생

  • warm up count 늘리기
    • 실제 트래픽과 같은 많은수의 warm up 시도
      => 내부 재연상황에서 응답지연문제 해결!

=> 왜 해결되었지? JIT 내부에 대해 알아보자!



JIT 내부

  • JIT는 메서드 전체단위로 컴파일함
    = 메서드 내 모든 바이트코드는 한꺼번에 네이티브 코드로 됨

  • Tiered compilation이라는 단계적 컴파일 통해 코드 최적화함

    • 메서드가 정해진 임계치만큼 호출되면 C1 단계로 최적화
    • C1 : 간략한 최적화
    • 또 임계치 넘게 호출되면 C2 단계로 최적화
    • C2 : 최대 최적화 -> 코드캐시에 저장, 활용 -> 코드의 실행속도 높임

=> JIT는 단계별컴파일을 진행하니까
메서드가 C2 compiler를 통해 최대최적화 될 수 있도록 충분한 warm up시도를 하자!


  • 참고) cache full messgae
    • code cache 가득참 의미
      -> 성능상 이득 기대 못함 -> 크기 늘려주기


업데이트: