Clean Code that Works.

그래프 데이터베이스와 Neo4j

그래프 데이터 베이스와 Neo4j에 대해서는 아래의 그림 한장으로 설명 될 수 있습니다.
차분히 읽어 보면 개념 자체는 어렵지 않습니다. ㅎㅎ

아래 동영상은 Neo4j의 공동 설립자인 Emil Eifrem이 설명하는 그래프 데이터베이스입니다.


그럼 본론으로 들어가서..
아래 내용들은 Neo4j.org 에 있는 글들을 번역한 것입니다.
되게 어렵게 설명해서 발번역이 됬네요. ㅋ
직접들어가서 한번 보는것도 추천 드립니다.


그래프 데이터베이스란 무엇인가?

그래프 데이터베이스는 데이터를 그래프에 저장하고 데이터의 구조가 가장 일반적이고, 우아하고 높은 접근 방식으로 모든 데이터를 표현할 수 있다.

그래프에 대해 설명하는 몇가지 그래프들을 보도록 하자. 다이어그램 주위의 화살표를 따라 읽으면 문장을 형성해서 그래프를 읽을 수 있다.

그래프는 Nodes 와 Relationships 을 가지고 있다.

A Graph-[:RECORDS_DATA_IN]->Nodes-[:WHICH_HAVE]->Properties.
가장 심플한 그래프는 한개의 노드로 표현할 수 있다. 프로퍼티라는 값으로 정의 될 수 있다.
약간 평범하지 않은 이야기이긴 하지만 노드는 한개의 속성을 가지고 시작해서 몇 백만개까지 증가할 수 있다. 
이렇게 하는 것 보다는 명시적인 관계로 조직된 다수의 노드로 나누는게 좋다.

위 그래프를 화살표를 따라 읽으면 

A Graph는 Nodes 와 Relationships으로 기록 되고, 각각 Node들은 Relationship으로 조직될 수 있다. 
또 Nodes와 Relationships 은 각각 별도로 속성을 가질 수도 있다.


순회를 통해 그래프에 조회 하기

A Traversal - navigates -> a Graph; it - identifies -> Paths - which order -> Nodes.

순회는 그래프에 어떻게 질문을 하는가 라고 말할 수 있다.
알고리즘에 따라 시작 노드 부터 관계가 있는 노드까지 탐색하고, 아래와 같은 질문에 대한 답을 찾을 수 있다. 
"내 친구가 좋아 하는 음악중에 내가 가지고 있지  않은것은 무엇인가?"
"만약 이 파워 서플라이가 다운되면 웹 서비스에 끼치는 영향은 무엇인가?"



노드와 관계에 대한 인덱스.

An Index - maps from -> Properties - to either -> Nodes or Relationships. It - is a special -> Traversal

가끔 특정 노드나 관계에 저장된 속성들에 대해 찾아야할 때가 있다. 
"Account 중에서 사용자 이름이 '그래프 마스터'인 것에 대해 찾아라" 같은 순회 방식은 가장 일반적인 방식으로 인덱스 룩업에 최적화 되어 있다. 

Neo4J란 무엇인?

Neo4j는그래프 데이터베이스로 신뢰할 수 있고 끈끈하게 연결된 데이터들에 대해 빠르게 관리 및 조회할 수 있다.
Neo4j 는 오픈소스 그래프데이터베이스로 Neo Technology에서 제공한다.
Neo4j 속성들과 함께 다양한 관계들과 연결된 노드들을 직접 저장한다.

주요 특징

  • 직관적 : 데이터를 표현하기 위해 그래프 모델을 사용

  • 믿을수 있는 : FULL ACID 트랜잭션을 제공

  • 빠르고 안전한 : 커스텀 디스크와 네이티브 스토리지 엔진 

  • 대규모 확장 : 수십억개의 노드/관계/속성

  • 고 가용성 : 다양한 머신에 분산

  • 사람이 읽기 편한 그래프 

  • 쿼리 

  • 빠른 속도의 그래프 쿼리를 통산 빠른 검색 속도

  • 몇개의 작은 jar 파일들로 서버 세팅 가능

  • 간편 함 : REST interface를 통한 API 제공 및 OOP한 Java API 제공











팀내 공유 했던것 가볍게 정리.


발표 자료 : http://prezi.com/k56wvgphtmix/big/?utm_campaign=share&utm_medium=copy

프레지 자료라.. 읽을 내용이 없습니다. OTL

"생각은 언어로 표현되는 순간 죽어 버린다" 라는 말이 있는데요. 

팀 세미나를 말로 진행했었는데 글로 쓰려니 영 표현이 안되네요 ^^; 


왜 이책을 읽게 되었나?

제가 처음 빅데이터 관련해서.. 읽었던 책이 지금은 3판까지 나온 한빛미디어 출간 Hadoop 완벽 가이드 입니다. 이 책이 처음 출간 되었을 때는 빅데이터에 대한 내용들이 국내에 서서히 알려지기 시작했고 점점 관심있는 사람들이 늘어나기 시작했었습니다. 아무튼 이 책을 한 반절 정도 읽다가 말았다가 작년에 다른 하둡책을 사서 vmware에 우분투를 설치해서 책에 있는 내용을 실습해 봤습니다. 워드카운팅이라던지 기타 등등...


그런데 한달 정도 지나니깐 다 잊어 버렸습니다. -_-;

배웠는데 써먹을 곳이 없으니까 잊어 버린거죠. 그래서 좀 생각을 해 보니.. 내가 너무 빅 데이터의 기술(하둡)에만 집착하고 있는 것이 아닌가.. 과연 빅데이터가 무엇이고 기술적인 관점이 아닌 비즈니스 적인 관점에서 보면 어떻게 될까, 써먹을 곳을 찾아 볼 수 있을까 하고 생각하다가 이 책을 읽게 되었습니다.


제가 생각하는 이 책에서 가장 큰 핵심은 "빅 데이터의 시작은 모델과 시나리오를 만드는 것" 입니다. 

개발자의 마인드에서 빅데이터에 대한 공부를 할때 기술서적을 먼저 보면서 시작 하는 것도 좋지만 빅데이터가 과연 무엇이고 어떻게 써야 하는지 이것을 잘 생각해서 단순히 워드 카운팅이 아닌 진짜 쓸만한 모델과 시나리오를 만들어 보고 이것을 가지고 시작하면 좋을 것 같습니다.


WHY?

그럼 왜 빅데이터가 이렇게 관심을 끌게 되었는지 생각해보면 전체적인 시대의 흐름과 기술의 발전이 빅데이터 시대를 가속화 했다고 볼 수 있습니다.



가트너에 따르면 2020년에 스마트폰과 태블릿, PC 를 제외한 약 260억개의 디바이스가 인터넷에 연결되고 이것들을 포함하면 약 500억에서 750억개의 디바이스가 인터넷에 연결된다고 합니다. 이러한 디바이스들은 다양한 데이터들을 생산하게 되고 이렇게 생산된 데이터들이 빅 데이터가 됩니다.


그리고 이렇게 생성된 빅데이터들을 저장하고 처리하기 위한 시스템들의 가격도 많이 낮아져서 빅데이터가 관심을 끌 수 있는 한가지 원인이 됩니다. 

CPU, STORAGE, NETWORK, BANDWIDTH 이 하드웨어들의 가격은 시간이 지날수록 성능은 향상되고 가격은 낮아지기 때문에 합리적인 가격으로 매우 많은 양의 데이터들을 처리 할 수 있게 됩니다.


이렇게 다양한 디바이스이 만들어낸 데이터들과 이를 처리할 수 있는 하드웨어들의 성능향상과 비용감소에 따라 데이터에서 새로운 가치를 뽑아 낼 수 있기때문에 빅데이터가 인기를 끌게 됩니다. 


구글의 수석 과학자 이런 말을 했다고 하네요.

"우리는 남보다 더 나은 알고리즘을 가진것이 아니다. 단지 우리는 더 많은 데이터가 있을 뿐이다."

