Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

20배 빨라진 요나! (20x faster Yona!) #37

Open
doortts opened this issue Feb 19, 2016 · 4 comments
Open

20배 빨라진 요나! (20x faster Yona!) #37

doortts opened this issue Feb 19, 2016 · 4 comments

Comments

@doortts
Copy link

doortts commented Feb 19, 2016

@doortts (doortts) 님이 작성한 게시글입니다.
---

목차

  • fork 이후 작업내용
  • 접근방법
  • 지금까지는 그럼 왜? (어른들의 사정)
  • 향후 추가 성능 개선 방향 및 계획

fork 이후 작업내용

1. 밀렸던 기능들 merge
    - 그 동안 만들었지만 merge 하지 못했던 코드들
    - 만들면 금방인데 이런저런 이유로 못했던 기능 작성
3. h2 버전과 분리. MariaDB 로 이전
   - MySQL과 차이점 및 버전 비교
    - 성능자료 및 라이선스 확인
4. 성능 튜닝

성능 튜닝 접근방법

제목은 거창하지만 실제로 한 일은 그저 아주 교과서적인 내용을 그대로 진행했을 뿐입니다.

  • 사람보다 기계를 믿는다.
    • DDL auto generation
    • optimization commands
  • 설정 정리
    • connection pool 확인
    • thread pool 확인
  • 동시처리가 더 좋은 DB 사용 (H2 -> Maria)
    • 해당 DB의 특성 확인
    • 처리 옵션 확인
  • 느린곳을 찾는다. -> 해결가능한가 살펴본다 -> 인덱스, 캐시, 로직우회, 불필요한 요청 skip 등등을 적용해보고 테스트 해본다. -> 기본적으로는 apache bench 를 이용해서 1 user 부터 40~50 user까지 테스트 해본다 -> 테스트 장비가 full load가 걸려서 test 시에 performance drain이 생기지 않게 유의 -> 반복

DB

  • engine option 및 collation type에 따른 성능 확인
    • utf8mb4_bin, utf8mb4_unicode_ci
  • pk, fk에 인덱스가 잘 걸려 있는지 확인
  • 느린쿼리 찾기
    • MariaDB에서 옵션을 설정해서 sql trace
      #General Query Log
      general_log
      
      #Error Log
      
      #Slow Query Log
      slow_query_log = 1
      log-queries-not-using-indexes
      
    • full scan 제거
    • function index 처리 가능확인
      • Mariadb virtual column 테스트
  • 다량 쿼리 찾기
    • trace option 을 통해 페이지별 실행 sql 확인
    • memoization 등을 통해 쿼리 줄이기
  • connector 옵션 확인 후 테스트
  • pool size, timeout 조정하면서 테스트
  • DB block size 확인
  • column data compression 부하 확인
      row_format=compressed, key_block_size=8
    
  • DB lock 발생부분 확인
    • Next-key Locks, Gap lock 발생 부분 확인하기
      • @Transcational 영향 확인
      • 필요시에만 호출되게 하고 akka/promise로 동작하도록 변경

Application

  • CPU 사용이 많은 부분 찾아서 우회하거나 캐싱하기
    • 대체 모듈/엔진 테스트 (rihino, nashorn, marked.js front, markedj 등)
  • 자주 호출되는 메소드 확인
    • 필요할때만 호출되도록 변경
  • 권한에 따른 탐색이 깊어지고 쿼리가 다량 호출 되는 부분 확인
    • early return
    • memoization
  • Cache 사용 (HashMap memoization, guava cache)
    • 캐싱데이터도 zip 압축해서 메모리 사용량 줄이고 원본대비 사이즈 확인 (20% ~ 40% 사이즈 감소)
      • 느려지는 속도도 확인 (10% drain, 10ms -> 11ms)
    • 페이지 캐시는 나중으로 미루고 아직 적용하지 않음.
  • js/css등의 리소스 병합(resource concatenation)
    • latency sum이 줄어들고 page loading 시간 감소. 브라우저로 테스트 및 확인
  • 배경 이미지 사이즈 조절

튜닝결과

  • Concurrency는 높이고 CPU 사용은 줄이고 SQL call 분량도 줄게 되었습니다.
  • 일부 기능/페이지에 있어서는 Embedded 로 동작하는 H2 DB의 수준을 넘어서게 되었고
  • H2 기반으로 동작할때 조차도 기존보다 훨씬 빠르게 동작하게 되었습니다. (Yona H2 버전에 반영)
  • 처리한 내용 각각에 대해서는 AB(Apache Bench) 테스트 결과와 함께 다시 따로 항목별로 정리하기로 하겠습니다.

특히 worst 경우에 해당하는 '본문 + 댓글 55개'의 페이지의 단순 렌더링 처리부분에서만도

warm-up 상태 기준

기존 상태 BEST

Document Length:        880592 bytes

