Your SlideShare is downloading. ×
0
In-Memory Data Grid 기반 대용량 처리
Architecture Prototype
opennaru.com | 2013 | All Rights Reserved  1
인메모리 데이터그리드기반의 대용량 처리 아키텍처
• WebSocket을 이용한 대용량 데이터 입력 (Async)
• Restful API...
opennaru.com | 2013 | All Rights Reserved  2
시스템 구현 방안
• 데이터 젂송은 WebSocket 프로토콜을 사용
• 테스트 용도로 RESTful API 구현(RESTEasy 사용)...
opennaru.com | 2013 | All Rights Reserved  3
시스템 상세 아키텍처
MariaDB Database
WebSocket Server
@ServerEndpoint
Java Messaging...
opennaru.com | 2013 | All Rights Reserved  4
MariaDB 테이블 정보
opennaru.com | 2013 | All Rights Reserved  5
메시지 Flow(POST)
JBoss
Data Grid
DB에 저장
Enrich
opennaru.com | 2013 | All Rights Reserved  6
Header text
opennaru.com | 2013 | All Rights Reserved  7
WebSocket
WebSocket Server
@ServerEndpoint
Java Messaging Service
demoQueue
...
opennaru.com | 2013 | All Rights Reserved  8
JMS Queue
WebSocket Server
@ServerEndpoint
Java Messaging Service
demoQueue
...
opennaru.com | 2013 | All Rights Reserved  9
Message Driven POJO(Bean)
WebSocket Server
@ServerEndpoint
Java Messaging Se...
opennaru.com | 2013 | All Rights Reserved  10
JAX-RS – RESTful API
WebSocket Server
@ServerEndpoint
Java Messaging Servic...
opennaru.com | 2013 | All Rights Reserved  11
@Service
WebSocket Server
@ServerEndpoint
Java Messaging Service
demoQueue
...
opennaru.com | 2013 | All Rights Reserved  12
@Repository, @Cacheable
WebSocket Server
@ServerEndpoint
Java Messaging Ser...
opennaru.com | 2013 | All Rights Reserved  13
JBoss Data Grid(Library Mode)
WebSocket Server
@ServerEndpoint
Java Messagi...
opennaru.com | 2013 | All Rights Reserved  14
데모 시스템 구성
test11
JBoss(Wildfly) Instance
test12
JBoss(Wildfly) Instance
Jav...
opennaru.com | 2013 | All Rights Reserved  15
장애 복구 후 처리 속도 문제
• JMS(HornetQ)는 처리 속도를 향상하기 위한 버퍼링 기능 제공함
• Consumer에 메시지를...
opennaru.com | 2013 | All Rights Reserved  16
Header text
opennaru.com | 2013 | All Rights Reserved  17
In memory storage engines
Distributed across a cluster providing “networked...
opennaru.com | 2013 | All Rights Reserved  18
Cache 적용 방안과 이슈
B C
D
지연시간
Read
지연시간
A B C
D
Application
A
지연시간
Read
WAS
A
...
opennaru.com | 2013 | All Rights Reserved  19
가상화 기반 환경에서 Scale out 고려 사항
DataGrid #1 DataGrid #2 DataGrid #3 DataGrid #N...
opennaru.com | 2013 | All Rights Reserved  20
opennaru.com | 2013 | All Rights Reserved  21
Eviction (제거)
• Eviction는 메모리가 부족해지지 않도록 메모리에서 엔트리를 삭제하는 과정
• 데이터 손실을 막기 위해...
opennaru.com | 2013 | All Rights Reserved  22
Expiration (맊료) – 1/2
• Eviction와 Expiration 차이
• Eviction - 엔트리 최대수를 넘었을 경...
opennaru.com | 2013 | All Rights Reserved  23
Expiration (맊료) – 2/2
• evictionCache 라는 이름의
Cache 선언
• 최대 1,000 개 엔트리맊 메모
...
opennaru.com | 2013 | All Rights Reserved  24
Header text
opennaru.com | 2013 | All Rights Reserved  25
Query API
• 풀텍스트 검색 엔진 Apache Lucene의 Lucene Directory 로 구현
• put시에 데이터 ind...
opennaru.com | 2013 | All Rights Reserved  26
Header text
opennaru.com | 2013 | All Rights Reserved  27
• 캐쉬 조작을 JTA 트랜잭션(transaction)상에서 사용할 수 있습니다.
• MVCC(Multi-Versioned Concur...
opennaru.com | 2013 | All Rights Reserved  28
• 배치 API는, put을 여러 차례 배치로 조작할 때 성능을 향상시키기 위해 사용할 수 있는
API 입니다.
• 배치 API는 JT...
opennaru.com | 2013 | All Rights Reserved  29
void putAll(Map<? extends K,? extends V> map, long lifespan, TimeUnit unit)...
opennaru.com | 2013 | All Rights Reserved  30
Header text
Upcoming SlideShare
Loading in...5
×

코드로 살펴보는 데이터 그리드 기반 대용량 처리 아키텍처

2,390

Published on

http://www.opennaru.com/
http://opennaru.tistory.com

데이터 그리드를 기반으로 대용량 트랜잭션을 처리할 수 있는 아키텍처 프로토타입을 소개합니다.
아키텍처의 주요 특징은 비동기 메세징을 이용하여 신속하게 데이터를 입력받고, 데이터그리드를 이용하여 데이터베이스의 부하를 낮추는 것입니다.
주요 적용 오픈소스 Wildfly , JBoss Data Grid, MariaDB 이고, 적용 기술들은 WebSocket, Rest API, JMS , EDB (Event Driven Bean), Spring, MyBatis 등 입니다.

주요해결 과제는 다음과 같습니다.

* 대용량 데이터처리를 위한 빠른 프로세싱을 위하여 비동기 메세지를 사용
* 장애시에도 메세지 전달 보장 ( Reliable Message Delivery )
* 데이터베이스의 부하인한 전체 시스템 성능 저하 방지를 위한 인메모리 데이터 그리드 적용
* 고성능 양방향 네트워크 인터페이스를 위한 WebSocket 사용

오픈나루 블로그 - http://opennaru.tistory.com/
오픈나루 홈페이지 - http://www.opennaru.com/

Published in: Technology, Business
0 Comments
16 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,390
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
67
Comments
0
Likes
16
Embeds 0
No embeds

No notes for slide

Transcript of "코드로 살펴보는 데이터 그리드 기반 대용량 처리 아키텍처"

  1. 1. In-Memory Data Grid 기반 대용량 처리 Architecture Prototype
  2. 2. opennaru.com | 2013 | All Rights Reserved  1 인메모리 데이터그리드기반의 대용량 처리 아키텍처 • WebSocket을 이용한 대용량 데이터 입력 (Async) • Restful API 를 이용한 데이터 조회 및 조작 (Sync) • JBoss Data Grid 를 이용한 데이터베이스 Cache MariaDB Database WebSocket Server @ServerEndpoint Java Messaging Service demoQueue JAX RS @Path @Controller Message Driven Bean @Service MyBatis @Repository @Cachable Message Driven BeanMessage Driven POJO(Bean) @MessageDriven JBoss Data Grid JBoss Enterprise Application Platform
  3. 3. opennaru.com | 2013 | All Rights Reserved  2 시스템 구현 방안 • 데이터 젂송은 WebSocket 프로토콜을 사용 • 테스트 용도로 RESTful API 구현(RESTEasy 사용) • 데이터 입력과 처리를 분리하기 위하여 Message Queue를 사용 • 데이터 처리는 MDB(Message Driven Bean)을 사용하여 동시에 처리할 수 있도록 함 • JBoss Data Grid의 캐시를 사용하여 SQL 쿼리 수를 최소화 • 간단한 테이블 구조를 사용(User 정보) • 코드 테이블은 On-Demand 방식으로 JBoss Data Grid 캐시에 적재
  4. 4. opennaru.com | 2013 | All Rights Reserved  3 시스템 상세 아키텍처 MariaDB Database WebSocket Server @ServerEndpoint Java Messaging Service demoQueue JAX RS @Path @Controller Message Driven Bean @Service MyBatis @Repository @Cachable Message Driven Bean Message Driven POJO(Bean) @MessageDriven JBoss Data Grid JBoss Enterprise Application Platform
  5. 5. opennaru.com | 2013 | All Rights Reserved  4 MariaDB 테이블 정보
  6. 6. opennaru.com | 2013 | All Rights Reserved  5 메시지 Flow(POST) JBoss Data Grid DB에 저장 Enrich
  7. 7. opennaru.com | 2013 | All Rights Reserved  6 Header text
  8. 8. opennaru.com | 2013 | All Rights Reserved  7 WebSocket WebSocket Server @ServerEndpoint Java Messaging Service demoQueue JAX RS @Path @Controller Message Driven Bean @Service MyBatis @Repository @Cachable Message Driven BeanMessage Driven POJO(Bean) @MessageDriven JBoss Data Grid JBoss Enterprise Application Platform • JSR 356 표준 API • Full duplex bi-directional 통싞 • Undertow ( Wildfly ) @ServerEndpoint("/websocket") public class WebSocketServer { public static ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<String, Session>(); @OnMessage public String onMessage(String message, Session session) { System.out.println("-------------- WebSocket ------------"); System.out.println(">>>>> Received : "+ message); MessageSender.sendMessage(session.getId(), message); System.out.println("-------------------------------------"); return null; } }
  9. 9. opennaru.com | 2013 | All Rights Reserved  8 JMS Queue WebSocket Server @ServerEndpoint Java Messaging Service demoQueue JAX RS @Path @Controller Message Driven Bean @Service MyBatis @Repository @Cachable Message Driven BeanMessage Driven POJO(Bean) @MessageDriven JBoss Data Grid JBoss Enterprise Application Platform • Java Messaging Service • 메시지 젂달 보장 • 비동기 통싞을 위한 서비스 • HornetQ 구현체 사용(JBoss 포함) <jms-destinations> <jms-queue name="demoQueue"> <entry name="java:jboss/queue/demoQueue"/> <durable>true</durable> </jms-queue> </jms-destinations>
  10. 10. opennaru.com | 2013 | All Rights Reserved  9 Message Driven POJO(Bean) WebSocket Server @ServerEndpoint Java Messaging Service demoQueue JAX RS @Path @Controller Message Driven Bean @Service MyBatis @Repository @Cachable Message Driven BeanMessage Driven POJO(Bean) @MessageDriven JBoss Data Grid JBoss Enterprise Application Platform • Listener 사용 비동기 처리 • JMS Queue의 메시지를 받아 처리 • 멀티 스레드로 동시 처리 @Component public class MessageExtractor implements MessageListener { @Autowired private CustomerService customerService; private ObjectMapper mapper; public void onMessage(Message message) { try { String msg = ((TextMessage) message).getText(); Command command = mapper.readValue(msg, Command.class); System.out.println("================ onMessage =============="); System.out.println(">>>>> command=" + command); ... } catch (Exception e ) { }
  11. 11. opennaru.com | 2013 | All Rights Reserved  10 JAX-RS – RESTful API WebSocket Server @ServerEndpoint Java Messaging Service demoQueue JAX RS @Path @Controller Message Driven Bean @Service MyBatis @Repository @Cachable Message Driven BeanMessage Driven POJO(Bean) @MessageDriven JBoss Data Grid JBoss Enterprise Application Platform • JAX-RS JSR-311 표준 API • EJB, Spring Integration • RESTEasy 사용(JBoss 포함) @Controller @Path("/api") public class CustomerController { @GET @Produces({MediaType.APPLICATION_JSON + ";charset=UTF-8"}) @Path("/customer/{userid}") public Customer getCustomerById(@PathParam("userid") String userid) throws Exception { return customerService.getCustomerById(userid); } @POST @Produces({MediaType.APPLICATION_JSON + ";charset=UTF-8"}) @Path("/customer/{userid}") public Customer updateCustomer(@PathParam("userid") String userid, Customer customer) throws Exception { customer.setUserid(userid); return customerService.updateCustomer(customer); } @DELETE @Produces({MediaType.APPLICATION_JSON + ";charset=UTF-8"}) @Path("/customer/{userid}") public Customer deleteCustomer(@PathParam("userid") String userid, Customer customer) throws Exception { customer.setUserid(userid); return customerService.deleteCustomer(customer);
  12. 12. opennaru.com | 2013 | All Rights Reserved  11 @Service WebSocket Server @ServerEndpoint Java Messaging Service demoQueue JAX RS @Path @Controller Message Driven Bean @Service MyBatis @Repository @Cachable Message Driven BeanMessage Driven POJO(Bean) @MessageDriven JBoss Data Grid JBoss Enterprise Application Platform • Spring MVC Framework • Spring 컴포넌트 @Service public class CustomerService { private Logger logger = LoggerFactory.getLogger(CustomerService.class); @Autowired CustomerDao customerDao; public Customer getCustomerById(String userid) { return customerDao.getCustomerById(userid); } }
  13. 13. opennaru.com | 2013 | All Rights Reserved  12 @Repository, @Cacheable WebSocket Server @ServerEndpoint Java Messaging Service demoQueue JAX RS @Path @Controller Message Driven Bean @Service MyBatis @Repository @Cachable Message Driven BeanMessage Driven POJO(Bean) @MessageDriven JBoss Data Grid JBoss Enterprise Application Platform • MyBatis를 사용하여 구현 • Infinispan Spring 연동 모듈 사용 @Repository public class CustomerDaoImpl extends AbstractDao implements CustomerDao { @CachePut(value="customerCache", key="#customer.userid") public Customer insertCustomer(Customer customer) { int ret = getSqlSession().insert("customer.insertCustomer", customer); return customer; } @CacheEvict(value="customerCache", key="#customer.userid") public Customer deleteCustomer(Customer customer) { int ret = getSqlSession().delete("customer.deleteCustomer", customer); return customer; } @CachePut(value="customerCache", key="#customer.userid") public Customer updateCustomer(Customer customer) { int ret = getSqlSession().update("customer.updateCustomer", customer); return customer; } }
  14. 14. opennaru.com | 2013 | All Rights Reserved  13 JBoss Data Grid(Library Mode) WebSocket Server @ServerEndpoint Java Messaging Service demoQueue JAX RS @Path @Controller Message Driven Bean @Service MyBatis @Repository @Cachable Message Driven BeanMessage Driven POJO(Bean) @MessageDriven JBoss Data Grid JBoss Enterprise Application Platform • JSR 107, 347 표준 API 지원 • JBoss Data Grid(Infinispan) 사용 • Spring Framework 연동 모듈 제공 <namedCache name="customerCache"> <jmxStatistics enabled="true"/> <unsafe unreliableReturnValues="false"/> <clustering mode="distribution"> <stateTransfer awaitInitialTransfer="false" chunkSize="10000" timeout="240000"/> <sync replTimeout="200000"/> <hash numOwners="2" numSegments="80"/> <l1 enabled="true" lifespan="600000"/> </clustering> </namedCache> <namedCache name="zipcodeCache"> <jmxStatistics enabled="true"/> <unsafe unreliableReturnValues="false"/> <clustering mode="distribution"> <stateTransfer awaitInitialTransfer="false" chunkSize="10000" timeout="240000"/> <sync replTimeout="200000"/> <hash numOwners="2" numSegments="80"/> <l1 enabled="true" lifespan="600000"/> </clustering> </namedCache>
  15. 15. opennaru.com | 2013 | All Rights Reserved  14 데모 시스템 구성 test11 JBoss(Wildfly) Instance test12 JBoss(Wildfly) Instance Java SE WebSocket Client
  16. 16. opennaru.com | 2013 | All Rights Reserved  15 장애 복구 후 처리 속도 문제 • JMS(HornetQ)는 처리 속도를 향상하기 위한 버퍼링 기능 제공함 • Consumer에 메시지를 미리 가져다 놓아 다음 메시지 처리 속도를 향상 시킴 • consumer-window-size는 1 MB 기본값 • 속도가 느린 Consumer이 경우 버퍼링 되기 때문에 오히려 속도가 느려짐 • 속도가 느린 Consumer에서는 consumer-window-size를 0 으로 설정 Message Queue Consumer 메시지 처리 메시지 처리 메시지 처리
  17. 17. opennaru.com | 2013 | All Rights Reserved  16 Header text
  18. 18. opennaru.com | 2013 | All Rights Reserved  17 In memory storage engines Distributed across a cluster providing “networked memory” Pacemakersto databases Provide simple key,valuestorage Linear scalability and elasticitydue to distributed a lgorithms What is a Data Grid
  19. 19. opennaru.com | 2013 | All Rights Reserved  18 Cache 적용 방안과 이슈 B C D 지연시간 Read 지연시간 A B C D Application A 지연시간 Read WAS A Application Cache A B C DA Read DataGrid #1 DataGrid #2 DataGrid #3 DataGrid #4 B C D A A B C D WAS Application A C D B A 지연시간 Read WAS #1 Application Cache B C D A’ A’ B C DA WAS #2 Application Cache A B C DA Step1 : UPDATE … SET ...’A” … Step2 : put() 캐쉬 불일치 (Incoherent) DB와 불일치 (Inconsistency) No Cache Local Cache Cache Consistency Issue Distributed Cache
  20. 20. opennaru.com | 2013 | All Rights Reserved  19 가상화 기반 환경에서 Scale out 고려 사항 DataGrid #1 DataGrid #2 DataGrid #3 DataGrid #N Virtual Machine WAS #1 Application Virtual Machine WAS #2 Application Virtual Machine WAS #3 Application Virtual Machine WAS #1 Application Virtual Machine WAS #2 Application Virtual Machine WAS #3 Application Virtual Machine WAS #N Application
  21. 21. opennaru.com | 2013 | All Rights Reserved  20
  22. 22. opennaru.com | 2013 | All Rights Reserved  21 Eviction (제거) • Eviction는 메모리가 부족해지지 않도록 메모리에서 엔트리를 삭제하는 과정 • 데이터 손실을 막기 위해서는 CacheStore 에 저장 • Eviction은 젂체 클러스터를 대상으로 하지 않고 개별 노드를 대상으로 작업 • Eviction 젂략 • NONE - 설정되어있는 Eviction 젂략 없음 • FIFO - first-in-first-out (선입 선출) 젂략 • LRU - least-recenty-used 젂략 • UNORDERED - 무작위 Eviction 젂략 • LIRS - Low Inter-reference Recency Set 패턴 • Eviction 선언 예 • 최대 1000 개 엔트리, LRU Eviction 젂략, 500 ms 마다 Eviction 쓰레드 실행 <infinispan> <namedCache name="evictionCache"> <eviction maxEntries="1000“ strategy="LRU” wakeUpInterval="500" /> </namedCache> </infinispan>
  23. 23. opennaru.com | 2013 | All Rights Reserved  22 Expiration (맊료) – 1/2 • Eviction와 Expiration 차이 • Eviction - 엔트리 최대수를 넘었을 경우에 삭제 • Expiration - 엔트리 보관 기간을 넘겼을 경우에 삭제 • Expiration는 지정된 시간을 넘긴 엔트리를 삭제 • 엔트리에 lifespan, maximum idle time을 설정하고 초과하는 엔트리는 제거 • Expiration 엔트리는 Eviction 엔트리와 같이 passivate 되지 않음 • Expiration 엔트리는 글로벌하게 삭제 • 메모리, CacheStore, 클러스터 와이드 모두 • Expiration의 예 • HTTP Session • SFSB Session
  24. 24. opennaru.com | 2013 | All Rights Reserved  23 Expiration (맊료) – 2/2 • evictionCache 라는 이름의 Cache 선언 • 최대 1,000 개 엔트리맊 메모 리에 저장 • Expiration 쓰레드는 500ms 마다 실행 • 엔트리는 생성된 지 60,000 ms 되거나 사용된지 10,000 ms 가 지나면 둘 중 먼저의 경우에 맊료 <infinispan> <namedCache name="evictionCache"> <eviction maxEntries="1000" strategy="LRU” /> <expiration wakeUpInterval="500" lifespan="60000" maxIdle="10000” /> <loaders passivation="true"> <loader class="org.infinispan.loaders.file.FileCacheStore"> <properties> <property name="location" value="${java.io.tmpdir}"/> </properties> </loader> </loaders> </namedCache> </infinispan>
  25. 25. opennaru.com | 2013 | All Rights Reserved  24 Header text
  26. 26. opennaru.com | 2013 | All Rights Reserved  25 Query API • 풀텍스트 검색 엔진 Apache Lucene의 Lucene Directory 로 구현 • put시에 데이터 index를 생성/저장 • Hibernate Search API를 사용해 검색
  27. 27. opennaru.com | 2013 | All Rights Reserved  26 Header text
  28. 28. opennaru.com | 2013 | All Rights Reserved  27 • 캐쉬 조작을 JTA 트랜잭션(transaction)상에서 사용할 수 있습니다. • MVCC(Multi-Versioned Concurrency Control) • 캐쉬 엔트리 락 • commit/rollback의 지원 • 동일 트랜잭션(transaction)내에서의 복수의 캐시 인스턴스 조작 • 데드락 검출 try { utx.begin(); Integer value = cache1.get(key); // get에서는 분산 락은 취득하지 않는다 cache1.lock(key) // 명시적인 분산 락 취득[1] value = cache1.get(key); value = value + 1; cache1.put(key, value); // 데이터 변경 cache2.put(key, value); // 암묵적인 분산 락의 취득[2], 데이터의 변경 utx.commit(); // 변경의 반영, 분산 락 개방 } catch (Exception e) { utx.rollback(); // 변경의 취소, 분산 락 개방 } • Distribution 캐쉬의 경우, commit 시 데이터를 복제 합니다. [1] get에서는 락을 취득하지 않기 때문에, get→put를 배타적으로 하려면, 명시적으로 락을 취득할 필요가 있습니다. [2] put 조작은 락을 취득하기 때문에, 이 조작에서는 암묵적으로 락 취득을 합니다. 암묵적인 락 취득하게 하려면, 캐쉬 설정을<transaction lockingMode="PESSIMISTIC">과 같이 지정해야 합니다. JTA 트랜잭션 지원
  29. 29. opennaru.com | 2013 | All Rights Reserved  28 • 배치 API는, put을 여러 차례 배치로 조작할 때 성능을 향상시키기 위해 사용할 수 있는 API 입니다. • 배치 API는 JTA 트랜잭션(transaction)의 지원과 거의 동일한 기능이 되지맊, 트랜잭션(transaction)에 참가 할 수 있는 자원이 1개 JDG 캐시 인스턴스로 한정되는 점이 다릅니다. try { cache.startBatch(); // 배치 트랜잭션 시작 cache.put("k1", "value"); // 분산 락 취득, 데이터의 변경 cache.put("k2", "value"); // 분산 락 취득, 데이터의 변경 cache.put("k3", "value"); // 분산 락 취득, 데이터의 변경 cache.endBatch(true); // 변경의 반영, 분산 락 개방 } catch (Exception e) { cache.endBatch(false); // 변경의 취소, 분산 락 개방 } 배치 API 지원
  30. 30. opennaru.com | 2013 | All Rights Reserved  29 void putAll(Map<? extends K,? extends V> map, long lifespan, TimeUnit unit) NotifyingFuture putAllAsync(Map<? extends K,? extends V> data) putAll • putAll API는, put을 여러 차례 배치로 조작할 때 성능을 향상시키기 위해 사용할 수 있는 API 입니다. • Collection의 객체를 한꺼번에 Cache에 put하여 배치 Loading시에 유리합니다. • 배치 Loading시 put / putAll을 비교하면 성능이 몇 배 이상 빨라집니다.
  31. 31. opennaru.com | 2013 | All Rights Reserved  30 Header text
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×