물론 더 나은 알고리즘도 가지고 있겠지만 -ㅁ-;; 데이터가 얼마나 중요한지 강조 하고 있습니다.


WHAT? 


그럼 빅데이터는 무엇인가?

IT 시장 전문 리서치 업체인 IDC에서는 아래와 같이 정의 하고 있습니다.


"빅데이터는 클라우드 컴퓨팅과 대형 메모리 모델의 변화를 포함한 하드웨어 기능의 변화와 플랫폼 변경에 따른 데이터 처리 능력과 비용을 극대화하기 위한 기술 범위의 발현이다"


단순히 볼륨이 큰 데이터를 의미 하는것이 아니라 데이터 처리 속도, 데이터 관리 인프라등 여러가지 사항을 만족 해야 빅데이터라고 볼 수 있습니다.


최근에 IDC는 빅데이터를 분석 관점인 BI(Business Intelligence)측면에서 대규모의 데이터로부터 매우 빠르게 데이터를 추출, 발굴, 분석하여 가치를 경제적으로 찾아낼 수 있는 새로운 기술과 차세대 아키텍처라고 정의 하였습니다. 


그럼 빅데이터의 특징을 정의 할 수 있는 4가지 V(보통 이 4가지를 충족하면 빅데이터로 볼 수 있습니다)에 대해서 알아 보도록 하겠습니다.



위 이미지에 설명이 잘 되어 있네요!

여기를 참조 하시면 됩니다. http://dashburst.com/infographic/big-data-volume-variety-velocity/


간략히 정리 해 보면 

VOLUME : Big data is big. 말그대로 BIG 해야 겠죠. 2020년에는 40제타 바이트정도가 될꺼라고 예상한다고 합니다.(1제타 바이트 = 뉴욕 맨하탄의 20% 규모의 서버)

VELOCITY : 보통 한사람당 2.5정도의 네트워크 커넥션을 가지고 있고 엄청난 양의 데이터를 생산해 냅니다. 이것들을 신속하게 분석 해야 겠죠.

VARIETY : 다양한 형태의 데이터들. 지금 당장만 하더라도 YouTube에 40억 시간의 비디오가 올라와있고 페이스북을 통해 한달에 공유되는 내용만 해도 300억 건에 다랍니다.

VERACITY : 데이터의 불확실성. 데이터가 늘어난 만큼 쓸모있는 데이터를 뽑아내는 것도 중요합니다. 북미에서 매년 3조 천억 달러정도가 데이터를 검증하는데 소모 된다고 합니다. 이 때문에 데이터 분석학자들이 많이 필요 하다고 합니다.


HOW?

그럼 빅데이가 무엇인지 대충 감을 잠았으니..어떻게 활용할 것인지 생각해 보도록 하죠.

빅데이터의 주요 니즈와 활용에 대해 아래와 같이 간략히 정리 할 수 있습니다.


1. 대량 데이터 분석과 거래량 처리는 매우 복잡하고 광범위한 데이터베이스의 로직 및 도식을 필요로 함

2. 다량의 정형/비정형 데이터 수집 및 분석 필요

3. 동시에 수 천명의 웹 어플리케이션 사용에 따른 대용량 데이터 관리 필요.

4. 조직관련 데이터는 방대한 네트워크 및 엔티티 유형을 포괄함. 


이러한 비즈니스 활용 시나리오로는 고객 행동분석을 통한 고객이탈 방지, 소셜 네트워크에는 감성 분석을 통해 상품, 서비스에 관한 긍정적인지 부정적인지 어떤 반응을 하는지에 관한 분석이 있습니다. 쇼핑몰에서는 비슷한 취향의 아이템을 추천하는 교차판매 엔진같은게 있을 수 있고, 인터넷의 클릭스트림을 분석하고 로그 데이터의 마이닝을 통해 악의적인 부정과 인터넷 범죄자들을 찾는데 도움이 될 수도 있습니다. 금융 업종 및 제조와 유통 업종에서도 네트워크상에서 발생한 로그와 다양한 센서 기반의 데이터를 통해서 다양한 문제를 파악하고 분석해서 해결하는데 도움이 될 수도 있습니다.

