'분류 전체보기'에 해당되는 글 648건

  1. 2015/04/08 용비 07. Step-5. Clustering the application
  2. 2015/04/06 용비 06. Step-4. Configuring the default cache
  3. 2015/04/06 용비 05. Step-3. Making Entries expire
  4. 2015/04/03 용비 04. Step-2. Putting stuff in the cache
  5. 2015/04/03 용비 03. Step-1. Initializing the CacheManager

이번 단계에서는 강력한 infinispan clustering 대해 알아볼 것이다. Multiple node 데이터를 어떻게 공유할 있는지를 보여줄 것이다. multiple node 동일 physical host 있을 수도 있고, 분리된 VM이나 따로 떨어진 machine 있을 수도 있다. tutorial 목적에 맞도록 동일한 host에서 모든 node 실행하는 것은 network이나 firewall 대한 변경작업이 필요 없이 때문에 가장 쉬운 방법이다. 최고의 결과를 위해 vertical splitting (여러 개의 터미널 윈도우 사용) 지원하는 terminal 사용하라. (Linux : Terminator, OSX : iTerm2, Windows : ConEmu)


CacheManager Cluster 속하도록 설정하기 위하여 특별히 전송이 가능한 "global" configuration 설정해야 한다.


GlobalConfigurationBuilder global = GlobalConfigurationBuilder.defaultClusteredBuilder(); global.transport().clusterName("WeatherApp");

cacheManager = new DefaultCacheManager(global.build(), config.build());


우리는 편리한 defaultClusterBuilder() method 사용하여 쉽게 갔지만, GlobalConfigurationBuilder 구성하고 필요한 파라미터들을 수정함으로 동일한 결과를 얻을 있다. Clustered CacheManager 만드는 것만으로는 충분하지 않다. 우리는 Clustered Cache 원한다. 예제에서는 default cache configuration 수정하여 기본적으로 2곳에 데이터를 저장하는 distributed synchronous cache 사용할 것이다.


config.clustering().cacheMode(CacheMode.DIST_SYNC);


우리가 저장한 Entries들은 network 통해 node 전송되어야 하기 때문에, key value 대해서 java.io.Serializable interface 통해 구현할 필요가 있다. Entry들은 key hash하여 cluster member 사이에 분산처리 된다. 2곳에 저장하도록 설정했기 때문에, entry primary owner backup owner 가질 것이다. 이제 여러 개의 terminal 띄워 놓고 다음과 같이 해보자.


git checkout -f step-5

mvn clean package exec:exec # from terminal 1

mvn exec:exec # from terminal 2


서로간에 "wait"하도록 설정하지 않았기 때문에 첫번째 instance 시작되자마자 두번째 instance 시작하라. 최종 결과는 이전 단계와 유사하겠지만 (2곳에서 보여짐), 서로 간의 node discovery 관련된 추가적인 logging 있을 것이다. 우리는 이런 동작을 통제하기 위해서 다음 단계에서는 listener 추가할 것이다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/672

이전 단계에서 우리는 put() method 대한 overload mortal entries (생명주기를 갖는 데이터) 저장했다. 하지만, 모든 데이터에 대해서 같은 lifespan으로 유효기간을 설정하고 싶다면, Cache default expiration value 가지도록 설정할 있다. 이렇게 하기 위해서 org.infinispan.configuration.cache.Configuration object 파라미터로 넘겨서 DefaultCacheManager 구성할 것이다. Infinispan Configuration 대부분 runtime시에는 변경할 없다. 그리고 ConfigurationBuilder 통해서 생성할 있다. 위의 use-case (ConfigurationBuilder 이용) 경우, 모든 entries 대해 5초간의 기본 유효기간을 가지도록 cache configuration 생성해보자. 다음 코드는 어떻게 생성할 있는지를 보여준다.


ConfigurationBuilder config = new ConfigurationBuilder();

config.expiration().lifespan(5, TimeUnit.SECONDS);

cacheManager = new DefaultCacheManager(config.build());


Configuration Builder fluent pattern (method cascading or method chaning) 사용한다. 따라서 chained method 통해서 configuration 튜닝할 있다. 다시 application 실행해보자.


