2014년 1월 30일 목요일

핫로드 원격 질의 시작 가이드

지난번의 "내장 및 원격 질의" 글에 이어서, 빠른 시간 내에 원격 질의를 배우고 실행할 수 있는 시작 가이드를 준비하였다.

가이드는 간단한 자바 애플리케이션으로 리모트 캐시에 데이터를 저장하고 핫로드를 통한 질의를 사용하여 데이터를 가져온다. 이 프로젝트는 또한 Ion Savin에 의해 C++로 작성된 애플리케이션도 포함한다. 이 애플리케이션은 C++ 핫로드 클라이언트를 사용하며 같은 데이터를 읽고 쓸 수 있으며(아직 질의는 안됨) C++와 자바 클라이언트 간 상호 작용을 보여준다. 이 시점에서 프로토콜버퍼 인코딩 지원은 C++ 클라이언트의 부분이 아니라 외부 C++ 헬퍼 클래스에 의해 지원된다. 하지만 이는 차후 버전에서 향상될 것이다.

이 애플리케이션 코드는 깃허브jboss-jdg-quickstarts 프로젝트 아래에 있다.

이 투토리얼은 JBoss Data Grid(JDG)를 위해서 쓰여졌지만 인피니스팬에게도 역시 적용된 다. 한번 해보고 생각하는 바를 알려주면 감사하겠다.

원문:
Monday, 13 January 2014, A new quick start guide for remote queries over Hot Rod

2013년 11월 24일 일요일

인피니스팬 핫로드 C++ 클라이언트 6.0.0

핫로드 프로토콜을 설계할 때의 주요 목적 중 하나는 핫로드를 언어 중립적으로 하여 다른 언어로 쓰여진 애플리케이션이 인피니스팬 데이터그리드에 저장된 데이터를 사용할 수 있도록 하는 것이었다. 지능적인 클라이언트가 그리드 내에 어떻게 데이터가 저장되어 있는지 알고 더 뛰어난 성능을 제공할 수 있다는 점에서 핫로드 프로토콜은 특별하다. 우리는 세가지의 클라이언트 지능 레벨을 제공한다.


  • L1: 단순 클라이언트로 고정된 서버 주소의 리스트를 사용하여 라운드 로빈(round-robin)으로 그리드에 연결한다.
  • L2: 클라이언트는 그리드의 위상(topology)을 알고, 새로운 서버가 참여하거나 그리드로부터 제거될 때 알림을 받는다.
  • L3: 클라이언트는 그리드 위상과 키 해시를 사용하여 특정 데이터 항목을 소유하고 있는 주 소유자에 직접 연결 가능하다. 따라서 서버 노드간 원격 호출을 줄인다.


하지만 최근까지는 세 종류의 클라이언트만 있었다.


  • 모든 기능을 가진 자바 클라이언트 (L1, L2, L3)
  • 단순 파이썬 클라이언트 (L1)
  • Sunimal Rathnayake가 Google Summer of Code에서 개발한 C# 클라이언트 (L1)


이제 L1, L2, L3 모두 지원하는 핫로드 C++ 클라이언트의 6.0.0.Final 버전을 발표하려한다. 이 클라이언트는 리눅스, 유닉스, 위도우에서 컴파일 된다.

SIA와 지금까지 훌륭한 작업을 해준 Lorenzo Fili에게 특히 감사한다.

이 클라이언트가 자바 클라이언트와 동등한 기능을 갖추기 위해 아직 원격 질의와 OpenSSL을 추가하여야 한다. 이 기능들은 다음 개발 사이클에 이루어질 것이다.

한 번 다운로드 해보고 만약 도움을 주고 싶다면 깃허브의 우리 프로젝트로 오라.

원문:
Thursday, 21 November 2013, Infinispan HotRod C++ Client 6.0.0.Final

인피니스팬 6.0.0 최종버전이 나왔습니다!

인피니스팬 커뮤니티 여러분께,

인피니스팬 6.0.0  최종 릴리즈 버전인 "Infinium"을 발표합니다. 이 버전은 예전에 발표한 적과 같이 인피니스팬 최초로 아파치 라이선스 v2.0을 따르는 안정 버전이 되겠습니다.

