Skip to Content Skip to Search Go to Top Navigation Go to Side Menu


"Development" Category


Setting up high availability storage with MogileFS


Thursday, July 3, 2008

1. Environment

I used 4 Xen virtual images running ubuntu 8.04.
Two will run a tracker and the database, the other two will be the storage nodes.

Lets say the IP addresses will be:


192.168.0.195
192.168.0.196
192.168.0.197
192.168.0.198

2. Initial Setup

Install iptables:


apt-get install iptables

then apply initial setup


iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -j DROP
iptables-save -c > /etc/iptables.rules

you can save the rule for beyond machine reboot by adding the two lines below to /etc/network/interfaces

pre-up iptables-restore < /etc/iptables.rules
post-down iptables-save -c > /etc/iptables.rules

install mysql and wget and perldoc


apt-get install mysql-server
apt-get install wget
apt-get install perl-doc
apt-get install libio-aio-perl
apt-get install subversion
apt-get install build-essential

3. Common steps for installing MogileFS

retrieve the code (ripped of the how to wiki):


cd /usr/local/src
mkdir mogilefs-src
cd mogilefs-src
svn checkout http://code.sixapart.com/svn/mogilefs/trunk

install perl dependencies


cpan Danga::Socket
cpan Gearman::Client
cpan Gearman::Server
cpan Gearman::Client::Async
cpan Net::Netmask
cpan Perlbal
cpan IO::WrapTie

install the servers:


cd mogilefs-src/trunk/server
perl Makefile.PL
make
make test
make install

At the moment the test seems to need mysql to be installed and user root without password, so some tests are skipped

you will need to install MogileFS::Client
(the tests expect a tracker to run locally on port 7001)


cd mogilefs-src/trunk/api/perl/MogileFS-Client
perl Makefile.PL
make
make test
make install

and some admin tools:


cd mogilefs-src/trunk/utils
perl Makefile.PL
make
make test
make install

4. Tracker install

create the database:


mysql -uroot -p
mysql> CREATE DATABASE mogilefs;
mysql> GRANT ALL ON mogilefs.* TO 'mogile'@'%';
mysql> SET PASSWORD FOR 'mogile'@'%' = OLD_PASSWORD( 'sekrit' );
mysql> FLUSH PRIVILEGES;
mysql> quit

Create the schema


./mogdbsetup --dbname=mogilefs --dbuser=mogile --dbpassword=sekrit

(admin privilege is required for the initial setup, so if you’re admin user is not root with no password, you will need to specify –dbroopassword and –dbrootuser)

create /etc/mogilefs/mogilefsd.conf:


db_dsn DBI:mysql:mogilefs
db_user mogile
db_pass ******
conf_port 7001
listener_jobs 5

create a mogile user:


adduser mogile

and starts the tracker under that user:


su - mogile
mogilefsd

open a port for the tracker


iptables -A INPUT -p tcp --dport 7001 -j ACCEPT
iptables -F

5. Storage node

On the storage server, create a configuration file at /etc/mogilefs/mogstored.conf with the following:


httplisten=0.0.0.0:7500
mgmtlisten=0.0.0.0:7501
docroot=/var/mogdata

open a port:


iptables -A INPUT -p tcp --dport 7500 -j ACCEPT
iptables -F

register a new storage node:


mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.195:7001 host add mogilestorage --ip=192.168.0.197 --port=7500 --status=alive

it should now appears in the list:


mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.195:7001 host list

Add a device to the storage:


mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.195:7001 device add mogilestorage 1

and create the directory:


mkdir -p /var/mogdata/dev1

6. Starting the storage server

as root:

mogstored --daemon

7. Starting the tracker


su - mogile
mogilefsd -c /etc/mogilefs/mogilefsd.conf --daemon
exit

8. Testing

check that mogilefs components are online:


mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.195:7001 check

Quick sanity check of the storage daemon:


~/Projects/mogilefs $ telnet 192.168.0.197 7500
Trying 192.168.0.197...
Connected to 192.168.0.197.
Escape character is '^]'.
PUT /dev1/test HTTP/1.0
Content-length: 4
\n
test
HTTP/1.0 200 OK
Content-Type: text/html
Content-Length: 18
Server: Perlbal
Connection: close
200 - OK
Connection closed by foreign host.

create a domain


mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.195:7001 domain add mydomain

and a class


mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.195:7001 class add mydomain images

Quick sanity check of the tracker:


root@bbc-01:~# mogtool --trackers=127.0.0.1:7001 --domain=mydomain --class=images inject osname osname

on the store node, check /var/mogdata/dev1/0/000/000 for a file named xxxxxxxxxx.fid .
If the file exists it’s all good.

9. setting up the second pair