Concurrency Level:      10
Time taken for tests:   6.064 seconds
Complete requests:      10
Failed requests:        0
Total transferred:      8807700 bytes
HTML transferred:       8805920 bytes
Requests per second:    1.65 [#/sec] (mean)

Percentage of the requests served within a certain time (ms)
  50%   4783
  66%   4822
  75%   5005
  80%   5038
  90%   6063
  95%   6063
  98%   6063
  99%   6063
 100%   6063 (longest request)

BAD (튜닝전 H2 DB)

Document Length:        892908 bytes

Concurrency Level:      10
Time taken for tests:   20.210 seconds

그리고 경우에 따라 warm-up 상태, worst는 (튜닝전 MariaDB)

Document Length:        878772 bytes

Concurrency Level:      10
Time taken for tests:   54.772 seconds
Complete requests:      10

Percentage of the requests served within a certain time (ms)
  50%  47777
  66%  51844
  75%  51844
  80%  51844
  90%  54771
  95%  54771
  98%  54771
  99%  54771
 100%  54771 (longest request)

였으나 튜닝 후 -->

Document Length:        892908 bytes

Concurrency Level:      10
Time taken for tests:   1.513 seconds
Complete requests:      10
Failed requests:        0
Total transferred:      8930670 bytes
HTML transferred:       8929080 bytes
Requests per second:    6.61 [#/sec] (mean)
Time per request:       1513.419 [ms] (mean)
Time per request:       151.342 [ms] (mean, across all concurrent requests)
Transfer rate:          5762.69 [Kbytes/sec] received

Percentage of the requests served within a certain time (ms)
  50%   1476
  66%   1487
  75%   1497
  80%   1507
  90%   1512
  95%   1512
  98%   1512
  99%   1512
 100%   1512 (longest request)

수준으로 떨어졌습니다.

단순 비교만으로도 기존 best 상태기준 동일시간 처리량이 4배가 되었습니다. (여기에는 커넥션 요청 감소등 기타 리소부분 튜닝은 제외한 상태입니다.)
그리고 동일자원에서 동시 처리 가능한 접속자 숫자도 늘었고 네트워크 자원은 덜 쓰며 페이지는 더 빨리 열리게 바뀌었습니다.

지금까지는 그럼 왜?

  • 음.. 막상 쓰려고 보니.. 음.. 반성의 마음 뿐이라 할말이 없네요..
  • (...반성.. 반성..)

향후 추가 성능 개선 방향 및 계획

사실 현재정도면 이미 충분히 안정적이 되었고 빨라 졌기 때문에 당분간은 성능을 좀 더 쥐어짜내지 않아도 될 것 같습니다.
(Yona H2 버전 자체도 더더 빨라졌기때문에 말이죠.) 그럼에도 몇 가지 더 정리한다면

  • network을 통한 resource 요청을 좀 더 줄이기
  • EBean(ORM) 쿼리량을 좀 더 줄이기
  • 댓글 유저가 많을 경우 각 유저의 avatar image 요청과 확인(304가 나오더라도 latency가 생기니까)을 어떻게 줄일까에 대한 고민
  • 권한체크의 깊이를 더 줄이고 불필요한 체크를 최소화 하기
    정도를 생각하고 있습니다.

위에 기술한 작업들 각각에 대해서는 진행하면서 raw data를 최대한 남겨 놓았기 때문에 시간되는대로 다시 정리해서 공유하도록 하겠습니다.
(그래 봐야 스스로 반성만 깊어질테니.. 의미가 있나 싶기도 하지만..)

ps.

밤에 집에와서 하려면 참 에너지도 없고 힘들긴 하네요. 크~
(느릿느릿~)

@doortts
Copy link
Author

doortts commented Feb 19, 2016

@tru64ufs (Chang Song) 님이 작성한 코멘트입니다.
---

유후!!!!!

@doortts
Copy link
Author

doortts commented Feb 20, 2016

@benelog (정상혁) 님이 작성한 코멘트입니다.
---

20배 빨라진 근거가 궁금하네요.

@doortts
Copy link
Author

doortts commented Feb 20, 2016

@benelog (정상혁) 님이 작성한 코멘트입니다.
---

호기심에 Cache 적용로직 코드를 보고 리뷰의견을 드렸습니다. 멤버변수에 Thread-safety하지 않은 HashMap을 쓴 부분과 CacheLoader.load()메서드를 원래의 설계 의도와 다르게 쓴 점에 대해서 의견드렸습니다.

개인 프로젝트이니 받아들이실지는 수원님의 자유이고, 답변을 안 하셔도 이해합니다. ^^;

@doortts
Copy link
Author

doortts commented Feb 20, 2016

@doortts (doortts) 님이 작성한 코멘트입니다.
---

제가 load 메소드를 오해해서 작성했었네요. 알려주셔서 고맙습니다. @benelog 님~
새로 올렸는데 여유되시면 한 번 더 봐주세요. LRU 되는 간단한 concurrentHashMap으로 만드는게 목표였거든요.
해당 링크에도 history를 위해 코멘트 남길게요.

그리고 작업했던 내용들 정리해서 내부로도 공유할테니 그때도 보고 의견주세요!
그럼 주말 잘 보내세요

ps
저는 감기가 심하게 와서 병원가보려고요. 감기조심하시구요

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant