[travis] Added Riak service for testing purposes.

[riak] Added test unit.
[riak] Set eventual consistency as default in both README.md and riak.properties file, as strong consistency it's not the main model adopted by the db (check http://docs.basho.com/riak/kv/2.1.4/developing/app-guide/strong-consistency/ for further info).
[riak] Fixed getFields() function by transforming it into createResultHashMap(). This function creates the HashMap to give as result appropriately.
[riak] Removed scan transaction support for strong consistency model. 2i search is not allowed for this model, neither there is a suitable search mean to use to achieve a proper scan transaction.
[riak] Done minor fixes to code and comments.
This commit is contained in:
nygard_89 2016-04-13 23:15:27 +02:00
Родитель 776ec892ff
Коммит d209175963
6 изменённых файлов: 87 добавлений и 67 удалений

Просмотреть файл

@ -30,6 +30,7 @@ script: mvn test -q
# Services to start for tests.
services:
- mongodb
- riak
# Use the Container based infrastructure.

Просмотреть файл

@ -19,7 +19,7 @@ LICENSE file.
Riak KV Client for Yahoo! Cloud System Benchmark (YCSB)
--------------------------------------------------------
The Riak KV YCSB client is designed to work with the Yahoo! Cloud System Benchmark (YCSB) project (https://github.com/brianfrankcooper/YCSB) to support performance testing for the 2.0.X line of the Riak KV database.
The Riak KV YCSB client is designed to work with the Yahoo! Cloud System Benchmark (YCSB) project (https://github.com/brianfrankcooper/YCSB) to support performance testing for the 2.x.y line of the Riak KV database.
Creating a <i>bucket type</i> to use with YCSB
----------------------------
@ -33,7 +33,14 @@ storage_backend = leveldb
```
Create a bucket type named "ycsb"<sup id="a1">[1](#f1)</sup> by logging into one of the nodes in your cluster.
Then, if you want to use the <i>strong consistency model</i> (default), you have to follow the next two steps.
Then, if you want to use the <i>eventual consistency model</i> (default), you have to follow the next two steps.
```
riak-admin bucket-type create ycsb '{"props":{"allow_mult":"false"}}'
riak-admin bucket-type activate ycsb
```
If instead you want to use the <i>strong consistency model</i> implemented in Riak, then type:
1) In every `riak.conf` file, search for the `##strong_consistency=on` line and uncomment it. It is important that you do this <b>before you start your cluster</b>!
@ -43,14 +50,7 @@ Then, if you want to use the <i>strong consistency model</i> (default), you have
riak-admin bucket-type create ycsb '{"props":{"allow_mult":"false","consistent":true}}'
riak-admin bucket-type activate ycsb
```
If instead you want to use the <i>eventual consistency model</i> implemented in Riak, then type:
```
riak-admin bucket-type create ycsb '{"props":{"allow_mult":"false"}}'
riak-admin bucket-type activate ycsb
```
Note that you may want to specify the number of replicas to create for each object. To do so, you can add `"n_val":N` to the list of properties shown above (by default `N` is set to 3).
Riak KV configuration parameters

Просмотреть файл

@ -18,36 +18,42 @@ LICENSE file.
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.yahoo.ycsb</groupId>
<artifactId>binding-parent</artifactId>
<version>0.9.0-SNAPSHOT</version>
<relativePath>../binding-parent</relativePath>
</parent>
<parent>
<groupId>com.yahoo.ycsb</groupId>
<artifactId>binding-parent</artifactId>
<version>0.9.0-SNAPSHOT</version>
<relativePath>../binding-parent</relativePath>
</parent>
<artifactId>riak-binding</artifactId>
<name>Riak KV Binding</name>
<packaging>jar</packaging>
<artifactId>riak-binding</artifactId>
<name>Riak KV Binding</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.basho.riak</groupId>
<artifactId>riak-client</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>com.yahoo.ycsb</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.collections</groupId>
<artifactId>google-collections</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>com.basho.riak</groupId>
<artifactId>riak-client</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>com.yahoo.ycsb</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.collections</groupId>
<artifactId>google-collections</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Просмотреть файл

@ -48,7 +48,7 @@ import static com.yahoo.ycsb.db.riak.RiakUtils.getKeyAsLong;
import static com.yahoo.ycsb.db.riak.RiakUtils.serializeTable;
/**
* Riak KV 2.0.x client for YCSB framework.
* Riak KV 2.x.y client for YCSB framework.
*
*/
public final class RiakKVClient extends DB {
@ -90,6 +90,9 @@ public final class RiakKVClient extends DB {
e.printStackTrace();
}
// For testing purposes.
this.setProperties(propsPF);
hosts = propsPF.getProperty(HOST_PROPERTY).split(",");
port = Integer.parseInt(propsPF.getProperty(PORT_PROPERTY));
bucketType = propsPF.getProperty(BUCKET_TYPE_PROPERTY);
@ -227,7 +230,8 @@ public final class RiakKVClient extends DB {
return Status.ERROR;
}
result.put(key, getFields(fields, response));
// Create the result HashMap.
createResultHashMap(fields, response, result);
return Status.OK;
}
@ -236,6 +240,8 @@ public final class RiakKVClient extends DB {
* Perform a range scan for a set of records in the database. Each field/value pair from the result will be stored in
* a HashMap.
* Note: The scan operation requires the use of secondary indexes (2i) and LevelDB.
* IMPORTANT NOTE: the 2i queries DO NOT WORK in conjunction with strong consistency (ref: http://docs.basho
* .com/riak/kv/2.1.4/developing/usage/secondary-indexes/)!
*
* @param table The name of the table (Riak bucket)
* @param startkey The record key of the first record to read.
@ -247,6 +253,13 @@ public final class RiakKVClient extends DB {
@Override
public Status scan(String table, String startkey, int recordcount, Set<String> fields,
Vector<HashMap<String, ByteIterator>> result) {
// As of 2.1.4 Riak KV version, strong consistency does not support any suitable mean capable of searching
// consecutive stored keys, as requested by a scan transaction. So, the latter WILL NOT BE PERFORMED AT ALL!
// More info at http://docs.basho.com/riak/kv/2.1.4/developing/app-guide/strong-consistency/
if (strongConsistency) {
return Status.NOT_IMPLEMENTED;
}
Namespace ns = new Namespace(bucketType, table);
IntIndexQuery iiq = new IntIndexQuery
@ -280,7 +293,7 @@ public final class RiakKVClient extends DB {
}
HashMap<String, ByteIterator> partialResult = new HashMap<>();
partialResult.put(location.getKeyAsString(), getFields(fields, keyResponse));
createResultHashMap(fields, keyResponse, partialResult);
result.add(partialResult);
}
} catch (TimeoutException e) {
@ -339,46 +352,42 @@ public final class RiakKVClient extends DB {
}
/**
* Function that retrieves all the fields searched within a read or scan operation.
* Function that retrieves all the fields searched within a read or scan operation and puts them in the result
* HashMap.
*
* @param fields The list of fields to read, or null for all of them
* @param response A Vector of HashMaps, where each HashMap is a set field/value pairs for one record
* @return A ByteIterator containing all the values that correspond to the fields provided.
* @param fields The list of fields to read, or null for all of them.
* @param response A Vector of HashMaps, where each HashMap is a set field/value pairs for one record.
* @param resultHashMap The HashMap to return as result.
*/
private ByteIterator getFields(Set<String> fields, FetchValue.Response response) {
// If everything went fine, then a result must be given. Such an object is a hash table containing the (key, value)
// pairs based on the requested fields. Note that in a read operation, ONLY ONE OBJECT IS RETRIEVED!
private void createResultHashMap(Set<String> fields, FetchValue.Response response, HashMap<String, ByteIterator>
resultHashMap) {
// If everything went fine, then a result must be given. Such an object is a hash table containing the (field,
// value) pairs based on the requested fields. Note that in a read operation, ONLY ONE OBJECT IS RETRIEVED!
// The following line retrieves the previously serialized table which was store with an insert transaction.
byte[] responseFieldsAndValues = response.getValues().get(0).getValue().getValue();
ByteIterator valuesToPut;
// Deserialize the stored response table.
HashMap<String, ByteIterator> deserializedTable = new HashMap<>();
deserializeTable(responseFieldsAndValues, deserializedTable);
// If only specific fields are requested, then only these should be put in the result object!
if (fields != null) {
HashMap<String, ByteIterator> deserializedTable = new HashMap<>();
deserializeTable(responseFieldsAndValues, deserializedTable);
// Instantiate a new HashMap for returning only the requested fields.
HashMap<String, ByteIterator> returnMap = new HashMap<>();
// Build the return HashMap to provide as result.
// Populate the HashMap to provide as result.
for (Object field : fields.toArray()) {
// Comparison between a requested field and the ones retrieved: if they're equal, then proceed to store the
// couple in the returnMap.
// Comparison between a requested field and the ones retrieved. If they're equal (i.e. the get() operation
// DOES NOT return a null value), then proceed to store the pair in the resultHashMap.
ByteIterator value = deserializedTable.get(field);
if (value != null) {
returnMap.put((String) field, value);
resultHashMap.put((String) field, value);
}
}
// Finally, convert the returnMap to a byte array.
valuesToPut = new ByteArrayByteIterator(serializeTable(returnMap));
} else {
// If, instead, no field is specified, then all the ones retrieved must be provided as result.
valuesToPut = new ByteArrayByteIterator(responseFieldsAndValues);
for (String field : deserializedTable.keySet()) {
resultHashMap.put(field, deserializedTable.get(field));
}
}
// Return the results.
return valuesToPut;
}
/**
@ -542,4 +551,8 @@ public final class RiakKVClient extends DB {
throw new DBException(e);
}
}
RiakCluster getRiakCluster() {
return this.riakCluster;
}
}

Просмотреть файл

@ -17,7 +17,7 @@
*/
/**
* The YCSB binding for <a href="http://basho.com/products/riak-kv/">Riak KV</a> 2.0.x.
* The YCSB binding for <a href="http://basho.com/products/riak-kv/">Riak KV</a> 2.x.y.
*
*/
package com.yahoo.ycsb.db.riak;

Просмотреть файл

@ -50,7 +50,7 @@ riak.wait_time_before_retry=200
riak.transaction_time_limit=10
# riak.strong_consistency - boolean, indicates whether to use strong consistency (true) or eventual consistency (false).
riak.strong_consistency=true
riak.strong_consistency=false
# riak.debug - boolean, enables debug mode. This displays all the properties (specified or defaults) when a benchmark
# is started.