Posts Tagged ‘HowTo’

EC2, MySQL Cluster, and You!

Friday, August 17th, 2007

The past week I’ve been pounding my head bloody going round and round with setting up a MySQL Cluster in EC2. First trying it with Ubuntu, then Fedora 6, and then finally I learned to trust the fine folks at Canonical and believe in that their distro was tight and damn is it ever tight. The beauty of using Ubuntu is that everything you need is installed by default and there is no mucking trying to get the right packages, dependencies, or source. Yes, this is probably not the optimal way of going about this but I need a workable solution and fast and while there are a whole pile of rpms ready to roll the nightmare of getting simple things like perl dependencies satisfied in Fedora were enough to send me screaming out of the cloud.

Anyways, I have a wicked basic cluster running using the following process:

On the Management Node I’m using this config.ini which is sort of cribbed together (/var/lib/mysql-cluster/config.ini)

# Options affecting ndbd processes on all data nodes:
[NDBD DEFAULT]    
NoOfReplicas=2    # Number of replicas
DataMemory=256M    # How much memory to allocate for data storage
IndexMemory=256M   # How much memory to allocate for index storage
                  # For DataMemory and IndexMemory, we have used the
                  # default values. Since the "world" database takes up
                  # only about 500KB, this should be more than enough for
                  # this example Cluster setup.

# TCP/IP options:
[TCP DEFAULT]     
portnumber=2202   # This the default; however, you can use any
                  # port that is free for all the hosts in cluster
                  # Note: It is recommended beginning with MySQL 5.0 that
                  # you do not specify the portnumber at all and simply allow
                  # the default value to be used instead

# Management process options:
[NDB_MGMD]                      
hostname=mgmn           # Hostname or IP address of MGM node
datadir=/var/lib/mysql-cluster  # Directory for MGM node log files

# Options for data node "A":
[NDBD]                          
                                # (one [NDBD] section per data node)
hostname=ndbda           # Hostname or IP address
datadir=/mnt/mysql/data   # Directory for this data node's data files

# Options for data node "B":
[NDBD]                          
hostname=ndbdb           # Hostname or IP address
datadir=/mnt/mysql/data   # Directory for this data node's data files

# SQL node options:
[MYSQLD]                        
hostname=sqln           # Hostname or IP address
                                # (additional mysqld connections can be
                                # specified for this node for various
                                # purposes such as running ndb_restore)

Now, in the end I moved this into /mnt (cp -ar /var/lib/mysql-cluster) so that I didn’t have the threat of running out of disk space on the primary partition.

On the SQL Node in mysql.cnf (/etc/mysql/my.cnf) I have nothing more than this:

# Options for mysqld process:
[MYSQLD]
ndbcluster                      # run NDB storage engine
ndb-connectstring=mgmn  # location of management server
log=/var/lib/mysql/mysql.log

I am experimenting with adding settings back in but I’m not too sure if they belong in the config.ini on the management node or in here. My gut tell me management node. Anyhow, with this I copied the contents of /var/lib/mysql into /mnt (cp -ar again) and renamed the old directory and created a symbolic link pointing to the new location. Kludgey, yes, but I am still learning my way around MySQL and its various settings. Likely, I will figure which config file gets the data directory settings and I’ll make the appropriate changes. And yes, you read that right I do have logging turned on because I am the kind of guy who needs to know.

On the Data Node in my.cnf (/etc/mysql/my.cnf) this plain vanilla setup:

# Options for ndbd process:
[MYSQL_CLUSTER]
ndb-connectstring=mgmn  # location of management server

Now to tie all this boxes together I ended up using a host file, recommended by Paul Moen and my boss and with an endorsement like that I just had to run with it! On all of the nodes in /etc/hosts I dropped the internal IP addresses of each box in the cloud (nslookup domU-12-34-56-78-9A-B1.z-2.compute-1.internal):

# Mysql Cluster data node
10.1.2.3	ndbda
10.4.5.6	ndbdb
# Mysql Cluster mgm node
10.7.8.9	mgmn
# MySQL Cluster sql node
10.10.11.12	sqln

Starting everything up begins with the management cluster:

ndb_mgmd -f /mnt/mysql-cluster/config.ini

Then the data nodes:

ndbd --initial

Note, you only need to do the inital part if it is the first time the node is coming up if you are restarting a cluster you can skip it.

Lastly, the SQL node:

/etc/init.d/mysql start

On the management node you can issue a SHOW to figure out if your bacon is frying:

root@mgmn:~# ndb_mgm -e show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=2    @10.1.2.3  (Version: 5.0.38, Nodegroup: 0, Master)
id=3    @10.4.5.6  (Version: 5.0.38, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @10.7.8.9  (Version: 5.0.38)

[mysqld(API)]   1 node(s)
id=4    @10.10.11.12  (Version: 5.0.38)

Now, what about backups? Well, I am in the process of experimenting with issuing ndb_mgm -e “START BACKUP” on the cluster manager and that will dump a backup to each of the data nodes. Ideally, I would like to issue periodic backups to each individual node in a staggered fashion and have those gziped and sent up to S3. What I need to figure out is if I can issue a backup command for individual nodes like START BACKUP Node_2 or something there abouts. If that is the case I could then grow the data nodes out to the maximum four and take snapshots every 15 minutes which could give us decent coverage if our whole section of the cloud decided to pop.

If you have any questions, criticisms, or gripes feel free to slap me with them as I feel like I am still missing a huge chunk of the picture with all of this. :-D

Bluetooth, Headsets, Ubuntu, and You!

Monday, August 13th, 2007

Tired of having my co-workers laughing at me for not having skype set up (yes, I am still trying to figure out the internal mic) I decided to look into pairing my Samsung WEP170. The solution is pretty quick and dirty.

You’ll need to install several tools, which you can do without I’m not sure but here’s what I have installed so far to pair both my phone and the headset:

bluez-btsco
bluez-pin
bluez-utils
gnome-bluetooth
kdebluetooth
libbluetooth
libbtcl4
libgnomebt0
nautilus-sendto
qobex

For this exercise, though, we’ll be making use of bluez-btsco, bluez-pin, and kdebluetoothd. So after installing the packages modprobe btsco:

$ sudo modprobe snd-bt-sco

Turn on the headset and grab the MAC address:

$ hcitool scan

Copy it and get set up to enter the devices pin number when pairing:

$ passkey-agent –default /usr/bin/bluez-pin

In another terminal type the following with that MAC address you copied:

$ btsco -v BL:UE:TO:OT:HM:AC

Turn on the headset for pairing, in the case of the Samsung it means holding the power down until the light goes solid. If all goes well the passkey-agent should pop looking for the pin of the headset and once that is entered the device should pair and the little KBluetoothD icon should be in your notification area. To use it with Skype I just needed to configure it to use the headset which showed up as a secondary ALSA device with the prefix of BT.

Now, there are two ways to get your headset connected quickly one is to create a little script that issues the btsco command sans the -v and launch it whenever you turn the headset on or you can use the GUI tool found here but that requires you run it as sudo (or gksudo for pure, unadulterated GUI-ness). Other than that this is pretty easy, quick, and dirty. ;-)

Gratefully cribbed from this post and that post on Ubuntu forms as well as the discussion at the tool’s website.

EC2, MySQL, Replication, and You!

Tuesday, August 7th, 2007

One week in and I’m just beginning to get my head around the EC2 way of doing things which is different than what I am used to doing in meatspace with a pile of hardware as well as being worlds away from my Microsoft background. So after tackling a couple of minor projects like Monit + Mongrel, and playing with Memcached, I decided tackle a simple replication setup to get my feet wet in preparation for building a cluster.

After hammering my head against the wall for a day or so things clicked after realizing that this exercise is so much easier if I use the private DNS for plumbing rather than laying ssh tunnels all over the place, which by the way sort-of-kind-of-not-really worked.

Prologue – Create Your World

Look, it is a well known fact that the 9 or so GB that Amazon gives you on the main partition isn’t going to cut it so you have to make some changes to your MySQL environment. The best place for bins and logs are on /mnt. So, since I am epically lazy, I created a mysql directory in /mnt, passed ownership to mysql:mysql, backed up /var/lib/mysql, created a symbolic link to mysql, and then cp -a the contents of the old /var/lib/mysql into /mnt/mysql. Why the backup? Well, if your MySQL instance ever goes down it’ll take the contents of /mnt with it and having a copy of it helps with a speedy recovery.

Step One – Be The Master

Add or edit the following line in /etc/mysql/my.cnf
log=/mnt/mysql/log/mysql.log
server-id=1
log-bin=/var/log/mysql/mysql-bin.log
binlog-do-db=babygotdb

log=/var/lib/mysql/mysql.log (this part is important for seeing whether or not data is replicating)

Restart MySQL then launch the client and issue the following command to add a user with replication privileges:

GRANT REPLICATION SLAVE ON *.* TO ‘replicant’@'%’
IDENTIFIED BY ‘replicantsarepeopletoo’;

FLUSH PRIVILEGES;

Now use the database so we can finish things off…

USE babygotdb;

We want to clear any read locks before we move on so,