(책을 읽어 보시면 더 다양한 사례를 볼 수 있습니다.)


그럼 어떤 기술을 써야 할까요?

오픈 소스로 다음과 같이 정리할 수도 있습니다. 



허허허.. 이것들 언제 다 배우나요. ㅠㅠ

아래 링크에 위 이미지에 대한 설명이 있습니다. 

http://datakulfi.wordpress.com/2013/03/27/big-data-open-source-technology-landscape/


여기까지 빅데이터에 대해서 간략하게 정리해 보았습니다.

위 견해는 저의 관점에서 바라본 빅데이터구요. 더 많은 관심이 있으신분은 책을 보시는것을 추천 드립니다.


마무리로 간단히 말씀 드리면

개발자로서 빅데이터의 기술 부터 공부하기 보다는 빅데이터가 무엇이고 비즈니스적인 관점에 미리 생각해보고 공부를 하면 빅데이터에 대해서 좀 더 효과적으로 접근할 수 있고 생각의 범위가 넓어질 수 있습니다. 



"데이터가 있다면 데이터를 살펴보고, 우리가 가지고 있는 모든 정보를 마이닝 하자"

- 구글 수석 과학자 -



http://stackoverflow.com/questions/9829224/jquery-mobile-301-redirect-issues

http://java.dzone.com/articles/modelling-data-neo4j-0

이번에도 마음대로 번역!@

내용을 요약하면 노드을의 관계에 대해서 검증(확실하게 아는)된 것이면 노드에 속성을 부여(관계+1속성)을 사용하는 것 보다, 여러 타입의 관계를 사용 하는것이 read 속도에서 압도적으로 빠르다.

지금 하고있는 생활 코딩 소스를 보면 아래와 같은 관계로 표현하는것이 관계를 여러개 타입으로 사용하는 것이다.
관계에 대한 것을 아래처럼 type으로 정의할 수도 있고, 관계 클래스를 만들어서 정의(클래스에 속성값 사용 가능, 관계 + 속성) 할 수 있다.

@RelatedTo(type = "FRIENDS", direction = Direction.OUTGOING)
private Set<leaguesummoner> friends;
@RelatedTo(type = "LIKES", direction = Direction.OUTGOING)
private Set<leaguesummoner> likes;
@RelatedTo(type = "INTEREST", direction = Direction.OUTGOING)
private Set<leaguesummoner> interest;
@RelatedTo(type = "TROLL", direction = Direction.OUTGOING)
private Set<leaguesummoner> trolls;

아래부터 번역 시작.
Java로 작성된 샘플 코드는 Neo4J Java API를 사용한 것이고, Cypher(사이퍼)로 작성된 것은 Neo4j에서 제공하는 Cypher Query Language로 된 것이다.(SQL 처럼)

=======================================================================================

'초보자를 위한 Neo4j 모델링' 시리즈의 이전 포스트에서 양방향성 관계에 대해 살펴보았다. 이 포스트에서는 다른 타입의 여러 관계와 관계에 속성을 사용하는 방법에 대해 비교해 보도록 하겠다.

검증을 위한 속성(Properties as Qualifiers)

Neo4j에서 영화에 대한 평점을 매기는 모델링에 대해 이야기해보자. 사람들은 1~5까지 평점을 매길수 있고 이것을 모델링 하는 처음으로 생각한 방법은 'RATED' 라는 관계를 생성하고 1~5사이의 값을 가지고 있는 rating이라는 속성을 만드는 것이다.

Java 와 Cypher을 사용하여 이 모델에 대한 쿼리를 만드는것은 간단하다. 펄프 픽션에 대한 긍정적인 평가들을 구할려면 아래와 같이 rating이 3이상인 것을 구하면 된다.

1.for (Relationship r : pulpFiction.getRelationships(INCOMING, RATED)) {
2.if ((int) r.getProperty("rating") > 3) {
3.Node fan = r.getStartNode(); //do something with it
4.}
5.}