이 버전은 다수의 안정성 확장과 버그 수정 이외에도 많이 요청되었던 기능들을 포함합니다:

  • 원격 질의 지원. 핫로드 클라이언트가 새로운 질의 DSL을 사용하여 인피니스팬 그리드에 질의를 던질 수 있습니다. 이 기능은 아파치 루씬과 구글 프로토버퍼를 기반으로 작성되었으며 이 기술들은 정보를 저장하고 언어에 중립적으로 인피니스팬 서버에 질의하기 위한 기반이 됩니다. 자바 핫로드 클라이언트는 이미 이것을 지원하기 위한 확장이 끝났고, 곧 발표될 C++ 핫로드 클라이언트도 또한 이 기능을 포함할 예정입니다. (읽기/쓰기가 먼저, 이후에 전체 질의 기능이 구현 될 예정)
  • C++ 핫로드 클라이언트.  C++ 애플리케이션이 인피니스팬 서버로부터 정보를 읽고 쓸 수 있게 되었습니다. 토폴로지(level2) 와 컨시스턴트 해시(level3)를 지원하는 (topology and consistent hash aware) 충분한 기능을 가진 핫로드 클라이언트이며 몇 일 안에 출시될 것입니다. 원격 질의와 SSL 지원 같은 기능을 다음 버전에 포함하여 자바 버전과 동등한 기능을 유지하게 될 것입니다.
  • 향상된 영속 통합. 우리는 캐시로더 API에 전반적으로 다시 손을 봤고 그 결과에 꽤 만족합니다. 인피니스팬 6.0의 새로운 영속 API(Persistence API)는 저장된 엔트리에 대한 병렬 순환(parallel iteration)을 지원하고, JSR-107 스펙에 맞춰 직렬화에 대한 오버헤드를 줄였습니다. 이는 구현을 더 이식 가능하게 합니다.
  • 더 효율적인 파일 캐시 스토어(FileCacheStore) 구현체. 이 파일 스토어는 만들어질 때부터 효율성을 염두에 두었으며 기존의 파일 스토어보다 몇 배의 빠른 성응을 냅니다. 이를 위해 비용이 드는 데 키가 메모리에 저장될 필요가 있습니다. 기여해준 칼스텐 블리스(Karsten Blees)에게 감사드립니다.
  • 불균질적 클러스터 지원. 이번 버전까지, 클러스터의 모든 멤버는 같은 만큼의 클러스터 데이터를 소유하고 있었습니다. 만약 하나의 장비가 다른 클러스터내 장비보다 더 강력할 때 이는 잘 동작하지 않았습니다. 이 새로운 기능은 특정 장비가 가지는 데이터를 평균과 비교하여 지정할 수 있도록 합니다.
  • 새로운 사용/성능 측정 통계치가 CloudTM 프로젝트 아래에서 개발되었습니다.
  • JCache(JSR-107) 구현 업그레이드. 인피니스팬 5.3.0에서 첫번째로 출시되었던 표준 캐시 지원이 1.0.0-PFD로 업그레이드 되었습니다.

이번 릴리즈에 포함된 기능과 수정된 버그 등의 완전한 리스트를 확인하려면 릴리즈 노트를 참고하세요.
이번 릴리즈의 사용자 문서는 개정되어 신규 웹사이트로 이전되었습니다. 우리는 훨씬 좋아졌다고 여기며, 여러분도 그렇게 생각하길 바랍니다.
이 릴리스는 코어 개발팀, QE팀 그리고 우리의 성장하는 커뮤니티의 지속적인 노력에 의해 5개월의 기간에 이루어졌습니다. 관련된 모두에게 깊은 감사를 드립니다!
최근 릴리즈를 찾으려면 다운로드 페이지를, 질문을 하기 위해서는 포럼이나 메일링 리스트를 확인하거나 또는 IRC에서 직접 우리를 찾으면 됩니다.

감사합니다.
애드리안(Adrian)

원문:
Tuesday, 19 November 2013, Infinispan 6.0.0.Final is out!

2013년 11월 11일 월요일

인피니스팬 아퀼리언(Arquillian) 컨테이너 1.1.0.Alpha1 릴리스

