SF New Tech

On Wednesday, I went to the SF New Tech. This is the biggest monthly technology event in San Francisco. It is not for free. If you want to come to the SF New Tech, you will have to pay between USD 15 and USD 30. This depends upon the time you book your tickets – the earlier, the better. Usually, the conference is sold out pretty quickly.

At the SF New Tech, people are gathering to network. And to see some new technology start-ups. After 2 hours of networking, there will usually be 5 or 6 new start-ups coming to the stage and to present their new products.

My new company VersionEye was one of them.

This is Myles Weissleder. He has been organizing the conference for many years. And he is doing a great job.

Every start-up has 10 mins on the big stage, 5 mins for a live demo …

.. and 5 mins for questions & discussions.

At the SF New Tech, you are not allowed to use PowerPoint. You have to show a live demo! I like that :-)

I got a lot of feedback and I am learning what the community wants and what it doesn’t want.And I am also learning what people are willing to pay for it.

I will present our solution again pretty soon at another conference here in the Bay Area.

RVM

RVM is an environment manager for Ruby. With RVM you can handle different versions of Ruby and different gemsets on the same machine.

With this command you can install the tool on your machine.

bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
source ~/.bash_profile

If you want to install a special ruby version on your machine, just try this:

rvm install 1.9.2

And RVM will install Ruby version 1.9.2 on you machine. Everything what RVM is downloading and installing is stored in your home directory under “~/.rvm”. You can now also install version 1.8.7.

rvm install 1.8.7

With this command you can see all your versions.

rvm list

That will list all installed ruby versions. If you want to use version 1.9.2, just type in:

rvm use 1.9.2

That’s it :-)

You can also create different gemsets.

rvm gemset create rails2

That will create a sperate gemset. Yo can use in every project a different ruby version and a different gemset. To choose a special gemset just type:

rvm gemset use rails2

You can list all your gemsets with this command:

rvm gemset list

That is pretty useful!

 

Failed to connecto to primary node

If you try to connect to MongoDB Replica Set via MognoID and you get this error message here:

/opt/local/lib/ruby1.9/gems/1.9.1/gems/mongo-1.5.2/lib/mongo/repl_set_connection.rb:165:inconnect': Failed to connect to primary node. (Mongo::ConnectionFailure) from /opt/local/lib/ruby1.9/gems/1.9.1/gems/mongo-1.5.2/lib/mongo/repl_set_connection.rb:500:insetup'
from /opt/local/lib/ruby1.9/gems/1.9.1/gems/mongo-1.5.2/lib/mongo/repl_set_connection.rb:144:in initialize' from /opt/local/lib/ruby1.9/gems/1.9.1/gems/mongoid-2.3.4/lib/mongoid/config/replset_database.rb:24:innew'
from /opt/local/lib/ruby1.9/gems/1.9.1/gems/mongoid-2.3.4/lib/mongoid/config/replset_database.rb:24:in configure' from /opt/local/lib/ruby1.9/gems/1.9.1/gems/mongoid-2.3.4/lib/mongoid/config.rb:316:inconfigure_databases'
from /opt/local/lib/ruby1.9/gems/1.9.1/gems/mongoid-2.3.4/lib/mongoid/config.rb:119:in from_hash' from /opt/local/lib/ruby1.9/gems/1.9.1/gems/mongoid-2.3.4/lib/mongoid/config.rb:136:inload!'
from /opt/local/lib/ruby1.9/gems/1.9.1/gems/mongoid-2.3.4/lib/mongoid.rb:147:in load!' from /Users/reiz/workspace/versioneye/versioneye/config/application.rb:33:inclass:Application'
from /Users/reiz/workspace/versioneye/versioneye/config/application.rb:18:in <module:Versioneye>' from /Users/reiz/workspace/versioneye/versioneye/config/application.rb:17:in'
from /opt/local/lib/ruby1.9/gems/1.9.1/gems/railties-3.1.0/lib/rails/commands.rb:52:in require' from /opt/local/lib/ruby1.9/gems/1.9.1/gems/railties-3.1.0/lib/rails/commands.rb:52:inblock in '
from /opt/local/lib/ruby1.9/gems/1.9.1/gems/railties-3.1.0/lib/rails/commands.rb:49:in tap' from /opt/local/lib/ruby1.9/gems/1.9.1/gems/railties-3.1.0/lib/rails/commands.rb:49:in'
from script/rails 
in require' from script/rails:6:in'