Replay instructions 1 to 8, then:

when you’ve got the second storage set up, you will need to register the second storage and its device to all trackers:


mkdir -p /var/mogdata/dev2
mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.195:7001 host add mogilestorage2 --ip=192.168.0.198 --port=7500 --status=alive
mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.195:7001 device add mogilestorage2 2
mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.196:7001 host add mogilestorage2 --ip=192.168.0.198 --port=7500 --status=alive
mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.196:7001 device add mogilestorage2 2

you will also need to register the first storage and its device to the second tracker:


mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.196:7001 host add mogilestorage --ip=192.168.0.197 --port=7500 --status=alive
mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.196:7001 device add mogilestorage 1

sanity check the installation:


mogadm --lib=/usr/local/share/perl/5.8.8 --trackers=192.168.0.195:7001,192.168.0.196:7001 check

Checking trackers…
192.168.0.195:7001 … OK
192.168.0.196:7001 … OK

Checking hosts…
[ 1] mogilestorage2 … OK
[ 2] mogilestorage … OK

Checking devices…
host device size(G) used(G) free(G) use% ob state I/O%
—- ———— ———- ———- ———- —— ———- —–
[ 1] dev2 9.921 0.757 9.164 7.63% writeable 0.0
[ 2] dev1 9.921 0.600 9.321 6.05% writeable 0.0
—- ———— ———- ———- ———- ——
total: 19.842 1.357 18.485 6.84%

And voila.

Ruby on Rails with_scope and returning


Thursday, June 19, 2008

This week in my current project I’ve come across two ruby constructs that were new to me.

with_scope and returning.

Found a blog where they are both nicely explained:

Your Company’s App


Sunday, March 16, 2008

A funny but familiar comic strip :-)

Your Company’s App: “Company’s”

(Via Daring Fireball.)

Proposed solution for Microsoft’s browser issues and illustrative pie chart


Wednesday, February 20, 2008

I’ve started to miss making blog posts with fancy diagramme, mind-blowing pie charts.

The Open letter from Opera’s CTO published in The Register has given me the opportunity to drawn this blog under the total wisdom of yet another pie chart as buried in the comments to the article, I found this:

it's funny

You’ll notice it’s in the same vein as that one from last year :-D

When subversion is not good enough


Monday, February 18, 2008

I hate subversion right now.

For reasons outside my control I have to keep development branches open for a long time and therefore I need to sync them regularly with trunk and these merge operations are quite annoying and source of headaches.

Additionally, in the recent months I found myself coding disconnected from a network more often than before and I wished I could commit my changes locally and sync them when back online.

Some perl developers around me have played with SVK in the past, and at the end of last year I came across a blog post reviewing several Distributed Version Control System (DVCS).

And Let’s not forget DARCS.

I’ll play with a couple of these, but my choice may be simpler as two developers in my team have already started using Git with the git-svn hook between themselves.

Ruby On Rails tips


Saturday, February 16, 2008

Recently, I’ve been working on a Rails project for the first time.
It’s a nice change after years of perl.

There are quite a few little things that I knew how to do in perl, that I didn’t have clue on how to do it in Rails. Also I run into issue peculiar to Rails or ruby.

I solved all these issues so far and the links below give pointers to some helpful information.


Integrating Perl Tests Report in Cruise Control


Monday, November 19, 2007

Back In May, I’ve posted a “TAP vs XML” article (triggered by a similarly titled article from Curtis Poe) mainly focused on the challenge of integrating perl testing with Cruise Control.

In the meantime, Rufus Cable pointed me to the direction of Matisse Enzer who wrote a tool to output perl test report into the junit xml format used by Apache Ant.

Controlled Vocabulary And Semantic Web


Monday, October 29, 2007

If you’re not sure what’s the difference between a controlled vocabulary, a taxonomy and a thesaurus, this blog article is quite good at clarifying the above concepts and more.

What’s not covered are tags and folksonomy.

Automation of release notes in agile projects


Wednesday, September 19, 2007

My team works in short iterations at the end of which we should be able to release a new version of the software with added value.

To facilitate the generation of release notes, another team I was observing is using markups in their version control commit message: they add [R] in the commit message to denote the addition new features to the repository.

I thought it was a good idea and introduced it as a version control standard in my team.
After a couple of iterations, there weren’t many [R] in the commit messages.

We found ourselves sometimes shying away from adding an [R] to the commit message, as we’re not always sure a feature is done or not. Also we do commit often, I’d say compulsively, at various steps of our work: it’s easy to commit the last chunk without realizing it’s the last. It is also easy to mark a commit with [R] on a chunk of code for which some files are accidentally missing from the commit.