인피니스팬 사용자 여러분,

인피니스팬 아퀼리언 컨테이너의 새로운 버전이 메이븐 아티펙트(artifact)로 제이보스 메이븐 저장소에 릴리스 되었습니다. 이전 버전은 이 포스트에서 발표되었으며, 그 포스트는 제이보스 메이븐 저장소의 주소와 그 설치 방법, 인피니스팬 아퀼리언 컨테이너 자체의 주소 등의 정보를 포함하고 있습니다.

버전 5.3 부터 인피니스팬 서버가 JBoss AS 7에 기반하고 infinispan-arquillian-container라는 서브모듈이 지워질 수도 있기 때문에, 아마도 이제 우리는 이 프로젝트를 인피니스팬 아퀼리언 컨테이너 보다는 인피니스팬 아퀼리언 확장이라고 불러야 할 것 입니다.

결과적으로 인피니스팬 서버를 위한 아퀼리언 설정은 간단해졌습니다.


인피니스팬 서버를 사용한 테스트 개발

이제 arquillian.xml 파일을 작성하는 단 한가지 방법만 존재합니다.


 
    
        
            
                /path/to/infinispan/server1
                9999
                testuser
                testpassword
                clustered.xml
                -Djava.net.preferIPv4Stack=true -Djboss.node.name=node0
            
        
        
            
                /path/to/infinispan/server2
                10099
                testuser
                testpassword
                clustered.xml
                -Djava.net.preferIPv4Stack=true -Djboss.node.name=node1 -Djboss.socket.binding.port-offset=100
            
        
    


ispnHome 속성은 더이상 존재하지 않습니다. 인피니스팬 서버를 가리키는 패스는 이제 jbossHome으로 지정합니다. serverConfg 속성은 해당 서버의 설정을 지정합니다.

인피니스팬 아퀼리언 확장을 사용하여 테스트를 실행하기 위해, 아래의 의존성들을 사용합니다.
org.jboss.as:jboss-as-arquillian-container-managed:jar:7.2.0.Final:test
org.infinispan.arquillian.container:infinispan-arquillian-impl:jar:1.1.0.Alpha1:test

이제 우리의 테스트에서 서버를 실행하기 위한 설정을 마쳤습니다. 이젠 테스트를 좀 더 효과적으로 할 수 있도록 하는 약간의 추가작업을 소개합니다.


RemoteInfinispanServers

@InfinispanResource를 RemoteInfinispanServer 타입의 인스턴스 변수에 붙여서 실행되고 있는 인피니스팬 서버에 대한 참조를 여전히 주입시킬 수 있습니다.

@InfinispanResource("container1")
RemoteInfinispanServer server1;

주입 대상의 인피니스팬 서버가 여러개라면 각각의 서버를 주입하는 대신 이제 아래 코드를 사용 가능합니다.

@InfinispanResource
RemoteInfinispanServers servers;

그리고 서버 변수 위에서 .getServer(이름)을 호출하여 각각의 서버를 얻어 올 수 있습니다. 이름은 반듯이 arquillian.xml에 존재하는 컨테이너 정의와 대응하여야 합니다. 이 호출의 결과로 RemoteInfinispanServer를 얻습니다.


WithRunningServer

지금까지 사용자는 전체 테스트 묶음(mode="suite") 전이나 각각의 별도의 클래스(mode="class") 테스트 전에 인피니스팬 서버를 시작해야만 했었습니다. WithRunningServer 애노테이션은 테스트 메소드 이전에 자동으로 서버를 시작하고 이후에는 서버를 정지하게 합니다. 예를 들면,

@WithRunningServer({ "container1", "container2" })
public void testMethod() { ... }

이런 경우에 컨테이너는 arquillian.xml 파일에 mode="manual"라고 표시해서 인피니스팬 아퀼리언 확장이 자체적으로 이 서버들의 라이프사이클을 책임진다는 것에 주의하세요.

@WithRunningServer 애노테이선이 클래스에 붙을 때, 그 서버는 테스트 클래스 내의 첫번째 메소드 호출 전에 시작되고 JUnit의 @AfterClass 이벤트가 불려질 때 정지하게 됩니다.


