주요글: 도커 시작하기
반응형

소셜 네트워크 서비스의 특징은 뭘까? 또는 요즘 서비스들의 특징은 뭘까? 한마디로 정의할 수는 없겠지만, 두드러진 특징 중 하나는 바로 데이터의 '관계(relation)'에 있다. 친구 관계, 사용자와 영화와의 관계, 구매되는 상품 간의 관계 등 관계가 서비스의 핵심적인 요소로 떠오르고 있다. 이런 관계를 표현하는 여러 가지 방법이 있는데, 그 중 하나는 그래프를 사용하는 것이다. 그래프는 Vertex와 Edge로 구성되기 때문에, 관계를 표현하기에 적합하다. 아래는 개발자와 개발 언어 간의 관계를 그래프를 이용해서 표현한 예이다.


[그래프는 Vertext와 Edge로 관계를 보다 직관적으로 표현할 수 있다.]


이런 그래프 데이터를 보관하고 조회하기 위해 RDB나 기타 DB를 사용할 수 있겠지만, 그래프 DB를 사용하면 그래프 자체를 있는 그대로 저장하고 사용할 수 있다. 본 글에서는 그래프DB 중에서 필자가 개인적으로 맘에 들었던 Neo4j를 소개하고자 한다.


Neo4j란?


Neo4j는 그래프 데이터를 저장하고 관리하기 위한 그래프 DB 이다. Neo4j의 주요 특징으로는 다음과 같은 것들이 있다.

  • 자바 기반의 그래프 DB로서, 임베딩 방식과 REST 방식을 지원한다.
  • 트랜잭션을 지원하며, JTA를 지원한다.
  • 인덱스 및 노드 탐색을 지원한다.
  • 이중화를 통한 고가용성을 지원한다. (Zookeeper 사용)
  • 백업/복구를 지원한다.

Neo4j의 그래프 모델


Neo4j의 그래프는 다음의 세 가지로 구성된다.

  • 노드Node (그래프의 Vertex)
  • 관계Relation (그래프의 Edge)
  • 프로퍼티 (노드와 관계의 속성 값)

Neo4j는 노드를 이용해서 데이터를 보관한다. 완전히 동일하진 않지만 관계형 데이터의 엔티티와 유사하다. 관계는 두 노드 사이의 연결을 표현하는 것으로, 방향성을 갖는다. 예를 들어, 앞서 그래프 예시에서 노드와 관계는  아래 그림과 같으며, 개발자1에서 Java로의 방향을 갖는 관계를 갖고 있다.



관계는 단방향일 수도 있고 양방향일 수도 있다. 예를 들어, 친구 관계는 단반향 보다는 양방향에 더 가까울 것이다. 또한, Neo4j의 관계는 타입을 갖는다. 예를 들어, 위 그림에서 관계는 LIKE 타입과 LOVE 타입 두 가지가 존재한다.


노드와 관계는 (키, 값)으로 구성되는 프로퍼티를 이용해서 값을 가질 수 있다. 예를 들어, 개발자를 위한 노드는 아이디, 이름,  이메일 등을 프로퍼티를 이용해서 저장할 수 있으며, 관계는 해당 언어 경력 시작 연도를 프로퍼티로 가질 수 있을 것이다.


그래프의 주요 특징 중 하나는 특정 조건에 따라 경로를 만들수 있다는 것이다. 예를 들어, 친구의 친구 또는 친구의 친구의 친구 관계에 해당하는 사람을 찾고 싶다고 해 보자. 이를 그래프로 표현하면 다음과 같이 직관적으로 탐색할 수 있게 된다.



Neo4j는 노드의 관계를 이용해서 탐색할 수 있는 API와 쿼리 언어를 지원하고 있기 때문에, 위와 같은 그래프에서 친구의 친구 또는 친구의 친구의 친구를 간단한 코드로 찾아낼 수 있다.


Neo4j 퀵스타트


퀵 스타트 문서는 http://docs.neo4j.org/chunked/stable/tutorials-java-embedded.html 에 잘 정리되어 있으니, 이 문서를 보면서 한 단계씩 따라해 볼 것을 권한다.


소셜 네트워크와 추천에서의 Neo4j