git checkout -f step-4

mvn clean package exec:exec


이전 단계와 같은 결과가 나올 것이다. 우리는 application 동작을 변경한 것이 아니라 cache 대한 semantics 변경했다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/671

일반적으로 application 값비싼 계산 결과나 data 조회하는 것이 data-source 느리게 하는  경우 (ex. Database or webservice) cache data 저장한다. 만약 그러한 데이터가 도시명이나 제품 형태와 같이 변경할 없다면 (혹은 대부분 변경할 없는 경우) 그러한 형태로 저장하는 경우는 의미가 있다하지만, 데이터가 주기적으로 재생성되거나 다시 조회해야 필요가 있다면 expiration time (유효기간) 설정하는 것을 고려해볼 만하다. 이런 cache entry들을 mortal (생명주기를 갖는 데이터)이라고 한다. Infinispan에서는 2가지 형태로 entry expiration time 설정할 있다.

  • 데이터가 cache 저장된 이후 유효 기간 (ex. lifespan)
  • 데이터의 최종 접근 시간 (last accessed time)이후 유효 기간 (ex. Maximum idle time)

Cache Interface 특별히 하나 혹은 두가지 expiration properties들을 적용할 있도록 put() method overloaded version 제공한다. 다음 예제는 5초간의 유효기간을 갖는 entry 어떻게 저장하는 지를 보여준다.


cache.put(location, weather, 5, TimeUnit.SECONDS);


이것을
유념하면서 application 다시 실행시켜 보자.


git checkout -f step-3

mvn clean package exec:exec


[Output]

---- Fetching weather information ----
Rome, Italy - Temperature: 12.9° C, Conditions: light rain
Como, Italy - Temperature: 6.3° C, Conditions: Sky is Clear
Basel, Switzerland - Temperature: 0.8° C, Conditions: overcast clouds
Bern, Switzerland - Temperature: -1.6° C, Conditions: broken clouds
London, UK - Temperature: 1.8° C, Conditions: light rain
Newcastle, UK - Temperature: 2.6° C, Conditions: scattered clouds
Bucharest, Romania - Temperature: 9.3° C, Conditions: scattered clouds
Cluj-Napoca, Romania - Temperature: 6.4° C, Conditions: scattered clouds
Ottawa, Canada - Temperature: -7.0° C, Conditions: overcast clouds
Toronto, Canada - Temperature: -7.0° C, Conditions: broken clouds
Lisbon, Portugal - Temperature: 14.6° C, Conditions: overcast clouds
Porto, Portugal - Temperature: 12.2° C, Conditions: moderate rain
Raleigh, USA - Temperature: 3.9° C, Conditions: Sky is Clear
Washington, USA - Temperature: 3.4° C, Conditions: light rain
---- Fetched in 1205ms ----
---- Fetching weather information ----
Rome, Italy - Temperature: 12.9° C, Conditions: light rain
Como, Italy - Temperature: 6.3° C, Conditions: Sky is Clear
Basel, Switzerland - Temperature: 0.8° C, Conditions: overcast clouds
Bern, Switzerland - Temperature: -1.6° C, Conditions: broken clouds
London, UK - Temperature: 1.8° C, Conditions: light rain
Newcastle, UK - Temperature: 2.6° C, Conditions: scattered clouds
Bucharest, Romania - Temperature: 9.3° C, Conditions: scattered clouds
Cluj-Napoca, Romania - Temperature: 6.4° C, Conditions: scattered clouds
Ottawa, Canada - Temperature: -7.0° C, Conditions: overcast clouds
Toronto, Canada - Temperature: -7.0° C, Conditions: broken clouds
Lisbon, Portugal - Temperature: 14.6° C, Conditions: overcast clouds
Porto, Portugal - Temperature: 12.2° C, Conditions: moderate rain
Raleigh, USA - Temperature: 3.9° C, Conditions: Sky is Clear
Washington, USA - Temperature: 3.4° C, Conditions: light rain
---- Fetched in 2ms ----
---- Fetching weather information ----
Rome, Italy - Temperature: 12.9° C, Conditions: light rain
Como, Italy - Temperature: 6.3° C, Conditions: Sky is Clear
Basel, Switzerland - Temperature: 0.8° C, Conditions: overcast clouds
Bern, Switzerland - Temperature: -1.6° C, Conditions: broken clouds
London, UK - Temperature: 1.8° C, Conditions: light rain
Newcastle, UK - Temperature: 2.6° C, Conditions: scattered clouds
Bucharest, Romania - Temperature: 9.3° C, Conditions: scattered clouds
Cluj-Napoca, Romania - Temperature: 6.4° C, Conditions: scattered clouds
Ottawa, Canada - Temperature: -7.0° C, Conditions: overcast clouds
Toronto, Canada - Temperature: -7.0° C, Conditions: broken clouds
Lisbon, Portugal - Temperature: 14.6° C, Conditions: overcast clouds
Porto, Portugal - Temperature: 12.2° C, Conditions: moderate rain
Raleigh, USA - Temperature: 3.9° C, Conditions: Sky is Clear
Washington, USA - Temperature: 3.4° C, Conditions: light rain
---- Fetched in 1048ms ----