After further investigation, I discovered a difference in branching strategy between the two teams:
In my team we branch on ad-hoc basis when we are about to start a risky task, but keep working on trunk for work with limited scope and impact. The other team is systematically creating branches for ANY new work they are doing, which means that merging branches (after running the test suite on that branch) to trunk define what is a completed feature and the [R] mark tends to be found on commit message for merges.

Since we are not applying a branch for every feature policy we need to find other ways to identify task done in an iteration. What we are doing though is acceptance test driven development.
It starts with a user story, then the associated acceptance tests. We use fit to write FIT tables for acceptances and write the fixture code for the automated test. The Fit infrastructure is held in Fitnesse which is a wiki-on-steroids with an integrated FIT runner.

Each user story is en entry in the wiki, and Fitnesse allows you to create virtual wiki links on wiki entries which allow easy creation of indexes (dynamically or statically updated).
We are already using these facilities to regroup all completed and validated stories on a page called RunningTestedFeature which is then executed as a suite as part of our continuous integration process for regression testing.

The interesting bit is that in a similar way, for each iteration we can also create a page linking to all stories planned for that iteration at the end of which the suite is executed . The stories whose acceptances tests passed become the bullet point item in the release note if we decide to release.

And there is an added bonus: by keeping these iteration index pages over time, it will help the calculation of velocity as it becomes easy to count how many stories are completed per iteration.

Perl OO = Evil ?


Sunday, September 2, 2007

In response to Chris’ comment about “OO=Evil” and his perl program that he said would have been easier to change had it been written in Java:

by saying “…much easier to alter if it were written in java.” , I think you meant to say ”much easier if it was properly encapsulated, layered with  clearly defined interfaces between components and recognizable abstractions and design patterns”

Object Orientation paradigm is all about that:

  • Modularity through encapsulation, abstraction, interfaces
  • Re-usability through polymorphisms, inheritance, interfaces

The existence of documented and proven design patterns for OO further helps build and refactor  OO programs.

These are characteristics of OO programming in general, not specific to a language.

You can write proper Object Oriented Programs in perl (see Damian Conway’s PBP or better, the recent effort around Moose)

You can apply the OO design patterns to such perl programs (e.g:  see Object::PerlDesignPatterns)

and they will have the same benefits as properly written Java programs (easy to refactor and to reuse code).

It’s just that:

  • Java was designed for Object Orientation, therefore if you write java you are forced into this paradigm. Because of that  they are more tools for java to assist OO programming (especially for refactoring).
  • OO in Perl 5 has too many unsatisfactory way to do it and a too verbose syntax

Regarding the talk on Perl’s Worst Practices and the seemingly controversial  “OO=Evil”:

what Mark Fowler  meant is that, OO is not only the paradigm in computing and it’s not always the best way to solve a problem.

You’ve got OO programming, procedural programming, functional programming,  aspect oriented programming,…

The nature of perl doesn’t force you in any of these (”There’s More Than One Way To Do It”), and each of these paradigms are better than the others for their own class of problems.

In other words,  a skilled programmer should use the paradigm that suit best the domain of problems it tries to solve.

Of course, all programmers involved in writing or changing such programs need to have the same understanding of the domain and the best suited paradigm otherwise …

Mark Fowler also hinted at the multiple unsatisfactory ways along with heavy syntax when doing OO with perl 5 as a reason for OO=Evil.

Perl 6 has a new object system which is very good and it is being ported on perl 5 as Moose.

Regarding my views on OO=Evil

I’m a big fan of Object Orientation as implemented with Objective-C or Small Talk.

Java OO is less elegant than
ST/Objective-C’s.

Perl 5 OO implementation upsets me more, but at least I can choose not do OO in perl.
Also, the prospects of Perl 6 and the influence it had on Perl 5 (Moose) is starting to make OO in perl more interesting and desirable.

I think OO is not always the best paradigm, and I’m liking Functional Programming more and more.
Mark Jason Dominus’ High Order Perl  is the  “FP design patterns” reference for perl programmers.

I found it difficult to get my head around (I’m still in the first chapters of HOP) and also I don’t know
the best practices for unit testing FP programs.

I can restrospectively see a bunch of code of mine that might have benefitted of FP. Conversely, I have also unappropriately applied FP to some code. My current project though is better served by using OO.

Going back to OO, Ruby’s OO is close to Small Talk, and Perl 6 is also borrowing things from Small Talk (ST traits will be known as roles in Perl 6) among other languages.

So, OO in Perl 5 is the devil, but often you have to sleep with it and at the end you get used to it.
If I can identify problems in code I create or change that are better solved by FP (I really need to make progress with HOP), I’ll go for it.
In Perl 6,  OO (and FP too) will be dramatically improved.

If you can’t wait, go for Ruby or Perl 5+Moose.