This presentation is an HTML5 website
Press → key to advance.
Having issues seeing the presentation? Read the disclaimer
blog : http://bleujin.tistory.com/ company : i-on communications, cxm team role : 표준프레임워크 커미터(since 2011)
- https://github.com/bleujin/aradon(분산 미들웨어) - https://github.com/bleujin/craken(분산 레파지토리) - etc) aradonClient, isearcher, ionframework
http://github.com/bleujin/craken
Embed Repository / RDB, hadoop, nutch, memcache
infinispan, netty, isearcher
about 300 class - 1.0M / since 2012 (current 0.4)
만약 이런 서비스를 만든다면..
Mobile Game
Weather Service
Global CRM Service
Good! 이제 만들어 봅시다.
흠. 좋아요 심플한 아키텍쳐군요.
상품 이미지같은 BLOB도 관리했으면 해요. .... 그런 것 쯤이야 금방이죠
전문 검색이 필요해요. .... Lucene을 사용할 기회가 되겠군요(선이 조금 복잡해졌군요)
사용자가 너무 많아서 분산이 필요해요 .... 톰캣에는 클러스터링이란게 .. 어?
좋아요. 최근 유행하는 OpenSource 기술을 사용하죠. 일단 컴퓨터가 톰캣 3대에 Hadoop은 MasterNode와 DataNode를 포함해서 기본 5대에 Sharding하는 MongoDB를 설치해야 하는데 Mongos와 ConfigSrv와 Sharding을 고려하면... .... 여기에 Nutch는... 자.. 잠깐만요. 구현은 그렇다 치더라도 이거 누가 관리하죠?
저희 입장에서는 RDB에 저장된 것만이 아니라 Blob이나 Index도 관리 해야 할 데이타에요 그렇지만 수십대의 분산이 필요하지도 않고 관리할 인력도 없죠.
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)
Example HelloWorld Source
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() ; }
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() ; }
{"age":21,"name":"hero","cname":"seoul"} {"age":20,"name":"bleujin","cname":null}
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)) ; }
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() ; }
ReadNodeImpl[fqn=/query/1]
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() ; } }
Thanks For Listening ! Questions ?
Slides available at
http://github.com/bleujin/craken