Tag Archives: Kundera

[NoSQL/Cassandra] Kundera에 대한 간략한 소개

Introduction

Kundera는 JPA 2.0을 준수하는 NoSQL데이터저장소용 객체-데이터저장소 매핑 라이브러리입니다. 현재를 기준으로 관계형 데이터베이스와 함께 Cassandra, HBase, MongoDB를 지원합니다. Kundera는 NoSQL 데이터베이스를 간단하고 재밌게 다룰수 있도록 만들어 줍니다. Kundera는 이미 존재하는 다른 클라이언트 라이브러리들을 또 만든것이 아닙니다. 오히려 기존의 라이브러리들을 사용하여 그것들에 좀 더 추가하고 API들을 래핑하여 개발자로 하여금 불필요한 코드를 제거하여 정리되고 깔끔한 코드가 되도록 하여주며 코드의 퀄리티를 높여줍니다. 이런 모든것들이 생산성을 높여줍니다.

Kundera는 교차-데이터저장소 퍼시스턴스(지속성?)를 제공합니다. 이것은 한번의 메소드 호출로 다른 데이터 저장소에 엔티티들을 저장하고 가져올수 있음을 뜻합니다.

Kundera는 현재 트랜젝션을 관리할 수 없습니다. 이런 이유로 개발자들은 반드시 그들이 개발중인 어플리케이션의 원자성에 대한 보장을 할 수 있도록 책임감을 가져야 합니다.

Kundera는 JPA 2.0에 호환됩니다. 이것은 엄격하게 JPA 어노테이션을 사용하여 객체를 데이터저장소의 테이블에 집어넣을 수 있습니다. (테이블이라고 말했지만 테이블이라는 용어는 RDB에서 사용되는 용어이며 NoSQL데이터베이스에서는 일반적으로 컬럼패밀리라는 용어를 사용합니다)

Basic Concepts

* Rules

– 엔티티 클래스는 반드시 @Entity 어노테이션을 사용해야 합니다.

– 엔티티 클래스는 반드시 테이블명 name과 스키마명 schema 속성을 포함한 @Table 어노테이션을 사용해야 합니다. (테이블과 스키마는 데이터저장소의 종류에 따라 다른 의미를 가지고 있습니다.)

– 엔티티를 NoSQL저장소에 저장하려면 스키마명은 [스키마 이름]@[퍼시스턴스 유닛(PU) 이름]의 형태를 지켜야 합니다.

– 엔티티 클래스는 반드시 인자가 하나도 없는 기본 생성자를 가져야 합니다.

– 각각의 엔티티는 @Id 어노테이션을 가진 필드(멤버변수)가 있어야 합니다. 이 필드는 로우Key로 사용됩니다.

@Id 필드는 반드시 String타입이어야 합니다.

@Id 필드는 반드시 엔티티당 한개만 존재해야 합니다.

– 모든 필드에는 @Embedded@ElementCollection을 포함할 수 있습니다. (Cassandra의 Super Column(s), MongoDB의 Nested Document(s))

@Embedded 또는 @ElementCollection 어노테이션이 붙은 필드의 클래스 정의에는 반드시 @Embeddable 어노테이션을 사용해야 합니다. (JPA방법임!)

– 관계형 엔티티는 다른 엔티티클래스와의 관계를 표현하는 @OneToOne, @OneToMany 어노테이션을 사용합니다. (위의 룰들을 적용한 상태에서) 이렇게 정의된 엔티티들은 각각의 다른 테이블에 저장될 것이며 외래키는 Kundera에 의해 관리됩니다.

Annotations

Kundera는 JPA 어노테이션셋에서 그 어떤 새로운 어노테이션도 추가하지 않았습니다. 좀 더 정확히 말하자면 이미 존재하고 있는것들에 새로운 의미를 부여하였습니다.

– 일반적인 JPA의 방법을 사용하기 때문에 Kundera를 시작하는것은 매우 적은 시간이 소요됩니다.

– 모든 데이터 저장소에 대해 일관적인 어노테이션을 사용합니다.

– 다음은 저장소에 따라 어노테이션의 용어 뜻이 어떻게 달라지는지 보여주는 예시입니다.

사용자 삽입 이미지

Getting Started in 5 minutes

지금부터 Cassandra에 데이터를 보관하는 예제를 수행해 보도록 하겠습니다. 하지만 당신이 좋아하는 다른 데이터 저장소(Kundera가 현재 지원하는 HBase, MongoDB, RDB)를 사용해도 상관없습니다.

카산드라 서버 세팅하기

우리는 이미 당신이 카산드라 서버를 가지고 있고 그것을 당신의 머신에서 적절히 구동중에 있다고 가정하고 이부분을 깊게 관여하지 않을 것입니다. 만약에 아니라면 [여기 좋은 링크]에서 도움이 될만한 정보를 찾으시기 바랍니다(하지만 지금 제 블로그에도 좋은 정보 많습니다. Cassandra로 검색해 보세욧!). 이 예제는 당신의 카산드라 서버가 0.8.x버전이라 가정하고 진행됩니다.

Kundera Jar 파일 다운로드 후 프로젝트에 포함시키기

당신은 [이곳]에서 Kundera-dependency.jar 파일은 다운로드 할 수 있습니다. 다운받아 프로젝트에 포함시키도록 합니다. 또는 아래의 코드를 당신의 maven 프로젝트 pom.xml에 추가하여 maven 저장소로 부터 다운받도록 할 수도 있습니다.
[code]<project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd”>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.impetus.poc</groupId>
  <artifactId>KunderaPOC</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>KunderaPOC</name>
  <url>http://maven.apache.org</url>
  <repositories>
    <repository>
      <id>kundera-missing</id>
      <name>Kundera Public Missing Resources Repository</name>
      <url>http://kundera.googlecode.com/svn/maven2/maven-missing-resources</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>com.impetus.client</groupId>
      <artifactId>kundera-cassandra</artifactId>
      <version>2.0.4</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>[/code]

persistence.xml 파일 작성하기

다음의 내용을 작성하여 당신의 classpath안의 META-INF 폴더 안에 넣어주도록 합니다. 아래 설정에는 eh-cache에 대한 설정이 있는데 실제 원본 문서안에는 존재하지 않는군요. 이상하긴 하네요;
[code]<persistence xmlns=”http://java.sun.com/xml/ns/persistence” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  xsi:schemaLocation=”http://java.sun.com/xml/ns/persistence
  http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd”
  version=”2.0″>
  <persistence-unit name=”cassandra_pu”>
    <provider>com.impetus.kundera.KunderaPersistence</provider>    
    <properties>      
      <property name=”kundera.nodes” value=”localhost”/>
      <property name=”kundera.port” value=”9160″/>
      <property name=”kundera.keyspace” value=”KunderaExamples”/>
      <property name=”kundera.dialect” value=”cassandra”/>
      <property name=”kundera.client” value=”Pelops”/>
      <property name=”kundera.cache.provider.class” value=”com.impetus.kundera.cache.ehcache.EhCacheProvider”/>
            <property name=”kundera.cache.config.resource” value=”/ehcache-test.xml”/>        
    </properties>    
  </persistence-unit>
</persistence>[/code]

엔티티 클래스 작성하기

[code]import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = “users”, schema = “KunderaExamples@cassandra_pu”)
public class User
{
    @Id
    private String userId;
   
    @Column(name=”first_name”)
    private String firstName;
   
    @Column(name=”last_name”)
    private String lastName;
   
    @Column(name=”city”)
    private String city;    

    public User()
    {
    }

    public String getUserId()
    {
        return userId;
    }
    public void setUserId(String userId)
    {
        this.userId = userId;
    }
    public String getFirstName()
    {
        return firstName;
    }
    public void setFirstName(String firstName)
    {
        this.firstName = firstName;
    }
    public String getLastName()
    {
        return lastName;
    }
    public void setLastName(String lastName)
    {
        this.lastName = lastName;
    }
    public String getCity()
    {
        return city;
    }
    public void setCity(String city)
    {
        this.city = city;
    }
}[/code]

결정적인 순간!

Cassandra에서 Keyspace와 Column Family를 생성합니다.
[code]amresh@impetus-ubuntu:/usr/local/apache-cassandra-0.8.2/bin$ ./cassandra-cli –host localhost –port 9160
Connected to: “Test Cluster” on localhost/9160
Welcome to the Cassandra CLI.
Type ‘help;’ or ‘?’ for help.
Type ‘quit;’ or ‘exit;’ to quit.
[default@unknown]create keyspace KunderaExamples;
[default@unknown]use KunderaExamples;
[default@KunderaExamples]create column family users
  with comparator=UTF8Type
  and default_validation_class=UTF8Type
  and key_validation_class=UTF8Type;

81852270-2374-11e1-0000-242d50cf1fdd
Waiting for schema agreement…
… schemas agree across the cluster[/code]

아래의 코드를 실행해 봅시다.

만약에 어떠한 에러가 발생한다면 트러블슈팅 섹션을 확인해 보도록 합니다.
[code]import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class KunderaExample
{
    public static void main(String[] args)
    {
        User user = new User();
        user.setUserId(“0001”);
        user.setFirstName(“John”);
        user.setLastName(“Smith”);
        user.setCity(“London”);
       
        EntityManagerFactory emf =
          Persistence.createEntityManagerFactory(“cassandra_pu”);
        EntityManager em = emf.createEntityManager();
       
        em.persist(user);
        em.close();    
        emf.close();    
    }
}[/code]

cassandra-cli를 이용하여 저장된 데이터 확인하기

