Multi-Nodes Redis Cluster With Docker

Go to the complete article here.

Posted by
Tug Grall
at
10:12 AM
2
comments
Moving my Java from Couchbase to MongoDB pic.twitter.com/Wnn3pXfMGi
— Tugdual Grall (@tgrall) January 26, 2015
| Current Version | mykey |
| Version 1 | mykey::v1 |
| Version 2 | mykey::v2 |
| ... | ... |
function (doc, meta) {
if(doc.type && doc.type == "beer") {
emit(doc.name);
}
}
function (doc, meta) {
if(doc.type && doc.type == "beer" && (meta.id).indexOf("::v") == -1 ) {
emit(doc.name);
}
}
Object obj = client.get(key);
if (obj != null) {
// get the next version, create or use the key: mykey_version
long version = client.incr(key + "_version", 1, 1);
String keyForVersion = key + "::v" + version; // mykey::v1
try {
client.set(keyForVersion, obj).get();
} catch (Exception e) {
logger.severe("Cannot save version "+ version + " for key "+ key +" - Error:"+ e.getMessage() );
}
}
client.set(key, value);
Object obj = client.get(key);
// need to delete all the version first
Object vObject = this.get(key + "_version");
if (vObject != null) {
long biggerVersion = Long.parseLong((String) vObject);
try {
// delete all the versions
for (int i = 1; i <= biggerVersion; i++) {
String versionKey = key + "::v" + i;
client.delete(versionKey).get();
}
// delete the counter
client.delete(key + "_version").get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
client.delete(key);
git clone https://github.com/tgrall/couchbase-how-to-versioning.git cd how-to-versioning mvn clean install
...com.couchbase.howtos couchbase-how-to-versioning 1.0-SNAPSHOT ... couchbase couchbase-client 1.1.8
Listuris = new LinkedList (); uris.add(URI.create("http://127.0.0.1:8091/pools")); CouchbaseClientWithVersioning client = null try { client = new CouchbaseClientWithVersioning(uris, "default", ""); String key = "key-001"; client.set(key, "This is the original version"); System.out.printf("Original '%s' .\n", client.get(key)); client.set(key, "This is a new version", true); // create a new version System.out.printf("Current Version '%s' .\n", client.get(key)); System.out.printf("Version 1 '%s' .\n", client.get(key, 1)); client.set(key, "This is another version", true); // create a new version System.out.printf("All versions %s .\n", client.getAllVersions(key)); client.deleteVersion(key, 1); // create a new version System.out.printf("All versions %s (after delete 1 version).\n", client.getAllVersions(key)); client.delete(key); // create a new version System.out.printf("All versions %s (after delete the main key).\n", client.getAllVersions(key)); } catch (Exception e) { e.printStackTrace(); } if (client !=null) { client.shutdown(); }
client = new CouchbaseClientWithVersioning(uris, "default", "");
client.setAutomaticVersionning(true);
Posted by
Tug Grall
at
6:59 AM
0
comments
+-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | CountryCode | char(3) | NO | | | | | District | char(20) | NO | | | | | Population | int(11) | NO | | 0 | | +-------------+----------+------+-----+---------+----------------+
city:3805
{
"Name": "San Francisco",
"District": "California",
"ID": 3805,
"Population": 776733,
"CountryCode": "USA"
}
{
"rows": [
{"key": "city", "value": 4079},
{"key": "country", "value": 239},
{"key": "countrylanguage", "value": 984}
]
}
{
"total_rows": 4079,
"rows": [
{"id": "city:1", "key": 1, "value": null},
{"id": "city:2", "key": 2, "value": null},
{"id": "city:3", "key": 3, "value": null},
{"id": "city:4", "key": 4, "value": null},
{"id": "city:5", "key": 5, "value": null}
]
}
{
"total_rows": 984,
"rows": [
{"id": "countrylanguage:1", "key": ["ABW", "Dutch"], "value": null},
{"id": "countrylanguage:2", "key": ["ABW", "English"], "value": null},
{"id": "countrylanguage:3", "key": ["ABW", "Papiamento"], "value": null},
{"id": "countrylanguage:4", "key": ["ABW", "Spanish"], "value": null},
{"id": "countrylanguage:5", "key": ["AFG", "Balochi"], "value": null}
]
}
+-------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+-------+
| CountryCode | char(3) | NO | PRI | | |
| Language | char(30) | NO | PRI | | |
| IsOfficial | enum('T','F') | NO | | F | |
| Percentage | float(4,1) | NO | | 0.0 | |
+-------------+---------------+------+-----+---------+-------+
## SQL Information ## sql.connection=jdbc:mysql://192.168.99.19:3306/world sql.username=root sql.password=password ## Couchbase Information ## cb.uris=http://localhost:8091/pools cb.bucket=default cb.password= ## Import information import.tables=ALL import.createViews=true import.typefield=type import.fieldcase=lower
java -cp "./CouchbaseSqlImporter.jar:./mysql-connector-java-5.1.25-bin.jar" com.couchbase.util.SqlImporter import.properties
Posted by
Tug Grall
at
7:36 AM
0
comments
I have created this simple screencast to show how you can, using Couchbase do some realtime analysis based on Twitter feed.
The key steps of this demonstration are
Posted by
Tug Grall
at
8:51 AM
0
comments
Labels:
couchbase,
mapreduce,
nosql,
screencast,
Video,
views
Note : This article has been written in March 2013, since Couchbase and its drivers have a changed a lot. I am not working with/for Couchbase anymore, with no time to udpate the code.A friend of mine wants to build a simple system to capture ideas, and votes. Even if you can find many online services to do that, I think it is a good opportunity to show how easy it is to develop new application using a Couchbase and Node.js.
git clone https://github.com/tgrall/couchbase-node-ideas.git
I read this question on Twitter, let me answer the question in this short article.
First of all you need to be sure your documents have an attribute that contains a date ;), something like :
To get the "latest hired employee" you need to create a view, and emit the hire date as key. The important part is to check that this date is emitted in a format that is sorted properly, for example an array of value using dateToArray function, or the time as numerical value. In the following view I am using the date as an array like that I will be able to do some grouping but this is another topic. The view looks like the following:
Now that you have a view. You can now query it using the parameters:
Posted by
Tug Grall
at
8:32 PM
2
comments
Most of the applications have to deal with "master/detail" type of data:
{
"type": "dept",
"id": 10,
"name": "Accounting",
"city": "New York"
}
Employee
{
"type": "emp",
"id": 7782,
"name": "Blake",
"job": "Clark",
"manager": 7839,
"salary": 2450,
"dept_id": "dept__10"
}
./cbdocloader -n 127.0.0.1:8091 -u Administrator -p password -b default ~/Downloads/emp-dept.zip
Yesterday was my last day at eXo... I have been working at eXo since 2008, and we have achieved many exciting things such as building eXo Platform, the open source social platform, and the Cloud-IDE allowing developers to build, test, and deploy applications online.
It was a great experience for me, but it is time for me to jump into a new adventure...
I am joining Couchbase as a Technical Evangelist for the EMEA Region. When I have started to work with NoSQL engines (starting with Google BigTable for Resultri) I really enjoyed the experience and the flexibility that it gives to the developers. Then I choose to work on a documented oriented database because it looks very natural to me, and evaluate the clustering capabilities. This is how I discovered Couchbase and its community.
This new job is a great opportunity for me to do the things that I really like about software:
Posted by
Tug Grall
at
2:25 AM
3
comments
After some basic articles about Couchbase installation, Node.js integration. Let's now dive into a more complete example: a chat application.
The first version of the chat should be compliant with the following requirements:
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var driver = require('couchbase');
driver.connect({
"username": "",
"password": "",
"hostname": "localhost:8091",
"bucket": "default"},
function(err, couchbase) {
if (err) {
throw (err)
}
server.listen(8080);
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html');
});
...
// Application code
// Socket.io events
...
});
{
"type": "message",
"user": "Tug",
"message": "Hello all !",
"timestamp": 1349836768909
}
socket.on('postMessage', function(data) {
// create a new message
var message = {
type: "message",
user: socket.username,
message: data,
timestamp: Date.now()
}
var messageKey = message.timestamp +"-"+ message.user;
io.sockets.emit('updateChatWindow', message);
couchbase.set(messageKey, JSON.stringify(message),function(err) { });
});
function (doc, meta) {
if ( meta.type == "json" && doc.type == "message" ) {
emit(doc.timestamp, null);
}
}
{"id":"1352733392477-JOHN","key":1352733392477,"value":null},
curl -X PUT -H 'Content-Type: application/json' http://127.0.0.1:8092/default/_design/chat -d '{"views":{"message_hisory":{"map":"function (doc, meta) {\n \n if ( meta.type == \"json\" && doc.type == \"message\" ) {\n emit(doc.timestamp, null);\n }\n}"}}}'
socket.on('showhistory', function(limit,startkey) {
limit = (limit == undefined || limit == 0)? 5 : limit;
var options = {"descending": "true", "limit" : limit, "stale" : "false"};
if (startkey > 0) {
options.startkey = startkey-1;
}
couchbase.view("chat","message_hisory", options , function(err, resp, view) {
var rows = view.rows;
var keys = new Array();
for( var i = 0; i < rows.length ; i++ ) {
keys.push( rows[i].id );
}
couchbase.get(keys,function(err, doc, meta) {
socket.emit('updateChatWindow', doc, true);
});
});
});
socket.on('postMessage', function(data) {
// create a new message
var message = {
type: "message",
user: socket.username,
message: data,
timestamp: Date.now()
}
couchbase.incr("chat:msg_count", function (data, error, key, cas, value ) {
var messageKey = "chat:"+ value;
message.id = value;
io.sockets.emit('updateChatWindow', message);
couchbase.set(messageKey, JSON.stringify(message),function(err) { });
});
});
socket.on('showHistory', function(limit,startkey) {
var keys = new Array();
for (i = startkey; i > (startkey-limit) && i >= 0 ; i--) {
keys.push("chat:"+i);
}
couchbase.get(keys,function(err, doc, meta) {
socket.emit('updateChatWindow', doc, true);
});
});
An easy way to create large dataset when playing/demonstrating Couchbase -or any other NoSQL engine- is to inject Twitter feed into your database.
For this small application I am using:
...... com.couchbase.demo.TwitterInjector .
mvn clean package
twitter4j.jsonStoreEnabled=true oauth.consumerKey=[YOUR CONSUMER KEY] oauth.consumerSecret=[YOUR CONSUMER SECRET KEY] oauth.accessToken=[YOUR ACCESS TOKEN] oauth.accessTokenSecret=[YOUR ACCESS TOKEN SECRET] couchbase.uri.list=http://127.0.0.1:8091/pools couchbase.bucket=default couchbase.password=
jar -jar [path-to-jar]/CouchbaseTwitterInjector.jar
NOTE: The Couchbase Node.js Client Library is currently changing. I will update this article and source code once the API is stable.
ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"
brew install node
brew install https://github.com/couchbase/homebrew/raw/preview/Library/Formula/libcouchbase.rb
mkdir sample-app cd sample-app
var http = require("http");
function onRequest(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
var server = http.createServer(onRequest);
server.listen(8080);
console.log("> SERVER STARTED");
node app.js
npm install couchbase
var http = require("http");
// load the Couchbase driver and connect to the cluster
var driver = require('couchbase');
var cb = new driver.Couchbase("localhost:8091", null, null, "default");
...
...
function insertData() {
// insert employees in Couchbase
var emps = [{
"type": "employee",
"id": 100,
"name": "Thomas",
"dept": "Sales",
"salary": 5000
}, {
"type": "employee",
"id": 200,
"name": "John",
"dept": "Development",
"salary": 4500
}, {
"type": "employee",
"id": 300,
"name": "Jane",
"dept": "Marketing",
"salary": 5000
}]
// Insert the data in Couchbase using the add method ()
for (index = 0; index < emps.length; index++) {
cb.add(JSON.stringify(emps[index].id), JSON.stringify(emps[index]), 0, undefined, function(data, err, key, cas) {
if (err && err != 12) { // 12 : LCB_KEY_EEXISTS
console.log("Failed to store object:\n" + err);
}
});
}
}
server.listen(8080, insertData());
var http = require("http");
// load the Couchbase driver and connect to the cluster
var driver = require('couchbase');
var cb = new driver.Couchbase("localhost:8091", null, null, "default");
// load the baseview module
var baseview = require('baseview')({url: 'http://localhost:8092', bucket: 'default'});
...
...
function insertData() {
//create a new view
baseview.setDesign('design_employees', {
'basic_list': {
'map': "function (doc, meta) { if(doc.type == 'employee') {emit(meta.id, doc.name);}}"
}
},
function(err, res){
if (err != null) console.log(err);
}
);
...
}
...
This new code, create a new view in Couchbase server:function onRequest(request, response) {
response.writeHead(200, {
"Content-Type": "text/plain"
});
response.write("See list of employees in the console");
var params =
{ 'descending' : 'true'
, 'include_docs' : 'true'
};
baseview.view('design_employees', 'basic_list', params, function(error, data) {
for( var i = data.rows.length-1,length = data.rows.length ; i >= 0; i-- ) {
var employee = data.rows[i].doc.json;
console.log(employee);
}
});
response.end();
}
var http = require("http");
var driver = require('couchbase');
var cb = new driver.Couchbase("localhost:8091", null, null, "default");
var baseview = require('baseview')({url: 'http://127.0.0.1:8092',bucket: 'default'});
function onRequest(request, response) {
response.writeHead(200, {
"Content-Type": "text/plain"
});
response.write("See list of employees in the console");
var params = {
'descending': 'true',
'include_docs': 'true'
};
baseview.view('design_employees', 'basic_list', params, function(error, data) {
for (var i = data.rows.length - 1, length = data.rows.length; i >= 0; i--) {
var employee = data.rows[i].doc.json;
console.log(employee);
}
});
response.end();
}
function insertData() {
//create a new view
baseview.setDesign('design_employees', {
'basic_list': {
'map': "function (doc, meta) { if(doc.type == 'employee') {emit(meta.id, doc.name);}}"
}
}, function(err, res) {
if (err != null) console.log(err);
});
// insert employees in Couchbase
var emps = [{
"type": "employee",
"id": 100,
"name": "Thomas",
"dept": "Sales",
"salary": 5000
}, {
"type": "employee",
"id": 200,
"name": "John",
"dept": "Development",
"salary": 4500
}, {
"type": "employee",
"id": 300,
"name": "Jane",
"dept": "Marketing",
"salary": 5000
}]
// Insert the data in Couchbase using the add method ()
for (index = 0; index < emps.length; index++) {
cb.add(JSON.stringify(emps[index].id), JSON.stringify(emps[index]), 0, undefined, function(data, err, key, cas) {
if (err && err != 12) { // 12 : LCB_KEY_EEXISTS
console.log("Failed to store object:\n" + err);
}
});
}
}
var server = http.createServer(onRequest);
server.listen(8080, insertData());
console.log("> SERVER STARTED");


200,Jason,Technology,5500 300,Mayla,Technology,7000 400,Nisha,Marketing,9500 500,Randy,Technology,6000 501,Ritu,Accounting,5400
function (doc) {
emit(doc.dept, null);
}
{"total_rows":6,"rows":[
{"id":"501","key":"Accounting","value":null},
{"id":"400","key":"Marketing","value":null},
{"id":"100","key":"Sales","value":null},
{"id":"200","key":"Technology","value":null},
{"id":"300","key":"Technology","value":null},
{"id":"500","key":"Technology","value":null}
]
}
{"total_rows":6,"rows":[
{"id":"200","key":"Technology","value":null},
{"id":"300","key":"Technology","value":null},
{"id":"500","key":"Technology","value":null}
]
}
{"total_rows":6,"rows":[
{"id":"200","key":"Technology","value":null,"doc": {"_id":"200","_rev":"1-1de6e6751608eada0000003200000000","$flags":0,"$expiration":0,"name":"Jason","dept":"Technology","salary":5500}},
{"id":"300","key":"Technology","value":null,"doc":{"_id":"300","_rev":"1-f3e44cee742bfae10000003200000000","$flags":0,"$expiration":0,"name":"Mayla","dept":"Technology","salary":7000}},
{"id":"500","key":"Technology","value":null,"doc": {"_id":"500","_rev":"1-05780359aac8f3790000003200000000","$flags":0,"$expiration":0,"name":"Randy","dept":"Technology","salary":6000}}
]
}
function (doc) {
emit(doc.salary, null);
}
{"total_rows":6,"rows":[
{"id":"100","key":5000,"value":null,"doc":{"_id":"100","_rev":"1-0f33580d780014060000002e00000000","$flags":0,"$expiration":0,"name":"Thomas","dept":"Sales","salary":5000}},
{"id":"501","key":5400,"value":null,"doc":{"_id":"501","_rev":"1-b1fe5bc79637720e0000003100000000","$flags":0,"$expiration":0,"name":"Ritu","dept":"Accounting","salary":5400}},
{"id":"200","key":5500,"value":null,"doc":{"_id":"200","_rev":"1-1de6e6751608eada0000003200000000","$flags":0,"$expiration":0,"name":"Jason","dept":"Technology","salary":5500}},
{"id":"500","key":6000,"value":null,"doc":{"_id":"500","_rev":"1-05780359aac8f3790000003200000000","$flags":0,"$expiration":0,"name":"Randy","dept":"Technology","salary":6000}}
]
}
Posted by
Tug Grall
at
8:31 AM
7
comments