동일하게 사이퍼에서는 아래와 같이 하면 된다.

1.START   pulpFiction=node({id})
2.MATCH   (pulpFiction)<-[r:RATED]-(fan)
3.WHERE   r.rating > 3
4.RETURN  fan


다양한 관계들

우리는 가능한 관계들에 대해서 다 알고 있기 때문에 각각 평점에 대해 다른 관계를 설정하는 방법을 생각할 수도 있다.  
예를 들어 1~5까지의 평점에 따라  LOVED, LIKED, NEUTRAL, DISLIKED, HATED의 관계를 만들 수 있다. 
이 관계를 그래프로 표현하면 아래와 같다.

이전에 사용했던 쿼리들은 동일한 결과를 표시하기 위해 약간 수정을 해야 한다. 펄프 픽션의 팬이 누구인지 자바로 표현하면 아래와 같다.

1.for (Relationship r : pulpFiction.getRelationships(INCOMING, LIKED, LOVED)) {
2.Node fan = r.getStartNode(); //do something with it
3.}

그리고 사이퍼로 표현하면

1.for (Relationship r : pulpFiction.getRelationships(INCOMING, LIKED, LOVED)) {
2.Node fan = r.getStartNode(); //do something with it
3.}


비교 하기

위 두가지 방법에 대한 쿼리 문법은 크게 다르지 않다. 
예를 들어 보면 10가지 다른  관계가 있고 이중에서 7가지를 조회하는 쿼리를 만들 경우 첫번째 방식이 더 효과적이라고 주장할 것이다. 
이 방식은 우리가 찾길 원하는 관계 타입에 대해서 전부 입력해서 조회하지 않아도 된다.

하지만 우리는 성능에 관점을 두고 두가지 방법으로 탐색을 해보도록 하자. 
첫 번째 실험은 두 가지 방법사이의 쓰기 처리량의 차이가 있는지 알 수 있도록 되어있다.
노드 사이의 1000개의 관계를 생성 하고 이걸 생성하는데 걸리는 시간을 측정했다. 
결과는 아래와 같다.

둘 사이의 명확한 쓰기량 차이는 보이지 않지만 탐색을 위한 경우에는 다르게 나온다.

두 번째 실험은, 100개의 노드와 5000개의 무작위 관계를 가지 쿼리를 수행했다.(무슨 말인지 이해가 안되서 아래 원문을 참조 하세요)
In the second experiment, we executed all the queries shown earlier 100 times on a graph with 100 nodes and 5,000 randomly qualified, uniformly distributed relationships (which makes the degree of each node 100, on average).

실험은 아래 3개지 다른 세팅을 가지고 수행하였다.

1. 캐쉬 없이 데이터를 디스크에서 읽는다.
2. 데이터에 대한 로우레벨 캐시만 적용되어 있고, 하이레벨 캐쉬는 중지
3. 데이터에 대한 하이레벨 캐시 적용.

아래 두가지 그림은 각각 Cypher와 Java에서 수행했을때의 결과를 보여준다.

다양한 관계를 생성하는 방법이 항상 단일관계-1개 속성의 방법보다 더 뛰어난 성능을 보여주고 가끔 8배 이상의 성능을 보여준다. 
여기에는 Neo4j에서 디스크와 메모리에서의 데이터를 구성하는 방법의 기술적인 이유가 있다. 하지만 이 내용을 여기선 다루지 않고, 다음 글에서 이야기 할예정이다.

Single-hop 탐색 측정을 수행한것이 중요한데 이 결과가 8배 빠른데 관계의 깊이가 2레벨이 되면 64배 빠를수 있고 3레벨이 되면 512배 빠를 수 있다.

결론

가능하면 다양한 관계를 설정하는 방식이 단일관계-1개 속성의 방식보다 월등한 성능을 보여준다. 이 방식은 두번째 방식 보다 항상 최소한 2배 이상 빠르다.

만약 하이레벨 캐쉬를 사용하고 native Java API를 사용하면 다양한 관계를 설정하는 방법이 두번째 방식보다 8배 이상 빠르다.