[code][default@unknown] use KunderaExamples;
Authenticated to keyspace: KunderaExamples
[default@KunderaExamples] list users;
Using default limit of 100
——————-
RowKey: 0001
=> (column=city, value=London, timestamp=1323551942371)
=> (column=first_name, value=John, timestamp=1323551942371)
=> (column=last_name, value=Smith, timestamp=1323551942371)

1 Row Returned.[/code]

Kundera 다운로드 받으러 가기

링크 : https://github.com/impetus-opensource/Kundera/wiki/Download-Kundera
참고 : https://github.com/impetus-opensource/Kundera/wiki/

[NoSQL/Java] Cassandra 클라이언트 퍼포먼스 비교 (Pelops/Hector/Kundera)

Java용으로 쓸만한 Cassandra 클라이언트 라이브러리를 찾다보니 대충 Pelops, Hector, Kundera정도로 나뉘어 지는것 같더군요. 셋중에 무엇이 가장 좋은가를 놓고 비교해 보자면 다양한 결론이 나오겠지만 Kundera에서 자체적으로 내놓은 퍼포먼스 테스트 결과가 있습니다. 퍼포먼스만 달랑 놓고 보면 Kundera가 가장 떨어지는 결과를 보여주니 일부러 거짓말 하는 데이터는 아닌것 같아 보입니다.

Kundera Performance 발번역

Kundera의 퍼포먼스를 Hector / Pelops와 비교해 보았습니다. 왜 Hector / Pelops인가요? Kundera는 데이터 저장소에 객체를 매핑해주는 툴이고 Hector / Pelops는 하이 레벨의 Cassandra 클라이언트입니다. 그렇기 때문에 이 비교는 논란이 될 수 있습니다. 이 비교의 의도는 Kundera 가 추가적으로 제공하는 매핑이나 다른 멋진 기능들의 오버헤드가 얼마나 되는지 계산해 보기 위함입니다.

Kundera – Cassandra는 Lucene기반의 인덱싱을 제공하며 그렇기 때문에 Hector/Pelops가 할수 있는 것들외에 추가적인 작업이 가능합니다. 그러므로 테스트는 이 Lucene인덱싱을 사용할때와 안할때 두가지 시나리오를 가지고 진행됩니다. 전자는 이 추가적인 인덱싱 기능을 사용하지 않으므로 비교해볼만한 상대가 될지 모르겠지만 후자의 경우에는 인덱싱을 내장 지원하기 때문에 비교대상이라 보기 어려운 퍼포먼스를 보여주긴 합니다.

Kundera Without Indexing Support

Bulk Load:

Number Of Records
(Single Thread)
Pelops Time
(in ms)
Hector Time
(in ms)
Kundera
(in ms)
1 22 56 82
1000 550 666 925
4000 1791 1928 2952
40000 10533 10645 12392
100000 23832 24675 25994
1000000 221154 229619 236242

Concurrent Load:

Number Of Threads
(1 record)
Pelops Time
(in ms)
Hector Time
(in ms)
Kundera
(in ms)
10 53 57 80
100 232 259 250
1000 1560 1443 1718
10000 9120 8514 10127
40000 28869 28330 29506
50000 36454 34823 36336
100000 68586 65513 69513

Concurrent Load + Bulk Load:

Number Of Threads
(1000 rec/ thread)
Pelops Time
(in ms)
Hector Time
(in ms)
Kundera
(in ms)
10 3968 4434 5085
100 21560 22329 25274
1000 227232 207834 226541

Kundera With Indexing Support

Bulk Load:

Number Of Records
(Single Thread)
Pelops Time
(in ms)
Hector Time
(in ms)
Kundera
(in ms)
1 25 40 93
1000 677 957 1719
4000 2131 2429 3901
40000 13009 13075 22158
100000 28884 30097 44876
1000000 256986 262067 375137

Concurrent Load:

Number Of Threads
(1 record)
Pelops Time
(in ms)
Hector Time
(in ms)
Kundera
(in ms)
10 53 56 118
100 232 281 552
1000 1560 1823 2762
10000 9120 9776 14104
40000 28869 32331 39549
50000 36454 37172 50099
100000 68586 74304 95410

Concurrent Load + Bulk Load:

Number Of Threads
(1000 rec/ thread)
Pelops Time
(in ms)
Hector Time
(in ms)
Kundera
(in ms)
10 4343 4738 9546
100 26010 24619 35196
1000 227232 219247 308975


위의 단순한 결과들로만 보면 Kundera는 모든 면에서 다른 라이브러리에 비교해 뒤쳐지는 속도를 보여줍니다. 하지만 Kundera는 Lucene인덱싱 POJO에 직접적인 데이터 매핑등 사용상에 많은 장점을 가지고 있습니다. 대충 검색해 보았을때는 Kundera는 Full-Text 검색도 지원한다고 합니다. 사실상 NoSQL에서 지원하기 어려운 점들입니다. 사용해 보진 않았지만 다양한 기능을 제공하는것으로 보여집니다.

참고: https://github.com/impetus-opensource/Kundera/wiki/Kundera-Performance