Skip to content

Commit

Permalink
Add Tarantool database
Browse files Browse the repository at this point in the history
http://tarantool.org and https://github.com/tarantool/tarantool
In "mail.ru" we wrote and widely use Tarantool key-value database.
It's key properties include:

* Defferent index types with iterators:
    - HASH (the fastest)
    - TREE (range and ordered retreival)
    - BITSET (bit mask search)
    - RTREE (geo search)
* multipart keys for HASH and TREE indexes
* Data persistence with by Write Ahead Log (WAL) and snapshots.
* asynchronous master-master replication, hot standby.
* coroutines and async. IO are used to implement high-performance lock-free access to data.
    - socket-io/file-io with yeilds from lua
* stored procedures in Lua (Using LuaJIT)
* supports plugins written on C/C++ (Have two basic plugins for working with MySQL and PostgreSQL)
* Authentication and access control

Move 'distribution target' to the end (it's needed for .jar to be in the .tar.gz)
  • Loading branch information
bigbes committed Jun 11, 2015
1 parent 076b802 commit bf4c4e5
Show file tree
Hide file tree
Showing 7 changed files with 318 additions and 2 deletions.
3 changes: 2 additions & 1 deletion bin/ycsb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ DATABASES = {
"cassandra-8" : "com.yahoo.ycsb.db.CassandraClient8",
"cassandra-10" : "com.yahoo.ycsb.db.CassandraClient10",
"cassandra-cql": "com.yahoo.ycsb.db.CassandraCQLClient",
"couchbase" : "com.yahoo.ycsb.db.CouchbaseClient",
"dynamodb" : "com.yahoo.ycsb.db.DynamoDBClient",
"elasticsearch": "com.yahoo.ycsb.db.ElasticSearchClient",
"gemfire" : "com.yahoo.ycsb.db.GemFireClient",
Expand All @@ -47,8 +48,8 @@ DATABASES = {
"nosqldb" : "com.yahoo.ycsb.db.NoSqlDbClient",
"orientdb" : "com.yahoo.ycsb.db.OrientDBClient",
"redis" : "com.yahoo.ycsb.db.RedisClient",
"tarantool" : "com.yahoo.ycsb.db.TarantoolClient"
"voldemort" : "com.yahoo.ycsb.db.VoldemortClient",
"couchbase" : "com.yahoo.ycsb.db.CouchbaseClient"
}

OPTIONS = {
Expand Down
4 changes: 3 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
<thrift.version>0.8.0</thrift.version>
<hypertable.version>0.9.5.6</hypertable.version>
<couchbase.version>1.1.8</couchbase.version>
<tarantool.version>1.6.1-SNAPSHOT</tarantool.version>
</properties>

<modules>
Expand All @@ -85,10 +86,11 @@
<module>orientdb</module>
<module>redis</module>
<module>voldemort</module>
<module>distribution</module>
<!--<module>mapkeeper</module>-->
<!--module>nosqldb</module-->
<module>couchbase</module>
<module>tarantool</module>
<module>distribution</module>
</modules>

<build>
Expand Down
62 changes: 62 additions & 0 deletions tarantool/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Tarantool

## Introduction

Tarantool is a NoSQL In-Memory database.
It's distributed under BSD licence and is hosted on [github][tarantool-github].

Tarantool features:

* Defferent index types with iterators:
- HASH (the fastest)
- TREE (range and ordered retreival)
- BITSET (bit mask search)
- RTREE (geo search)
* multipart keys for HASH and TREE indexes
* Data persistence with by Write Ahead Log (WAL) and snapshots.
* asynchronous master-master replication, hot standby.
* coroutines and async. IO are used to implement high-performance lock-free access to data.
- socket-io/file-io with yeilds from lua
* stored procedures in Lua (Using LuaJIT)
* supports plugins written on C/C++ (Have two basic plugins for working with MySQL and PostgreSQL)
* Authentication and access control

## Quick start

This section descrives how to run YCSB against a local Tarantool instance

### 1. Start Tarantool

First, clone Tarantool from it's own git repo and build it (described in our [README.md][tarantool-readme]):

cp YCSB/tarantool/config/tarantool-tree.lua <vardir>/tarantool.lua
cp TNT/src/box/tarantool_box <vardir>
cd <vardir>
./tarantool_box tarantool.lua

OR you can simply download ans install a binary package for your GNU/Linux or BSD distro from http://tarantool.org/download.html

### 2. Run YCSB

Now you are ready to run! First, load the data:

./bin/ycsb load tarantool -s -P workloads/workloada

Then, run the workload:

./bin/ycsb run tarantool -s -P workloads/workloada

See the next section for the list of configuration parameters for Tarantool.

## Tarantool Configuration Parameters

#### 'tarantool.host' (default : 'localhost')
Which host YCSB must use for connection with Tarantool
#### 'tarantool.port' (default : 3301)
Which port YCSB must use for connection with Tarantool
#### 'tarantool.space' (default : 1024)
(possible values: 0 .. 255)
Which space YCSB must use for benchmark Tarantool

[tarantool-github]: https://github.com/tarantool/tarantool/
[tarantool-readme]: https://github.com/tarantool/tarantool/blob/master/README.md
12 changes: 12 additions & 0 deletions tarantool/config/tarantool-hash.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
box.cfg {
listen=3303,
logger="tarantool.log",
log_level=5,
logger_nonblock=true,
wal_mode="none",
pid_file="tarantool.pid"
}

box.schema.space.create("ycsb", {id = 1024})
box.space.ycsb:create_index('primary', {type = 'hash', parts = {1, 'STR'}})
box.schema.user.grant('guest', 'read,write,execute', 'universe')
12 changes: 12 additions & 0 deletions tarantool/config/tarantool-tree.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
box.cfg {
listen=3303,
logger="tarantool.log",
log_level=5,
logger_nonblock=true,
wal_mode="none",
pid_file="tarantool.pid"
}

box.schema.space.create("ycsb", {id = 1024})
box.space.ycsb:create_index('primary', {type = 'tree', parts = {1, 'STR'}})
box.schema.user.grant('guest', 'read,write,execute', 'universe')
59 changes: 59 additions & 0 deletions tarantool/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>com.yahoo.ycsb</groupId>
<artifactId>root</artifactId>
<version>0.2.0-SNAPSHOT</version>
</parent>

<artifactId>tarantool-binding</artifactId>
<name>Tarantool DB Binding</name>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>org.tarantool</groupId>
<artifactId>connector</artifactId>
<version>${tarantool.version}</version>
</dependency>
<dependency>
<groupId>com.yahoo.ycsb</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

<repositories>
<repository>
<id>dgreenru-repo</id>
<name>dgreenru repository</name>
<url>http://dgreenru.github.com/repo/</url>
</repository>
</repositories>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven.assembly.version}</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
168 changes: 168 additions & 0 deletions tarantool/src/main/java/com/yahoo/ycsb/db/TarantoolClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package com.yahoo.ycsb.db;

import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.Arrays;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.HashMap;
import java.util.Properties;

import java.io.IOException;

import org.tarantool.TarantoolConnection16;
import org.tarantool.TarantoolConnection16Impl;
import org.tarantool.TarantoolException;
import org.tarantool.CommunicationException;

import com.yahoo.ycsb.DB;
import com.yahoo.ycsb.DBException;
import com.yahoo.ycsb.ByteIterator;
import com.yahoo.ycsb.StringByteIterator;

public class TarantoolClient extends DB {

public static final String HOST_PROPERTY = "tarantool.host";
public static final String PORT_PROPERTY = "tarantool.port";
public static final String SPACE_PROPERTY = "tarantool.space";

public static final String DEFAULT_HOST = "localhost";
public static final int DEFAULT_PORT = 3301;
public static final int DEFAULT_SPACE = 1024;

private static final Logger log = Logger.getLogger(TarantoolClient.class.getName());
private TarantoolConnection16Impl connection;
private int spaceNo;

public void init() throws DBException {
Properties props = getProperties();

int port = DEFAULT_PORT;
String portString = props.getProperty(PORT_PROPERTY);
if (portString != null) {
port = Integer.parseInt(portString);
}

String host = props.getProperty(HOST_PROPERTY);
if (host == null) {
host = DEFAULT_HOST;
}

spaceNo = DEFAULT_SPACE;
String spaceString = props.getProperty(SPACE_PROPERTY);
if (spaceString != null) {
spaceNo = Integer.parseInt(spaceString);
}

try {
this.connection = new TarantoolConnection16Impl(host, port);
}
catch (Exception exc) {
System.err.println("Can't init Tarantool connection:" + exc.toString());
exc.printStackTrace();
return;
}
}

public void cleanup() throws DBException{
this.connection.close();
}

@Override
public int insert(String table, String key, HashMap<String, ByteIterator> values) {
int j = 0;
String[] tuple = new String[1 + 2 * values.size()];
tuple[0] = key;
for (Map.Entry<String, ByteIterator> i: values.entrySet()) {
tuple[j + 1] = i.getKey();
tuple[j + 2] = i.getValue().toString();
j += 2;
}
try {
this.connection.insert(this.spaceNo, tuple);
} catch (TarantoolException e) {
e.printStackTrace();
return 1;
}
return 0;
}

private HashMap<String, ByteIterator> tuple_convert_filter (List<String> input,
Set<String> fields) {
HashMap<String, ByteIterator> result = new HashMap<String, ByteIterator>();
if (input == null)
return result;
for (int i = 1; i < input.toArray().length; i += 2)
if (fields == null || fields.contains(input.get(i)))
result.put(input.get(i), new StringByteIterator(input.get(i+1)));
return result;
}

@Override
public int read(String table, String key, Set<String> fields,
HashMap<String, ByteIterator> result) {
try {
List<String> response;
response = this.connection.select(this.spaceNo, 0, Arrays.asList(key), 0, 1, 0);
result = tuple_convert_filter(response, fields);
return 0;
} catch (TarantoolException e) {
e.printStackTrace();
return 1;
} catch (IndexOutOfBoundsException e) {
return 1;
}
}

@Override
public int scan(String table, String startkey,
int recordcount, Set<String> fields,
Vector<HashMap<String, ByteIterator>> result) {
List<String> response;
try {
response = this.connection.select(this.spaceNo, 0, Arrays.asList(startkey), 0, recordcount, 6);
} catch (TarantoolException e) {
e.printStackTrace();
return 1;
}
HashMap<String, ByteIterator> temp = tuple_convert_filter(response, fields);
if (!temp.isEmpty())
result.add((HashMap<String, ByteIterator>) temp.clone());
return 0;
}

@Override
public int delete(String table, String key) {
try {
this.connection.delete(this.spaceNo, Arrays.asList(key));
} catch (TarantoolException e) {
e.printStackTrace();
return 1;
} catch (IndexOutOfBoundsException e) {
return 1;
}
return 0;
}
@Override
public int update(String table, String key,
HashMap<String, ByteIterator> values) {
int j = 0;
String[] tuple = new String[1 + 2 * values.size()];
tuple[0] = key;
for (Map.Entry<String, ByteIterator> i: values.entrySet()) {
tuple[j + 1] = i.getKey();
tuple[j + 2] = i.getValue().toString();
j += 2;
}
try {
this.connection.replace(this.spaceNo, tuple);
} catch (TarantoolException e) {
e.printStackTrace();
return 1;
}
return 0;

}
}

0 comments on commit bf4c4e5

Please sign in to comment.