Than you should check out this link here: https://github.com/mongoid/mongoid/issues/1783#issuecomment-4319677Durran Jordan helped me to solve problem. Thx for that!

Rails + MongoDB ReplicaSet Configuration

This article shows how to configure a Ruby on Rails app for a MongoDB ReplicaSet. How to set up a MongoDB ReplicaSet I described here: MongoDB ReplicaSet Tutorial. And how to configure Rails to work together with MongoDB is described here: Rails + MongoDB Quickstart Tutorial.

If you want to connect to a ReplicaSet you just have to change your configuration a little bit. This is how your mongoid.yml file should look like:

production:
  database: mydb_prod
  hosts:
    - - mongonode1:1222
    - - mongonode2:1222
    - - mongonode3:1222
  read: :secondary

“mongonode1″, “mongonode2″ and “mongonode3″ should be mapped to a real ip address, of course! Usually you do that in “/etc/hosts”.

You don’t have to define a PRIMARY! The driver will figure out which of them is the PRIMARY. I like this! You also don’t need a load balancer. Because all nodes are known by the driver. And so the driver will figure it out.

The property “read” can have 2 values: [":secondary", ":primary"]. “:secondary” means that read operations can also be routed to secondary nodes. “:primary” means that all read operations will be routed to the PRIMARY node.

MongoDB ReplicaSet Tutorial

MongoDB is a document-oriented database. One cool feature is that you can easily set up a MongoDB cluster, a Replica Set. A Replica Set has at least 3 nodes. Show here on the image from the MongoDB docu.

In a Replica Set there is always one Master! All other nodes are “SECONDARY” nodes! Write operations have always to go to the “PRIMARY” (Master) Node. Read operations can also go to SECONDARY nodes.

If you want to start a mongod process as part of a Replica Set you can use this parameters:

./bin/mongod --port <PORT> --bind_ip <IP-ADRESS> --replSet <REPL-NAME> --rest

for example:

./bin/mongod --port 1222 --bind_ip 192.168.0.101 --replSet myreplset --rest

You can do that on 3 different servers, or more if you want. Than log in into the server which should be the first PRIMARY. Here you have to start the mongo shell and initiate the replica set.

rs.initiate()

That is initiating the replica set. Now the replica set is running with 1 node. Now you have to add the other nodes.

rs.add(“192.168.0.102:1222”)
rs.add("192.168.0.102:1222")

All right. Now the replica set is running with 3 nodes. Now you can open a browser and navigate to the ip address of the PRIMARY node:

http://192.168.0.101:1222/_replSet

Because we started the mongod process with the parameter “–rest” we can see now a small web application showing us the status of our replica set. Here we should see 3 Members. 1 PRIMARY and 2 SECONDARY.

Now you can connect to the PRIMARY via the mongo shell console and add a document to the database. For example:

mongo --host 192.168.0.101 --port 1222 
> use myfirstdb
> db.users.save ( {name : "Hans"} )

If you connect now to a SECONDARY you will see the document there.

mongo --host 192.168.0.102 --port 1222 
> use myfirstdb
> db.users.find()

If the PRIMARY goes down, there is an election in the replica set. So that one of the SECONDARIES become the new PRIMARY. When the old PRIMARY is again up and running, he will sync with the other nodes and become again the current PRIMARY.

I have setup a replica set for an Ruby on Rails application. And I played around with it. I just rebooted randomly some of the nodes. But my Ruby on Rails was still available could deliver the data. That is pretty cool! :-)

You can read more about Replica Set Configuration here: MongoDB Replica Set Configuration.

 

Insalling CouchDB on Mac OS X Lion

CouchDB is a document-oriented database with MapReduce feature. It provides a RESTful JSON API over HTTP. It offers distributed, featuring robust, incremental replication with bi-directional conflict detection and management. It is similar to MongoDB.

To install it on Mac OS X Lion, just execute this command here:

sudo port install couchdb

And after the installation this here:

sudo launchctl load -w /Library/LaunchDaemons/org.apache.couchdb.plist

