사용자가 공지글을 읽으면, 그 공지글을 읽음처리하려면 어떻게 해야할까? 참 어렵다...
대부분의 개발자들은 이게 뭐가 어려워!
테이블에 유저아이디, 공지글아이디 기준으로 읽음여부 Y/N저장하고 공지글하고 조인해서 여부 같이 붙여서 처리하면 되지!! 하는 사람도 있을것이고... 어렵다고 고개흔드는 사람도 있을것이다.
어렵다고 고개흔드는 사람이 나는 더 낫다고 생각한다.
(그래도 성능을 생각했을 확률이 높은 사람이 이 사람일지도 몰라서..ㅎ, 아니면 정말 모르는건가!!!)
데이터베이스에 넣는 방식은 누구나 생각하겠지만, 상당히 안좋은 방법이다.
만약 100만명 유저가 있고, 공지글이 100개가 쌓여있다고 한다면, 데이터베이스 크기는 어떻게 될까?
최약의 경우 모든 유저가 공지글을 읽었다고 하면, 100만x100개의 데이터베이스 ROW가 생긴다.
그리고 일반적으로 60%정도가 공지글을 읽는다고 해도 60만x100개의 데이터 베이스 ROW가 생길것이다.
6000만 ROW다..그리고 이 데이터는 지속적으로 늘어난다..공지글을 쓰면 쓸수록..
데이터만 어마어마하게 늘어나는게 아닌, 조인을 통한 사용에서도 문제가 발생할수있다..(성능 개판!!)
더불어, 주기적으로 일정 기간이 지난 데이터는 지우는 전략은 기본으로 가져가야 할것이다.
우리는 먼저 문제의 핵심을 파악해야한다.
과연, 6000만 ROW씩을 데이터베이스에 저장할만큼 공지글 읽음 처리가 중요한 기능일까?!
대부분은 중요한 기능/데이터가 아닐 확률이 크다.
심지어, 유저는 있는지도 모를확률이 크다..쩝;;
그렇다면, 좀더 효율적이고, 자원/속도에 이득이 되는 방법을 생각해봐야한다는 결론이 나온다.
여기서 가장중요한것!! HBASE나 클러스터링에서 자주쓰는 그놈!!!
블름필터 알고리즘을 쓰는 방법이있다.
이거 예전에 완벽하게 이해했는뎅 ㅠㅠ 까먹었다...
간단하게 여러개의 해시테이블을 이용하여, 저장할값을 해시한 값을 여러 해시테이블에 저장한다,
그리고 조회를 할때도, 조회할 값의 해시값으로 멀티 해시테이블에 조회하여, 모두 존재하는지를 확인하는 알고리즘이다.
사실 동작방법은 크게 어렵지않고 간단하다.
정확도를 높이면서, 값이 있는지 없는지를 확인하는 알고리즘이다.
여기서 해당 블름필터에 값을 넣고, 조회했을때,
값이 없다고 나오면, 정말 없는것이 100%확률로 맞고,
있다고 한다면, 오차범위(정할수있음)의 확률로 없을수도 있다.
이 알고리즘을 이용하면,
기존 데이터베이스에 저장해서 공지글 읽음을 하는것보다 30배는 더 적은 데이터/메모리를 가지고
공지글 읽었음을 저장하고 조회하여 판단할수있다.
여기서 중요한게 블름필터는 어떤 기준으로 만드느냐는게 중요한데,
그 갯수가 크지 않은 기준(크기가 작은 기준)으로 만드는게 중요하다.
즉, 유저기준으로 만드는것보다는 상대적으로 그 대상이 적은 공지글기준으로 블룸필터를 만드는게 유리하다.
(여러개의 블름필터를 관리해야하는 관점에서 관리대상이 적도록 기준을 잡는게 중요하다)
블름필터는 코드베이스로도 쉽게 쓸수있고, 영속성이 필요하다면, 가장 쉬운 레디스를 통해서도 가능하다.
(redisson 좋다!)
그리고 공지목록에 공지아이디 기준의 블름필터에 유저아이디로 조회를 하여, 해당 공지글을 해당유저가 읽었는지를 확인하여,
공지글에 읽음여부를 붙여서 API응답하게 만들면 된다.
여기서 중요한점!
공지글별로 블름필터를 레디스로 조회해야하기에, 레디스 통신이 공지글 갯수만큼 호출되게 된다.
이부분도, 레디스 파이프실행으로 묶어서 한번에 호출하도록 하여, 네트워크 통신비용을 한번으로 줄여서 그 효율을 극대화해야한다.
또한 공지글 목록이 과도하게 많을수있기에, 적절한 청크로 나눠서 파이프실행을 해야, 문제가 없을것이다.
어떠한 기능을 만들때는 정직한 방법만이 꼭 정답이 아닌 경우도 많다.
위 공지글 읽음같은 경우가 그 예라고 볼수있다.
개발자는 주어진 기능에 대해서 판단하고,
전제조건/필요조건의 수정을 통해 더 큰 이득을 얻을수있는지를 파악하는 능력또한 중요하다.
너무 정직하게만 개발을 하지말자..
그건 그렇고, HBASE에서 블름필터 공부한게..벌써..몇년이나 된거야 ㅠㅠ
'MY개발생각' 카테고리의 다른 글
| [개발생각] 트랜잭션 시간을 줄이자 (0) | 2026.04.05 |
|---|---|
| [개발생각] 게시판 JPA로 구현할때, 정해야 할것들 (0) | 2026.03.30 |
| [개발생각] StructuredTaskScope에 대해서 (0) | 2026.03.24 |
| [개발생각] 스크럼의 진정한 목적이 무엇일까? (0) | 2026.03.22 |
| [개발생각] REDIS에서 아토믹처리를 하려면 (0) | 2026.03.22 |