여러 가지 활용 분야가 있겠지만, 소셜 네트워크와 추천 기능이 필자가 Neo4j가 끌린 이유이다. 먼저 소셜 네트워크는 태생적으로 그래프에 적합한 데이터 구조를 갖고 있다. 트위터를 보면 한 사람이 다른 사람은 팔로우 하는데, 이 것은 그래프의 한 노드가 다른 노드에 대해 방향이 있는 관계를 갖는 것과 동일하다.


추천은 실제로 적용해보고 싶은 기능중의 하나로서, 특정 노드를 중심으로 한 추천을 가능하게 해 준다. 예를 들어, 회원이 컨텐츠를 좋아하는 관계는 다음과 같은 그래프로 표현할 수 있을 것이다.



위 그래프를 보면 "x가 좋아하는 영화 a를 좋아하는 다른 y가 좋아하는 영화"라는 공식을 사용해서 개인에 맞는 영화를 추천할 수 있음을 알 수 있다. 예를 들어, 로빈훗이 좋아하는 영화를 좋아하는 다른 사람이 좋아하는 영화는 '아이덴티티'와 '내 머리속의 지우개'이다. 여기에 함께 좋아하는 영화 개수가 더 많은 사용자의 랭킹을 높게 준다고 할 경우, '아이덴티티'가 '내 머리속의 지우개'보다 더 높은 점수를 받아서 추천 순위에서 상위에 위치하게 된다. 이걸 RDB와 쿼리를 이용해서 구현하려면 다소 복잡한 쿼리가 나오겠지만, Neo4j가 제공하는 Cypher라는 쿼리를 사용하면 다음과 같이 간단하게 개인에 맞춰진 추천 데이터를 구할 수 있다.


start me=node:USERID(id={0}) 

match me-[:LIKED]->movie<-[:LIKED]-otherUser-[:LIKED]->othermovie

return othermovie, count(*) as count order by count desc


유사한 방식으로 좋아하는 영화가 비슷한 사용자를 찾아서 친구로 추천할 수 있고, 특정 영화를 본 사용자들이 좋아하는 다른 영화를 추천할 수도 있을 것이다. 


Neo4j는 빅 데이터는 아니다


Neo4j는 아직 Shard를 지원하지 않는다. 즉, 모든 데이터가 단일 노드에 위치해야 한다는 얘기다. 물론, N대의 장비를 이용해서 읽기 성능의 확장과 가용성을 증가시킬 수는 있지만, 수평으로 장비를 늘린다고 해서 수용할 수 있는 데이터의 크기가 증가하는 것은 아니다. 따라서, 한 대의 장비의 수용 범위를 넘어서는 빅데이터를 보관해야 한다면 Neo4j는 적합하지 않다.


라이선스의 선택


Neo4j는  제공하는 기능에 따라 GPL, AGPL, 또는 상용 라이선스를 제공하고 있다. 


버전 

기능

라이선스 
Community

기본 기능 

GPL 
Advanced

모니터링 기능

AGPL 또는 상용 라이선스

Enterprise 

온라인 백업, HA, 모니터링

AGPL 또는 사용 라이선스


GPL과 AGPL의 가장 큰 차이점은 GPL은 모듈을 직접 사용하는 경우에만 소스를 오픈하면 되지만, AGPL은 REST 방식으로 사용해도 소스를 오픈해야 한다는 점이다. 예를 들어, Community 버전의 경우 Neo4j를 서버로 두고 별도 프로세스에서 REST API를 이용해서 접근한다면 내가 만든 소스 코드를 공개하지 않아도 되지만, 모니터링이나 HA 같은 기능을 사용하고 싶다면 임베딩 모드이건 서버 모드이건 상관없이 Neo4j를 사용하는 코드의 소스를 공개해야 한다. 소스를 공개하고 싶지 않다면 상용 라이선스를 사야 한다.


정리


Neo4j가 요즘 유행하는 빅 데이터는 아니지만, 거의 90%에 가까운 사이트의 데이터가 빅이 아님을 고려해 봤을 때 Neo4j는 소셜 기능, 추천 기능, 네트워크 분석 기능 등을 구현하기에 적합한 데이터베이스이다. 트랜잭션을 보장하고 있고, Spring Data Neo4j를 통해서 보다 쉽게 사용할 수도 있기 때문에, 그래프의 특징을 이용해서 특정 기능을 구현하고 싶은 개발자들은 Neo4j의 사용을 고려해볼만하다.

+ Recent posts