FLUSH TABLES WITH READ LOCK;

Now we want to check if what we set up looks like right:

SHOW MASTER STATUS;

This will tell you about the database File, Position, Binlog_Do_DB, and Binlog_Ignore_DB. You will need to know both the file and the position. In this case mine has the following:

File – mysql-bin.000023
Position – 3617723
Binlog_Do_DB – babygotdb
Binlog_Ignore_DB -

You should see something similar to that though it will be in a different format.

quit;

Now is when we dump the database and get it ready to ship over to the slave server.

$ mysqldump -B babygotdb | gzip > babygotdb.sql.gz

Then just scp it to the slave.

Step Two – Get To Know Your Slave

Like on the master we need to make some changes to /etc/mysql/my.cnf

server-id=2
master-host=domU-12-34-56-78-90-1A.usma1.compute.amazonaws.com
master-user=replicant
master-password=replicantsarepeopletoo
master-connect-retry=60
replicate-do-db=babygotdb
log=/var/lib/mysql/mysql.log

Restart mySQL and then launch the client and we have only a little more work to do until we are done.

Gunzip your SQL dump then jump into the mysql client as we need to create our replicated database:

CREATE DATABASE babygotdb;

Then we need to suck in what we dumped on the master:

SOURCE babygotdb.sql;

Stop the slave from running:

SLAVE STOP;

And get our environment ready for replication (this is one long command with each component marked out with commas)

CHANGE MASTER TO
MASTER_HOST=’domU-12-34-56-78-90-1A.usma1.compute.amazonaws.com’,
MASTER_USER=’replicant’,
MASTER_PASSWORD=’replicantsarepeopletoo’,
MASTER_LOG_FILE=’mysql-bin.000023′, MASTER_LOG_POS=3617723;

Now start the slave back up…

SLAVE START;

Watch the replication happen in real time:

$ tail -f /var/lib/mysql/mysql.log

If all is working properly you should be seeing transactions flying by on both as changes are made in the master database.

Gratefully cribbed from Phillip Pearson over at Second p0st and the HowTo Forge write up by falko.

My long term goal is to create images of slaves, masters, data nodes, and management nodes so that deployment will require less hammering on the forge and more tying up loose ends.

Encryption, USB Drive, Ubuntu, Windows, and You!

Thursday, May 24th, 2007

The other day I though I had lost my USB drive, a janky Kingston 1GB stick with no keychain holder that is temporarily replacing my burned out JumpDrive Sport. Deep sets of panic waves overtook me for most of the morning as I wracked my brain and retraced my steps trying to remember where I could have left it or dropped it. The reason that I was panicking was that I carry some quasi-sensitive data on there like the household budget and short stories I’m working on. No bank numbers or SSNs, just stuff that I don’t want people seeing.

Well, I did end up finding the drive wedged in the back seat of Management’s car but I learned an important lesson: if you are going to carry important data with you back it up and encrypt it. I already have the backup part down and have been doing it ever since my first USB drive crapped out on me and I lost piles of data but encryption was something I never got around to until now. The challenge is that I use Ubuntu at home (100% Windows free as of 60 days ago!) and by day I play at being a Windows sysadmin so I need a solution that works cross platform.

My first visit was to the TrueCrypt folks and while they make a fine product that for all intents and purposes worked well on my work box but completely borked the drive for my laptop. So I decided to approach the task from the Linux side looking for native solutions that had counterparts in the Windows world and LUKS plus FreeOTFE did the trick with a minimum of fuss.

On the Ubuntu side:

  • Grab cryptsetup and cryptmount: sudo apt-get install cryptsetup cryptmount
  • Wipe the disk or make some partitions: sudo cfdisk /dev/sdb [NOTE: check your drive's actual path with dmesg as you don't want to be wiping something like your primary drive]
  • Create an encrypted partition: sudo luksformat /dev/sdb [NOTE: pick a passphrase that you can remember because if you forget it kiss your data goodbye]

Now, because I’m plain lazy I rebooted to get the modules running that are related to reading the new encrypted volume but after that when I popped my drive in it asked for my passphrase and then mounted it for me to work on it to my heart’s delight.

On the Windows side:

  • Plug in the USB drive and go to Computer Management >> Disk Management, find the drive, and remove the assigned drive letter, FreeOTFE will assign a free letter to the drive when it mounts it
  • Get a copy of FreeOTFE
  • Unzip it into a directory and start it in Portable Mode
  • File >> Linux Volume >> Mount partition and enter your passphrase
  • Enjoy!

Pretty straight forward.

Gratefully cribbed from carthik’s post at Ubuntu Blog and from FreeOTFE’s solid documentation.