IPv6 지원

인피니스팬 아퀼리언 확장은 이제 IPv6 상에서 실행되는 인피니스팬 서버와 동작 가능하고 이는 JMX를 통해 서버에 접속 가능하기 때문입니다.


내장모드 인피니스팬 테스트하기

인피니스팬 서버 대신 인피니스팬 라이브러리와 테스트를 실행하는 것은 지난 번 버전으로 부터 변화가 없습니다. 이것에 대해서는 이전 블로그 포스트를 읽기 바랍니다.

이 프로젝트를 한 발짝 더 가게 도와준 Michal Linhard와 Vitalii Chepeliuk에게 감사드립니다.

감사합니다.
마틴(Martin)

원문:
Tuesday, 5 November 2013, Infinispan Arquillian Container 1.1.0.Alpha1 released

2013년 10월 9일 수요일

인피니스팬 6.0.0.CR1이 나왔습니다!

인피니스팬 커뮤니티 여러분께,

인피니스팬 6.0.0 첫번째 릴리즈 후보(CR1) 버전을 기쁘게 발표합니다.

많은 분들이 릴리즈 후보버전에 대해서 알고있듯이, 이 버전은 안정화된 6.0.0 버전을 위한 다수의 버그 수정과 기능 확장을 포함하고 있습니다.

이번 릴리즈에 포함된 기능과 수정된 버그 등의 완전한 리스트를 확인하려면 릴리즈 노트를 참고하세요. 최근 릴리즈를 찾으려면 다운로드 페이지를, 질문을 하기 위해서는 포럼이나 메일링 리스트를 확인하거나 또는 IRC에서 직접 우리를 찾으면 됩니다.

관련된 분들과 기여하신 모든 분들께 감사드립니다.

윌(Will)

원문:
Tuesday, 8 October 2013, Infinispan 6.0.0.CR1 is available!

2013년 10월 4일 금요일

인피니스팬 6.0.0.Beta2가 나왔습니다!

인피니스팬 커뮤니티 여러분께,

"일찍 릴리즈하라. 자주 릴리즈하라. 그리고 고객의 말에 귀기울여라"라는 소프트웨어 개발 철학에 확신을 가지면서, 오늘 인피니스팬 6.0.0.Beta2를 릴리즈합니다. 이는 주로 첫번째 베타에서 질풍같이 기능들을 추가한 이후에 안정화를 위한 릴리즈입니다. Beta2는 핫로드 원격 클라이언트와 LevelDB 캐시 스토어와 관련한 작은 버그 수정들을 포함하고 있습니다.

이번 릴리즈에 포함된 기능과 수정된 버그 등의 완전한 리스트를 확인하려면 릴리즈 노트를 참고하세요. 최근 릴리즈를 찾으려면 다운로드 페이지를, 질문을 하기 위해서는 포럼이나 메일링 리스트를 확인하거나 또는 IRC에서 직접 우리를 찾으면 됩니다.

감사합니다.

블라디미르(Vladimir)

원문:
Friday, 27 September 2013, Infinispan 6.0.0.Beta2 is released!

------------------
역자주. 원문은  2013년 9월 27일에 작성되었습니다.

내장 및 원격 질의

인피니스팬 메일링 리스트를 받아보고 있다면, 아마 질의에 관한 새로운 개발진행에 대해 살짝 엿들었을 것이다. 새로운 DSL, 핫로드 클라이언트를 사용한 원격 질의, 구글의 프로토콜 버퍼(protobuf)에 기반한 새로운 마샬러들이 그것이고, 지금이 이것들의 베일을 제대로 벗길 때이다!

새로운 질의 DSL

인피니스팬 버전 6.0부터, 캐시된 엔트리에 대해서 단순 필터링 DSL에 기반한 질의를 수행하는 새로운 (실험적인) 방법을 제공한다. 이 새로운 DSL의 목적은 질의를 더 간단히 작성하게 하고, 기저의 질의 메커니즘을 모르게 하여 미래에 루씬 이외의 대안적인 질의 엔진을 제공 가능케 하는 동시에 여전히 같은 질의 언어/API를 사용할 수 있도록 하는 데 있다. 이전의 하이버네이트 서치와 루씬 기반의 접근은 여전히 존재하며 계속 지원될 것이다. 사실 이 새로운 DSL은 현재 그 위에서 구현되었있다. 앞으로는 맵리듀스에 기반한 인덱스를 사용하지 않는 검색이 생길 것이며, 어쩌면 다른 뛰어난 검색 기술도 가능할 것이다.

