본문 바로가기

MY개발생각

[개발생각] 게시판 JPA로 구현할때, 정해야 할것들

예전에 신입 개발자 뽑을때, 게시판 만들기 코딩 과제 많았다고 하던데, 왜인지 알겠다 ㅋㅋ.. 

 

간만에 게시판을 만들어봤는데, 정말 어렵다. 구현이? 아니..

대량의 호출에도 느려지거나 허무하게 죽지않을 정도로 성능이 나도록 만드는게 정말 어렵다.

어렵다기 보다, 고민 포인트가 정말 많았다.

 

우선 고민 포인트 몇가지가 있었다.

 

1) JPA의 관계설정을 사용해야할까?

 게시판은 게시판, 포스트, 포스트의 댓글, 그리고 댓글의 댓글등, OneToMany, ManyToOne 의 관계설정이 많이 들어간다.

 관계설정을 통해, cascade설정을 하여, 데이터의 저장/삭제등의 동기화를 일관적으로 맞추고,

관계설정에 따라, 알아서 댓글 또는 대댓글등을 불러올수있기에, 상단한 매력으로 다가온다..

 

하지만, 편한만큼, 조회 기능에 많은 공을 드려야하고, 성능 튜닝을 할수있는 포인트가 줄어드는것은 어쩔수없는듯하다.

조회에서는 관계설정을 통해, N+1 문제에 따른 fetch join쿼리를 항상 염두해두어야하고,

관계설정에 따라 데이터 조회가 이루어짐에 따라, 쿼리 튜닝이라던가, 캐시사용에서 제한되는 부분이 존재하게 된다.

 

결론 : 관계설정을 하지않고, 별도의 쿼리를 통해 게시판을 구현한다.

물론 단점도 있겠지만, (아마 큰 단점이라면, 데이터 정합성과 구현의 복잡함일듯하다),

구현을 잘 정리하여 만들수있다면, 어느정도 단점은 극복할수있다고 생각했고, 관계설정을 하지않음으로 해서,

성능상 문제가 발생할수있는 부분에 대해서, 직접 방법을 선택하여 적용할수있기에

성능을 극한으로 끌어올릴수있는 장점을 위해서는 일부 고통(?!)을 감수해야만 한다고 생각했다.

(캐시, 블룸필터, 댓글, 대댓글을 별도 호출로 분리등등)

 

2) 쿼리를 최대한 묶어서 벌크로 요청한다.

관계설정을 하지않고 직접 쿼리를 날리거나, 레디스를 통해 댓글, 태그정보등을 저장할때,

가장 중요하게 생각해야하는 부분은 이런 요청을 최대한 묶어서 한번에 요청하여 사용하는 방법을 통합해서 사용해야,

관계설정을 하지않고, 개발자가 메뉴얼로 조회를 하는 방법에서 오는 성능 향상을 극대화 할수있다.

 

예를 들어)

게시글 목록 조회 기능을 만들때, 기본적으로

게시글 목록 조회 (N개 1번조회) + 게시글에 따른 태그 조회 (레디스 조회 N번) => 1 + N 번



이것을 만약,

게시글 목록조회 (N개 1번조회) + 게시글들에 따른 태그 조회를 한번에 리스트로 요청 
(레디스 PIPE명령을 통해, 복수개의 태그정보 조회요청 1번) => 1 + 1 번

 

1+N번 > 1+1번

2번의 호출로 1+N번 호출하는것과 같은 결과를 얻을수있다.

여기에 대댓글이나, 첨부파일조회등의 조회가 더들어간다고하면, 그 조회의 횟수차이는 더욱더 나게 된다.

이렇듯, 조회의 횟수를 줄이는 방법을 항상 고려해야 성능상의 이점을 얻을수있다.

 

내가 만든 게시판은 목록조회 1번 + 태그조회 1번 + 댓글조회 1번 => 총 3번으로 페이징목록에 대한 요청을 모두 처리하도록 구현했다. 

생각없이 만들면 아마

N개 목록조회 1번 + 태그조회 N번 + 댓글조회 N번 => 1+2N번 호출을 해야 가능한것을 3번으로 줄이게 되는것이다.

 

3) 게시판의 모든 데이터는 데이터베이스에 꼭 저장해야할까?

습관적으로 데이터베이스에 데이터를 저장하는 방법을 우리는 사용하고 있다.

뭔가 이런방식이 데이터가 사라지거나 유실되지 않느다는 과거에서의 학습에서 오는 안도감이랄까?

데이터베이스에 들어가는순간 데이터는 안전해~~ 라는 느낌..

하지만 시대를 바뀌었고, 클러스터링이 가능한 플랫폼들이 나왔고, 데이터 유실을 막아주는 여러 방식이 나오게 되었다.

그중에서 레디스도 퍼시스턴스를 안전하게 지원하는 여러 방법이 존재한다.

RDB, AOF등의 옵션을 통해, 최대한 데이터의 유실을 막을수있고, 서버다운등에 따른 데이터 복구도 할수있다

(물론, 복구에 따른, 시간/리소스의 투여는 감안해야한다. - AOF복구는 많이 느림..)

 

레디스를 적극사용하기로 했다.

특히 태그, 읽음표시, 댓글수등에는 레디스의 자료구조를 최대한 활용하여, 데이터베이스에 직접 저장을 하지않고,

레디스에 저장을 하는 방법을 사용했다. 레디스만으로 구현을 하였고, 만에 하나,

레디스 복구가 어려운 경우는 충분히 데이터베이스를 통해 복구가 가능한 부분을 파악해 두도록 했다.

 

이제는 만들일 없겠지?...ㅋ