Expiration 어떻게 동적하는지를 보여주기 위해서 우리는 5초간의 sleep time 추가하고, 세번째로 도시의 날씨를 조회하여 출력해 보았다. 위에서 보는 것처럼 세번째 조회 작업 수행 시간은 거의 첫번째 경우 (uncached case) 비슷하게 측정되는 것을 있다 : 모든 entries들이 유효기간이 지났다. Infinispan에서 expiration 느슨하게 확인한다. 예를 들어, 유효기간이 지난 entry 조회하려고 시도할 경우, 시점에 해당 entry cache에서 삭제될 것이다. Eviction 사용하여 pro-active removal (선제적으로 삭제) 가능하다.


기본적으로 cache 모든 entry 대해서 expire되기를 원하는 경우에는 특별히 put() method 호출을 사용할 필요 없이 cache 대한 설정으로 처리할 있다. 이것은 다음 단계에서 설명할 것이다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/670

CacheManager가 실행되면, 우리는 cache 생성 및 데이터 저장을 시작할 수 있다. Infinispan내의 Cache들은 유일한 이름으로 구분되는 "named" Cache들이다. 하지만, "default" Cache라는 특별한 cache가 있는데, 특별한 이름 없이도 쉽게 얻을 수 있는 cache이다. 이제 초기 버전의 WeatherService를 확장하여 cache에 조회한 날씨 데이터를 저장할 것이다. 이것을 위해서 WeatherService와 구체적인 구현 사이에 추상 클래스(CachingWeatherService)를 생성할 것이다. 이 클래스에서는 값비싼 remote call wrapping하여 remote call결과를 cache하고, 값비싼 remote API를 호출하는 대신, 다시 요청하기 전에 wether 데이터가 이미 cache에 있는지 확인한다. 첫번째로 cache를 얻어온다.

 

Cache<String, LocationWeather> cache = cacheManager.getCache();


CacheManager
에 존재하는 cache가 없으면, default configuration을 사용하여 cache를 생성한다. Key Value generic type assignment type에서 유추할 수 있다.  날씨 정보를 얻어오기 위한 caching wrapper는 다음과 같다.

 

LocationWeather weather = cache.get(location);

if (weather == null) {

weather = fetchWeather(location);

cache.put(location, weather);

}

return weather;


Infinispan
 Cache java.util.Map 인터페이스를 구현했기 때문에, 위의 코드는 따로 설명이 필요 없다. (self explanatory) 이제 Cache가 존재한다. Application을 다시 실행시켜 보자.

 

 

git checkout -f step-2

mvn clean package exec:exec

 

 

[Output]