To install couchdb as Service in the OS and start the couchdb daemon.Now you can open a browser and navigate to this address:

http://localhost:5984/

You should get a JSON result similar to that here:

{"couchdb":"Welcome","version":"1.1.0"}

And that’s it. CouchDB installed, up and running!

MongoID read_secondary deprecated

OK. If you are using Rails + MongoID and you get this error message here:

read_secondary options has now been deprecated and will be removed in driver v2.0. Use the :read option instead.

Than you just have to change your configuration. Just replace “read_secondary” with “read”.

Rails + MongoDB Tutorial. Quickstart.

This is a Quickstart Tutorial for Rails + MongoDB. Ruby on Rails and MongoDB, a document based database, is a pretty good fit. It is very easy to integrate MongoDB with Rails. If you want to know how to install MongoDB, check out this article here: Installing MongoDB on Mac OS X Lion. Or this here: Installing MongoDB on Linux.

I assume you are familiar with Ruby on Rails :-)

There are several GEMs to interact with MongoDB. I used the MongoID GEM. That worked pretty good for me. Just add this to your Gemfile:

gem 'bson_ext', '1.6.0'  
gem 'mongo', '1.6.0'
gem 'mongoid', '2.4.6'

And run “bundle install” on your project, to load the GEM from the internet. And add the file mongoid.yml to your config folder:

development:
    host: localhost
    database: myapp_dev

test:
    host: localhost
    database: myapp_test

production:
    host: localhost
    database: myapp_prod

This is the file where you are configuring the access to the database. If your mongodb instance is running locale you don’t need any username or password settings. Now you have to load the mongoid.yml file. You can do that by adding this line to your application.rb inside of the “class Application”.

Mongoid.load!("config/mongoid.yml")

Than just add a new Model to your project. For example “User”. That could look like that:

class User
include Mongoid::Document
include Mongoid::Timestamps
field :username, type: String
field :firstname, type: String
field :llastname, type: String
field :email, type: String
filed :age, type: Integer

end

That’s it. You just have to include the Mongoid:Document.

include Mongoid::Document

And define your fields! Now you can create a new user and save it like that:

user = User.new
user.username = "mike"
user.firstname = "Mike"
user.lastname = "Boby"
user.age = 44
user.save

Or make a query like that:

user = User.where( username: "mike")

Check out the Criteria API for MongoID. That is pretty straight forward. Worked pretty well for me.

MongoDB. Growing local.X files

I have a ReplicaSet with MongoDB 2.0.2 on two Debian Linux 6.0 servers. The ReplicaSet is working fine. But on one of the servers I realized that there are a bunch of local.x files.

  • local.0
  • local.1
  • local.22.

Each of them 2.1 GB. The actual database/collections are less than 1 GB. I am just wondering why there are all this files and taking more than 40 GB space ??

On a dedicated server with 800 GB this is not a big deal, but on a small VServer with 60GB HD this could be a huge problem!

If somebody have the same problem and an solution for it, please let me know!

mongodb replicasets with read errors

If you have a ReplicaSet setup with MongoDB and you try to read from a slave node and you get this Exception here:

mongdodb, replicates and error: { “$err” : “not master and slaveok=false”, “code” : 13435 }

or this here:

uncaught exception: count failed: { "errmsg" : "not master", "ok" : 0 }

Than the problem is that you are not allowed to read from the slave. By default MongoDB disables reads from Slaves. You can solve that by executing this here on the slave in the mongo shell:

rs.slaveOk()

Or just reconfigure your mongo driver.

MongoDB Import / Export

If you want to export a whole database on MongoDB, this is the tool you are looking for:

mongodump --host <HOST> --port <PORT> --db <DATABASE> --username <USERNAME> --password <PASSWORD>

that will export all your collections into a separate folder. Each collection is exported to a single bson file. After you executed the command you will have a “dump” folder. Under the dump folder there is folder the the name of the DATABASE and under the database folder are the collections on separate bson files.

If you want to import the files into another MongoDB on another server, this is the tool you are looking for:

mongorestore --host <HOST> --port <PORT> --username <USERNAME> --port <PORT> dump/<DATABASENAME>

That worked for me fine :-)