Loading...

This presentation is an HTML5 website

Press key to advance.

Having issues seeing the presentation? Read the disclaimer

Slides controls
  • and to move around.
  • Ctrl/Command and + or - to zoom in and out if slides don’t fit.
  • S to view page source.
  • T to change the theme.
  • H to toggle syntax highlight.
  • N to toggle speaker notes.
  • 3 to toggle 3D effect.
  • 0 to toggle help.
Whoami

I am..

blog : http://bleujin.tistory.com/
company : i-on communications, cxm team
role : 표준프레임워크 커미터(since 2011)

Working

 - https://github.com/bleujin/aradon(분산 미들웨어)
 - https://github.com/bleujin/craken(분산 레파지토리)
 - etc) aradonClient, isearcher, ionframework

CRAKEN*

Easy Repository For Dev

Rough Explain

HOME :

http://github.com/bleujin/craken

DO / SIMILARY :

Embed Repository / RDB, hadoop, nutch, memcache

SUPER :

infinispan, netty, isearcher

SIZE / SINCE:

about 300 class - 1.0M / since 2012 (current 0.4)
CRAKEN ~= Data + Index + BLOB

Today, Agenda...

Imaging

만약 이런 서비스를 만든다면..

Imaging
IMAGING

Case 1

Mobile Game
IMAGING

Case 2

Weather Service
IMAGING

Case 3

Global CRM Service

WHY

Good! 이제 만들어 봅시다.

ElephantThinking
WHY

처음에는...

흠. 좋아요 심플한 아키텍쳐군요.
WHY

+Blob

상품 이미지같은 BLOB도 관리했으면 해요.
.... 그런 것 쯤이야 금방이죠
WHY

+Index

전문 검색이 필요해요.
.... Lucene을 사용할 기회가 되겠군요(선이 조금 복잡해졌군요)
WHY

+분산

사용자가 너무 많아서 분산이 필요해요
.... 톰캣에는 클러스터링이란게 .. 어?
WHY

+분산

좋아요. 최근 유행하는 OpenSource 기술을 사용하죠.
일단 컴퓨터가 톰캣 3대에 Hadoop은 MasterNode와 DataNode를 포함해서 기본 5대에
Sharding하는 MongoDB를 설치해야 하는데 Mongos와 ConfigSrv와 Sharding을 고려하면...
.... 여기에 Nutch는... 
자.. 잠깐만요. 구현은 그렇다 치더라도 이거 누가 관리하죠?
WHY

그들이 진정 원했던 것은

WHY

Think, Think, Think


우리는 구글이나 애플이 아니에요.
WHY

그럴싸한데?

저희 입장에서는 RDB에 저장된 것만이 아니라 Blob이나 Index도 관리 해야 할 데이타에요
그렇지만 수십대의 분산이 필요하지도 않고 관리할 인력도 없죠. 	

Craken Feature

 

Craken Feature
Craken Feature

특징

  • TreeDocument Data + Blob + Index
  • Embeding
  • Distribute(DIST + REPL)
  • Cache(Memory Grid)
  • Event Notification
Craken Feature

Architecture

Craken Feature

Can do it

자쿠와는 다르다! 자쿠와는!

RDB Schema-Free(TreeDocument Model)
Hadoop Share Data
InMemory DB(H2,HSQL) Distribute
MongoDB Embedable

할 수 있는 것

Share Distributed Data(ex:HttpSession)
Composite Data Repository
Data Analytics Based MapReduce(expect)

극복해야할 과제

낯설다.
느리다.(300 ups, expect : 3000 ups)

Getting Started

Example HelloWorld Source

Getting Started
Getting Started

Hello World

Hello World

public void testHello() throws Exception {
    RepositoryImpl r = RepositoryImpl.inmemoryCreateWithTest() ;
    r.start() ;
    ReadSession session = r.login("test") ;
        
    session.tranSync(new TransactionJob<Void>() {
        public Void handle(WriteSession wsession) {
            wsession.pathBy("/hello").property("greeting", "Hello World");
            return null;
        }
    }) ;
        
    assertEquals("Hello World", session.pathBy("/hello").property("greeting").value()) ;
    r.shutdown() ;
}
Getting Started

Tree Doc Model

Create Emp

session.tranSync(new TransactionJob<Void>(){
    @Override
    public Void handle(WriteSession wsession) throws Exception {
        wsession.pathBy("/emps/bleujin").property("name", "bleujin")
        	.property("age", 20) ;
        wsession.pathBy("/emps/hero").property("name", "hero")
        	.property("age", 21)
        	.addChild("address").property("city", "seoul") ;
        return null;
    }
}) ;

ResultSet rs = session.pathBy("/emps")
    .children().gte("age", 10).toAdRows("name, age, address.city cname") ;
((Rows)rs).debugPrint() ;
}

Output

{"age":21,"name":"hero","cname":"seoul"}
{"age":20,"name":"bleujin","cname":null}
Getting Started

Blob

Blob IO

public void testIO() throws Exception {
    final InputStream src = new StringInputStream("LongLongString");
    
    session.tranSync(new TransactionJob<Void>() {
        public Void handle(WriteSession wsession) throws UnsupportedEncodingException {
            wsession.pathBy("/greet").property("greeting", "Hello World")
                .blob("file", src);
            return null;
        }
    }) ;
    
    final InputStream readed = session.pathBy("/greet").property("file")
        .asBlob().toInputStream();
    assertEquals("LongLongString", IOUtil.toStringWithClose(readed)) ;
}
Getting Started

Index

Auto Indexing

public void testQuery() throws Exception {
    session.tranSync(new TransactionJob<Void>() {
        public Void handle(WriteSession wsession) throws UnsupportedEncodingException {
            wsession.pathBy("/query/1").property("greeting", "태극기가 바람에 펄럭입니다.")
                .property("since", 20);
            wsession.pathBy("/query/2").property("greeting", "태극기가 바람에 펄럭입니다.") ;
            return null;
        }
    }) ;
    
    session.pathBy("/query").childQuery("greeting:바람")
    	.between("since", 10, 30)
        .ascending("since").find().debugPrint() ;
}

Output

ReadNodeImpl[fqn=/query/1]
Getting Started

Event Notification

public void testListener() throws Exception {
    final DebugListener listener = new DebugListener();
    session.workspace().addListener(listener) ;
    session.tran(new TransactionJob<Void>() {
        @Override
        public Void handle(WriteSession wsession) {
            wsession.root().addChild("bleujin").property("name", "bleujin");
            return null ;
        }
    }).get() ;
    assertEquals(1, listener.getCount()) ;
}

@Listener
static public class DebugListener {
    private AtomicInteger counter = new AtomicInteger() ;
    @CacheEntryModified
    public void modified(CacheEntryModifiedEvent<TreeNodeKey, AtomicHashMap<PropertyId, PropertyValue>> e){
        if (e.isPre()) return ;
        if (e.getKey().getType() == Type.DATA && (!e.getKey().getFqn().isSystem()))  {
            counter.incrementAndGet() ;
        }
    }
    public int getCount(){
        return counter.get() ;
    }
}

Demo

 

Demo
Demo

with websocket, script

Location:


Message:

Output:

See it today?

  • Modern Browsers
  • Mobile Browsers
  • Chrome extensions/Firefox Jetpack/Safari extensions
Craken ~= DATA + INDEX + BLOB