---- Fetching weather information ----
Rome, Italy - Temperature: 12.9° C, Conditions: light rain
Como, Italy - Temperature: 6.3° C, Conditions: Sky is Clear
Basel, Switzerland - Temperature: 0.8° C, Conditions: overcast clouds
Bern, Switzerland - Temperature: -1.6° C, Conditions: broken clouds
London, UK - Temperature: 1.8° C, Conditions: light rain
Newcastle, UK - Temperature: 2.6° C, Conditions: scattered clouds
Bucharest, Romania - Temperature: 9.3° C, Conditions: scattered clouds
Cluj-Napoca, Romania - Temperature: 6.4° C, Conditions: scattered clouds
Ottawa, Canada - Temperature: -7.0° C, Conditions: overcast clouds
Toronto, Canada - Temperature: -7.0° C, Conditions: broken clouds
Lisbon, Portugal - Temperature: 14.6° C, Conditions: overcast clouds
Porto, Portugal - Temperature: 12.2° C, Conditions: moderate rain
Raleigh, USA - Temperature: 3.9° C, Conditions: Sky is Clear
Washington, USA - Temperature: 3.4° C, Conditions: light rain
---- Fetched in 1634ms ----
---- Fetching weather information ----
Rome, Italy - Temperature: 12.9° C, Conditions: light rain
Como, Italy - Temperature: 6.3° C, Conditions: Sky is Clear
Basel, Switzerland - Temperature: 0.8° C, Conditions: overcast clouds
Bern, Switzerland - Temperature: -1.6° C, Conditions: broken clouds
London, UK - Temperature: 1.8° C, Conditions: light rain
Newcastle, UK - Temperature: 2.6° C, Conditions: scattered clouds
Bucharest, Romania - Temperature: 9.3° C, Conditions: scattered clouds
Cluj-Napoca, Romania - Temperature: 6.4° C, Conditions: scattered clouds
Ottawa, Canada - Temperature: -7.0° C, Conditions: overcast clouds
Toronto, Canada - Temperature: -7.0° C, Conditions: broken clouds
Lisbon, Portugal - Temperature: 14.6° C, Conditions: overcast clouds
Porto, Portugal - Temperature: 12.2° C, Conditions: moderate rain
Raleigh, USA - Temperature: 3.9° C, Conditions: Sky is Clear
Washington, USA - Temperature: 3.4° C, Conditions: light rain
---- Fetched in 2ms ----

 

두번째 날씨 조회 부분에서는 굉장히 빠른 것을 볼 수 있다. 위에서 Cache에 저장된 데이터는 Cache에서 삭제하기 전에는 없어지지 않는다. 다음 단계에서는 어떻게 생명주기를 갖는 데이터를 추가하는지를 살펴볼 것이다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/669

앞서 작성한 간단한 application infinispan을 추가하고, CacheManager를 초기화해보자. Infinispan 추가는pom.xml 파일에 다음 dependency를 추가하면 된다.

 

<dependency>

<groupId>org.infinispan</groupId>

<artifactId>infinispan-embedded</artifactId>

<version>7.1.0.Final</version>

</dependency>

 

이제 CacheManager를 추가할 수 있다. CacheManager는 다음과 같은 기능을 제공한다.

 

·         Cache container 역할. Cache lifecycle 관리

·         Global configuration, common data structure, resource 관리 (ex. Thread pools)

·         Clustering 관리

 

CacheManager는 무거운 component이다. Application 내에서 CacheManager를 초기화하고 싶다면 다음과 같이 간단하게 초기화할 수 있다.

 

CacheManager cacheManager = new DefaultCacheManager();

 

이것으로 Default local (ex. Non-clustered) CacheManager가 생성될 것이다. CacheManager는 적합한 처리가 필요한 약간의 resource를 포함하고 있기 때문에, 더 이상 불필요할 때는 정지시켜야할 필요가 있다. Stop() method를 호출하면 CacheManager가 정지된다.

 

cacheManager.stop();


CacheManager
를 정지하면 CacheManager를 통해서 얻었던 모든 resource들은 더 이상 사용할 수 없다.

 

이번 단계의 application을 컴파일하고 실행하려면 다음과 같이 하면 된다.

 

git checkout step-1

mvn clean package exec:exec

 

전혀 변화된 것이 없음을 보게 될 것이다. 이것은 우리가 CacheManager를 통해서 아무런 작업도 수행하지 않았기 때문이다. CacheManager에 대한 훌륭한 사용법은 다음 단계에서 살펴볼 것이다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/668