내장모드에서 DSL 기반 질의를 실행하는 것은 현재의 루씬 기반 질의를 실행하는 것과 거의 동일하다. 필요한 작업은 infinispan-query-dsl.jar와 infinispan-query.jar를 클래스패스에 넣고, 캐시의 인덱싱을 활성화 하고 캐시에 저장될 POJO에 어노테이션을 붙이는 것이 전부다.

ConfigurationBuilder cfg =newConfigurationBuilder();
cfg.indexing().enable();

DefaultCacheManager cacheManager =newDefaultCacheManager(cfg.build());

Cache cache = cacheManager.getCache();

다른 방법으로, 사용자 가이드에서 설명했듯이 인덱싱은 (그리고 다른 모든 것도) XML을 사용해 설정 가능하다. 그래서 여기서는 자세히 들어가지 않는다.
하이버네이트 서치 어노테이션을 붙인 엔티티는 아래와 같을 것이다.

import org.hibernate.search.annotations.*;
...

@Indexed
public class User {

    @Field(store = Store.YES, analyze = Analyze.NO)
    private String name;

    @Field(store = Store.YES, analyze = Analyze.NO, indexNullAs = Field.DEFAULT_NULL_TOKEN)
    private String surname;

    @IndexedEmbedded(indexNullAs = Field.DEFAULT_NULL_TOKEN)
    private List addresses;

    // .. the rest omitted for brevity
}

DSL 기반 질의를 실행하기 위해 아래처럼 (캐시 범위의) SearchManager로부터 QueryFactory 얻고 질의를 만든다.

import org.infinispan.query.Search;
import org.infinispan.query.dsl.QueryFactory;
import org.infinispan.query.dsl.Query;
...

QueryFactory qf = Search.getSearchManager(cache).getQueryFactory();

Query q = qf.from(User.class)
    .having("name").eq("John")
    .toBuilder().build();

List list = q.list();

assertEquals(1, list.size());
assertEquals("John", list.get(0).getName());
assertEquals("Doe", list.get(0).getSurname());

이것이 전부이다. DSL이 실제로 무엇을 할 수 있는지에 관한 호기심을 불러 일으켰으리라 생각된다. FilterConditionEndContext에서 지원 필터 동작 리스트를 확인할 수 있다. 하위 조건들을 포함하여 불린 연산으로 복수개의 조건을 조합하는 것도 역시 가능하다.

Query q = qf.from(User.class)
    .having("name").eq("John")
    .and().having("surname").eq("Doe")
    .and().not(qf.having("address.street").like("%Tanzania%").or().having("address.postCode").in("TZ13", "TZ22"))
    .toBuilder().build();

이 DSL은 상당히 멋지고, 사용자 피드백에 기반하여 미래에 계속 확장될 것이다. 이는 또한 결과 페이징, 소팅, 프로젝션, 내장 객체에 대한 지원을 제공하며, 모두 QueryDslConditionsTest에서 확인 가능하다. 적절한 사용자 가이드가 나오기 전까지는 이 클래스를 살펴 보기를 권한다. 그러나 이것은 관계형 데이터베이스가 아니다. 모든 질의는 단일 대상 엔티티 (그리고 그것의 내장 엔티티들) 범위에서 쓰여진다는 것을 명심하라. 조인은 (아직) 없고, 상관 하위질의도 없고, 그룹핑이나 aggregation도 없다.

