최근 NoSQL 관련 소식이 많이 들려서 나름 정리를 해보았다.
NoSQL이란?
- 정의: NoSQL은 비관계형 데이터 저장소로 고정된 테이블 스키마나 조인을 지원하지 않고 수평적 확장에 강하다. 학계에서는 구조적 저장소로 부르기도 한다. 구현 제품으로는 구글의 BigTable, 아마존의 Dynamo가 있고, 아파치 HBase, 페이스북의Cassandra등의 오픈소스 제품도 있다. ( NoSQL is a movement promoting a loosely defined class of non-relational data stores that break with a long history of relational databases and ACID guarantees. These data stores may not require fixed table schemas, usually avoid join operations and typically scale horizontally. Academics and papers typically refer to these databases as structured storage. Notable production implementations include Google’s BigTable and Amazon’s Dynamo, however there are also many publicly available open source variants including Apache HBase and Facebook’s Cassandra.) from 위키피디어
- NoSQL은 수평확장에 강하다. (strong network partition tolerance)
- 이미 많은 대형 사이트 솔루션이 ‘MySQL + Memcached’에서 NoSQL로 변화 중이다.
NoSQL 선택 기준
(참고: Visual Guide to NoSQL Systems)
CAP 선택
- Consistency: each client always has the same view of the data
- Availability: all clients can always read and write
- Partition tolerance: the system works well across physical network partitions
(참고: Brewer’s CAP Theorem CAP 중에서 2개만 얻을 수 있고 하나는 포기해야 한다는 이론)
ex) RDM (MySQL) = C + A, NoSQL (Cassandra) = A + P, BigTable = C + P
Data Model 선택
- Relational: RDBMS, support ACIDity
- Key-value: 키 기반의 get, put, delete 기능 제공
- Column-oriented: 테이블 기반이지만 조인 미지원, 컬럼기반 (not like row-oriented databases)
- Document-oriented: JSON, XML 형태의 구조적 문서 저장, 조인 미지원
NoSQL 적용 사례
Digg.com
- LAMP 기반에서 NoSQL 기반으로 구조 개편 (참고: Saying Yes to NoSQL; Going Steady with Cassandra)
- 상황
- 끝이 안보이게 빠르게 증가하는 데이터 때문에 고성능, 쓰기 중심의 어플리케이션 구축이 어려움
- 수평적, 수직적 확장 전략이 필요함
- CAP에서 Consistency를 포기할 수 있는 상황 (digg 서비스 특징)
- consistency는 어플리케이션 레벨에서 구현 가능
- 복수의 데이터 센터 지원, 수정 작업 시 다운타임 없어야 함
- 오픈소스 Cassandra 선택
- Cassandra? Dynamo 인프라 위에 BigTable 데이터 모델을 가지고 있는 분산 DB
- 컬럼기반, 구조적 문서 저장 가능
- 모든 노드가 개별적(identical)이고 데이터가 여러 노드와 데이터 센터간에 복제되어 안전
- 수평확장할 경우 읽기, 쓰기 성능이 선형적으로 증가
- 현재상황
- full text 인덱싱, relational and graph 인덱싱 추가
- Cassandra 성능 향상 (오픈소스 프로젝트 참가)
- atomic counter 기능 추가 (Zookeeper 기반)
- 그 이후의 자세한 내용 Looking to the future with Cassandra
digg.com 이외 대형 사이트
(참고: Building Scalable Databases: Are Relational Databases Compatible with Large Scale Websites?)
Digg.com에서는 친구가 추천(digg)한 글을 표시해주기 위해 Cassandra를 선택한 것으로 판단된다.
대량의 데이터를 가공하여 개인화된 정보를 표시해줄 때 기존의 RDB + 캐싱 기법이 한계를 갖고 있는데, 이를 비정규화된 데이터를 분산된 서버에 저장하는 방식으로 해결한 것으로 보인다.
즉, 내가 어떤 글을 추천했을 때 내 친구들의 모든 리스트에 내 추천 기록을 저장해서 해당 글이 친구에 의해 추천받았다는 것을 각각의 사용자에게 보여줄 수 있게 되는 것이다.
이는 Daum view에서 내가 구독하는 사용자가 발행한 최신글, 인기글을 보여주거나, 추천 LIVE, 추천평 LIVE를 보여주는 것과 유사하다고 할 수 있는데,
재미있는 사실은 view에서는 전혀 다른 방식으로 이를 해결했다는 것이다.
view에서는 기존 MySQL 기반의 데이터 영역을 Lucene 기반의 검색엔진으로 상당부분 대체했고 서비스가 검색을 기반으로 발전하고 있다.
내가 5명의 블로거를 구독하고 있을 때 이들이 추천한 정보를 가져오기 위해서 SQL 쿼리를 MySQL로 요청하는 것이 아니라,
검색 쿼리를 Lucene으로 요청하게 된다.
예를 들어 RDB 쿼리가 다음과 같다면,
SELECT * FROM recommend_table r
JOIN user_mapping_table um ON r.userid = um.userid
ORDER BY r.id desc;
검색 쿼리가 다음과 같이 만들어 질 수 있다.
(daumid:id1 OR daumid:id2 OR daumid:id3 OR daumid:id4 OR daumid:id5) type:recent
만일 구독 글 안에서 검색을 하고 싶으면 검색엔진의 이점은 더욱 분명히 드러나게 된다.
SELECT * FROM recommend_table r
JOIN user_mapping_table um ON r.userid = um.userid
JOIN news_table n ON r.news_id = n.id
WHERE n.title like ‘%검색어%’ OR n.summary like ‘%검색어%’
ORDER BY r.id desc;
(daumid:id1 OR daumid:id2 OR daumid:id3 OR daumid:id4 OR daumid:id5) type:recent 검색어
물론 Lucene 기반의 데이터 영역이 가지는 구조적 단점이 있겠지만
현재까지는 이런 변화가 기존에 생각하지 못했던 서비스들을 만들어낼 수 있는 기술적 기반이 되었다고 할 수 있다.
그리고 view 서비스는 사용자의 추천 행위를 검색 랭킹에 반영할 수 있는 소셜 검색의 새로운 도전 무대라고 생각한다.
기존에 서비스 기획과 검색 기획이 별도로 진행됐다면 검색이 바로 서비스인 새로운 모습이 구현되고 있는 것이다.
사용자가 참여하는 서비스가 검색의 품질에 직접 기여하게 되고, 검색 랭킹의 영향으로 다시 사용자 참여를 이끌어내는 새로운 생태계가 만들어지기를 기대해 본다.

3 Comments
루씬의 쿼리기반으로 해결할 경우 5명을 구독하니 이런쿼리가 가능하지 천명이상 구독하면 이게 속도가 나올까요? 정답에 가까운 선택은 아닌것 같습니다.^^
현재 몇 백명을 구독한 경우도 속도 문제 없이 잘 동작하고 있습니다. 작성자의 아이디를 모두 색인 처리하기 때문에 문제될 것이 없을 것 같은데요?
물론 이렇게 할 때 RDB의 결합 인덱싱과 검색의 필드 인덱싱이 어떤게 효율적인지 검토가 필요합니다.
색인과 분류에 최적화된게 검색엔진인만큼 아마도 웬만해서는 DB가 검색엔진의 이런 성능을 따라오지 못할것 같네요.
좋은 포스팅 잘 봤습니다.