2023-03-12-TIL
2023-03-12-TIL
Today I Learned
Instagram Architecture
이 제목 아래에는 인스타그램 아키텍처 자료가 아니라 채널톡 블로그의 분산 락 구현 글 링크가 저장되어 있다. 그 글은 지금 404를 반환하므로 내용을 다시 확인할 수 없다. 분산 락 자체는 여러 서버가 공유하는 저장소(Redis 등)에 락을 두어 동시 수정을 막는 기법이고, Redis 문서의 SET key value NX PX 패턴과 Redlock 알고리즘이 출발점이다.
- https://channel.io/ko/blog/distributedlock_2022_backend
Google Pagination
내가 생각하는 검색기능과 구글의 검색기능은 차이가 있다. 우선 구글은 검색엔진과 대상 DB(아마도 도큐먼트 DB)가 별도로 분리되어 있고, 해당 DB를 참조해서 쿼리 결과를 반환할 것 이다. 반면에, 내가 주로 구현하고자 하는 검색 기능은 RDB에서 쿼리를 통해서 결괏값을 가져오는 게 전부이다. 따라서 페이지네이션도 같은 로직을 통해서 구현한다고 해서 같은 성능 개선을 기대할 수는 없다.
모은 링크는 세 갈래다.
첫째, 화면에 보이는 페이지 번호를 어떻게 만들 것인가. kottenator의 gist는 현재 페이지 주변 몇 개와 첫 페이지, 마지막 페이지만 보여 주고 사이를 ...으로 줄이는 간단한 알고리즘을 보여 준다(1 ... 4 5 [6] 7 8 ... 20 같은 형태).
둘째, 검색 엔진에 페이지가 어떻게 보이는가(SEO). Google 검색 센터 문서는 페이지마다 ?page=n처럼 고유한 URL을 주고, 첫 페이지를 모든 페이지의 canonical로 지정하지 말고 각자 자기 canonical URL을 가지라고 권한다. Google은 URL의 # 뒤 프래그먼트를 무시하므로 페이지 번호를 프래그먼트에 넣으면 안 되고, 예전에 쓰던 rel="next", rel="prev"는 더 이상 사용하지 않는다고 밝힌다.
셋째, DB에서 페이지를 어떻게 가져오는가. OFFSET/LIMIT 방식은 구현이 쉽고 임의의 페이지로 바로 갈 수 있지만, DB가 앞의 행을 모두 읽고 버려야 하므로 뒤쪽 페이지일수록 느려지고, 그 사이에 행이 추가되거나 삭제되면 중복이나 누락이 생긴다. 커서(keyset) 방식은 마지막으로 본 행의 키를 기준으로 WHERE id < :lastId ORDER BY id DESC LIMIT 10처럼 조회해 인덱스로 바로 건너뛰므로 깊은 페이지에서도 빠르다. 대신 임의 페이지 이동이 어렵고 “다음”, “이전” 탐색에 맞는다.
1
2
3
4
5
-- OFFSET 방식: 앞의 10000행을 읽고 버린다
SELECT * FROM posts ORDER BY id DESC LIMIT 10 OFFSET 10000;
-- keyset 방식: 인덱스로 바로 이동한다
SELECT * FROM posts WHERE id < :last_id ORDER BY id DESC LIMIT 10;
전체 개수도 비용이다. Cybertec의 Laurenz Albe는 결과 전체 개수를 세는 count(*) 쿼리가 다른 모든 쿼리를 합친 것보다 비싼 경우가 많다고 지적하며, 가능하면 개수를 표시하지 말고, 필요하면 EXPLAIN의 추정치로 대략적인 수를 보여 주거나 사용자가 원할 때만 정확한 수를 세라고 권한다. Google도 정확한 개수를 보여 주지 않는다는 점을 함께 언급한다. 위 메모처럼 구글과 같은 화면을 RDB 위에 만들 때는, 전체 개수와 깊은 페이지 이동을 포기하거나 근사치로 대체하는 것이 현실적인 절충이다.
- https://developers.google.com/search/docs/specialty/ecommerce/pagination-and-incremental-page-loading
- https://gist.github.com/kottenator/9d936eb3e4e3c3e02598
- https://groups.google.com/g/api-craft/c/0jHKgRZ2PBY?pli=1
- https://www.lumar.io/learn/seo/site-architecture/pagination-seo-guide/
- https://stackoverflow.com/questions/11272108/logic-behind-pagination-like-google
- https://www.seoclarity.net/blog/pagination-seo
- https://www.link-assistant.com/news/seo-pagination.html
- https://medium.com/swlh/sql-pagination-you-are-probably-doing-it-wrong-d0f2719cc166
- https://www.cybertec-postgresql.com/en/pagination-problem-total-result-count/
- https://itnext.io/the-best-database-pagination-technique-is-530abf2aab51
- https://betterprogramming.pub/you-are-doing-sql-pagination-wrong-739a700acbd0
댓글
아직 댓글이 없습니다