좀 더 들어가서, 아마도 이 새 DSL에 관해서 가장 흥미로운 것은 핫로드 클라이언트를 통해 원격으로 사용하는 것일것이다. 이 도약을 위해서 먼저 캐시 엔트리를 저장하고 그것들을 마샬링하는 공통 형식을 채택했어야만 했다. 이는 또한 사용 언어간 제약에 없고, 객체 스키마의 진화를 지원할 만큼 충분히 탄탄하여야 한다. 하지만, 아마도 무엇보다 이 형식은 단지 불명확한 blob이기 보다는 하나의 스키마를 가져야 했다. 그렇지 않으면 인덱싱과 검색이 의미없다. 프로토콜 버퍼로 들어가보자.


프로토콜 버퍼 마샬러

자바 핫로드 클라이언트를 사용하기 위해 RemoteCacheManager를 설정하는 것은 간단하다.

import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
...

ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
clientBuilder.addServer()
    .host("127.0.0.1").port(11234)
    .marshaller(new ProtoStreamMarshaller());

아래 순서대로 하면 User 인스턴스를 프로토콜 버퍼 형식으로 원격 캐시에 저장하고 불러올 수 있다.

1. 사용자 엔티티를 위한 Protobuf 타입을 .proto파일에 선언하고 컴파일하여 .protobin 바이너리 기술자(binary descriptor)로 만든다.
2. 그 바이너리 기술자를 아래와 같이 RemoteCacheManager의 ProtoStreamMarshaller 인스턴스에 등록한다.

ProtoStreamMarshaller.getSerializationContext(remoteCacheManager)
    .registerProtofile("my-test-schema.protobin");

3. 엔티티마다 마샬러를 등록한다.

ProtoStreamMarshaller.getSerializationContext(remoteCacheManager)
    .registerMarshaller(User.class, new UserMarshaller());

2, 3번 단계는 Protostream 라이브러리가 동작하는 방법과 매우 가깝다. 그것은 아주 간단하지만 여기서 자세히 살펴볼 수는 없다. UserMarshaller 예제를 살펴보는 것이 많은 도움이 될 것이다.

사용자 객체를 프로토콜 버퍼 형식으로 유지하는 것은 다른 언어로 쓰여진 클라이언트들이 그것들을 사용할 수 있다는 데에 이점이 있다. 이것이 흥미롭게 들리지 않는 사람이라도 그것들이 쉽게 인덱싱 될 수 있다는 사실은 매력적이라고 생각할 것이다.


핫로드 클라이언트를 통한 원격 질의

RemoteCacheManagery를 위에서 설명한대로 설정하고, 다음 단계에서 원격 질의를 활성화 한다.

1. DSL jar를 클라이언트의 클래스패스에, infinispan-remote-query-server.jar를 서버의 클래스패스에 그리고 infinispan-remote-query-client.jar를 양쪽에 추가한다.
2. 캐시 설정에서 인덱싱을 활성화 한다. 내장모드도 동일하다.
3. 서버에서 (EmbeddedCacheManager 마다 하나의 인스턴스가 존재하는) ProtobufMetadataManager MBean의 registerProtofile 메소드를 사용하여 protobuf 바이너리 기술자를 등록한다.

캐시안에 들어온 모든 데이터는 엔티티에 하이버네이트 서치 어노테이션을 붙이지 않고 인덱싱 된다. 사실 이 클래스들은 자바 클라이언트에만 의미가 있으며 서버에는 존재하지도 않는다.

핫로드 클라이언트를 통해 질의를 실행하는 것은 내장모드와 아주 비슷하다. DSL은 사실 같다. 단지 작은 차이점은 QueryFactory를 얻는 방법이다.

import org.infinispan.client.hotrod.Search;
import org.infinispan.query.dsl.QueryFactory;
import org.infinispan.query.dsl.Query;
...

remoteCache.put(2, new User("John", "Doe", 33));

QueryFactory qf = Search.getQueryFactory(remoteCache);

Query query = qf.from(User.class)
    .having("name").eq("John")
    .toBuilder().build();

List list = query.list();
assertEquals(1, list.size());
assertEquals("John", list.get(0).getName());
assertEquals("Doe", list.get(0).getSurname());

이것보숑! 오늘의 여행일정이 끝났다. 인피니스팬 질의를 계속 눈여겨 보며, 당신의 커맨트를 공유해달라.

원문:
Thursday, 26 September 2013, Embedded and remote queries in Infinispan 6.0.0.Beta1