Author: barce

  • WP Geo Plugin

    The print_GeoCache_Url function came across my email today from a self-described local designer and geek, but after a little research, I found out it only works up to WordPress 1.2 . Thank goodness for the WordPress WP-Geo Plug-in which I’m using right now.

    More info here: WPGeo.com

    [wp_geo_map]

  • EC2 Backup Script

    This is a quick and dirty EC2 backup script for virtual unix servers that works just fine when crontabbed:

    #!/bin/bash

    DATE=`date +%m%d%Y-%H%m%M`
    BUCKET=”codebelay-$DATE”
    PRIVATE_KEY=’pk-codebelay.pem’
    PRIVATE_CERT=’cert-codebelay.pem’
    USERID=’555555555555′
    AWS_ACCESS_ID=’AKIA0000000000000′
    AWS_SECRET=’asdf+asdf+asdf+asdf’

    s3cmd mb s3://$BUCKET

    cd /mnt
    mkdir img
    ec2-bundle-vol -d /mnt/img -k /mnt/$PRIVATE_KEY -c /mnt/$PRIVATE_CERT -u $USERID -s 9999 –arch i386
    cd /dev
    mkdir loop
    cd loop
    mknod 0 b 7 0

    ec2-upload-bundle -b $BUCKET -m /mnt/img/image.manifest.xml -a $AWS_ACCESS_ID -s $AWS_SECRET

    # rm -rf /mnt/img
    echo “please register $BUCKET/image.manifest.xml” >> /mnt/registerbackups.txt

  • Notes on adding more MySQL databases

    Just notes for myself on adding more MySQL databases without shutting down the master database.

    on existing slave:

    /etc/init.d/mysqld stop

    copy data dir from /var/lib/mysql and data from /var/run/mysqld to new slave database:

    cd /var/lib
    tar cvf Mysql_slave.tar mysql/*
    scp Mysql_slave.tar root@new-db.com:/var/lib/.
    cd /var/run
    tar cvf Mysqld_slave.tar mysqld/*
    scp Mysqld_slave.tar mysqld/*
    scp Mysqld_slave.tar root@new-db.com:/var/run/.

    copy /etc/my.cnf from old slave to new slave
    add entry for new server-id

    start existing slave:

    cd /var/lib
    tar xvf Mysql_slave.tar
    cd /var/run
    tar xvf Mysqld_slave.tar
    /etc/init.d/mysqld start

    start new slave:

    /etc/init.d/mysqld start
    mysql
    start slave;

    on masterdb:
    e.g.:

    grant replication slave on *.* to ‘repl’@’192.168.107.33’ identified by ‘password’;

    test on master:
    create database repl;

    check on slave:
    show databases; /* should show new database */

    test on master:
    drop database repl;

    check on slave:
    show databases; /* new database should be dropped */

    Now it’s time to turn this into an automated shell script with Expect in there.

  • Part II: Getting to 600 Concurrent Users

    I couldn’t sleep last night. I’m worried we’ll lose this client.

    So just to be clear. I wasn’t part of the crew responsible for scaling this site. I had already set up a scalable architecture for the site, that would automatically and horizontally scale at Amazon. That idea got shot down for legal reasons that to my surprise haven’t been in play for awhile. Can we say, “Office politics?”

    I totally recommend Amazon’s Autoscaling to anybody that’s new to this.

    Instead of auto-scaling, the site was architected by a local San Francisco firm who I won’t mention here.

    Let’s just hope enough people read this so that they won’t even have to know the name of the company and will just know the smell of an un-scaleable architecture.

    Scalability requirement: 100,000 concurrent users

    This is how they set it up:

    • two web servers
    • one database
    • four video transcoders that hits the master database
    • one more app server that hits the master database
    • no slave db 😀

    If they had even googled ‘building scalable websites’ they would have come across a book that would have avoided all of this, Cal Henderson’s Building Scalable Websites. It should be mandatory reading for anybody working on a large website, and it just scratches the surface.

    So, how did we get to 600 concurrent users?

    We tweaked mysql by putting this in /etc/m.cnf:

    [mysqld]
    max_connections=10000
    query_cache_size=50000000
    thread_cache_size=16
    thread_concurrency=16 # only works on Solaris and is ignored on other OSes

    We ran siege and were able to get to about 300 concurrent users without breaking a sweat, but now apache was dying.

    So we tweaked apache. We started out with this:

    StartServers 8
    MinSpareServers 5
    MaxSpareServers 20
    ServerLimit 256
    MaxClients 256
    MaxRequestsPerChild 4000

    And ended up with this:

    StartServers 150
    MinSpareServers 50
    MaxSpareServers 200
    ServerLimit 256
    MaxClients 256
    MaxRequestsPerChild 4000

    RAM and CPU were doubled.

  • Scaling from 100 to 100000 concurrent users in a day?

    Well, it looks pretty bad right now. A vendor just ceded control for web application architecture. Initial tests say that the site won’t do no more 100 users concurrently.

    Who the hell makes a web app without a slave database and calls themselves website architects? Apparently these guys did.

    Please start following if you want to see if this web app can make it to launch.

  • App Identifier and Bundle Identifier Gotcha in iPhone Dev

    This is one of those things they don’t mention in the docs.

    When you create a provisioning profile for an iPhone app you get an app identifier. It looks like this:
    KED2IOCNA.com.codebelay.barceftw

    In order to get your iPhone app in development into your iPhone you got to have a bundle identifier. The docs that I’ve found so far tell you that your bundle identifier is the same as your app identifier. After struggling for close to 4 hours, I found out that your bundle identifier really is:
    com.codebelay.barceftw

    Just strip out the encrypted looking part and the dot (.) before com and you’re set.

  • Social Media Backup – What are the options now?

    Bad things happen:

    Dear Twitter,

    My Twitter page @mostlylisa has been hacked and deleted. It’s GONE!!! I am currently catatonic. Please help me restore my account, it’s like, my meaning in life.

    Much love to whom ever helps me!

    PS. If you miss me like I miss you, you can always be my Friend OR Fan on Facebook. I know it’s not the same, but it’s all I have now. *hold me*

    It only took twitter about 3 days to recover from this.

    djsteen

    Is there a faster way?

    First let’s look at the current options:

    • TweetBackup (NY Times)
    • BackUpMyTweets
    • If you are popular enough and folks raise a raucous, Twitter will go into the database back-up and restore your account into its pristine set up.

    BackupMyTweets required too much info to get it working. No, you cannot have my gmail password.

    I’ve tried Tweetbackup and they get kudos for using OAuth to make it easy to back your tweets up.

    The 3rd option, begging Twitter, simply can’t scale and will only work for those few elites close to Twitter or popular enough. There isn’t a consumer solution.

    How do we solve the problem of social media backup?

    The great thing is the problem is:

    • technical
    • can have the same business model as insurance
    • will gain recognition as more snafus happen

    Once again, if you haven’t already, use BackUpMyTweets.

  • Benchmarking Inserts on Drizzle and MySQL

    I’m not comparing apples to apples yet… but out of the box, drizzle does inserts faster than MySQL using the same table type, InnoDB.

    Here’s what I’m comparing:
    drizzle r1126 configured with defaults, and
    MySQL 5.1.38 configured with

    ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex \
    --enable-thread-safe-client --enable-local-infile --enable-shared \
    --with-plugins=partition,innobase
    

    which is really nothing complicated.

    SQL query caching is turned off on both database servers. Both are using the InnoDB engine plug-in.

    I’m running these benchmarks on a MacBook Pro 2.4 GHz Intel Core 2 Duo with 2GB 1067 MHz DDR3 RAM.

    I wrote benchmarking software about 2 years ago to test partitions but I’ve since abstracted the code to be database agnostic.

    You can get the benchmarking code at Github.

    At the command-line, you type:

    php build_tables.php 10000 4 drizzle

    where 10000 is the number of rows allocated total, and 4 is the number of partitions for those rows.

    You can type the same thing for mysql:

    php build_tables.php 10000 4 mysql

    and get interesting results.

    Here’s what I got:

    MySQL

    bash-3.2$ php build_tables.php 10000 4 mysql
    Elapsed time between Start and Test_Code_Partition: 13.856538
    last table for php partition: users_03
    Elapsed time between No_Partition and Code_Partition: 14.740206
    -------------------------------------------------------------
    marker           time index            ex time         perct   
    -------------------------------------------------------------
    Start            1252376759.26094100   -                0.00%
    -------------------------------------------------------------
    No_Partition     1252376773.11747900   13.856538       48.45%
    -------------------------------------------------------------
    Code_Partition   1252376787.85768500   14.740206       51.54%
    -------------------------------------------------------------
    Stop             1252376787.85815000   0.000465         0.00%
    -------------------------------------------------------------
    total            -                     28.597209      100.00%
    -------------------------------------------------------------
    20000 rows inserted...
    

    drizzle

    bash-3.2$ php build_tables.php 10000 4 drizzle
    Elapsed time between Start and Test_Code_Partition: 7.502141
    last table for php partition: users_03
    Elapsed time between No_Partition and Code_Partition: 7.072367
    -------------------------------------------------------------
    marker           time index            ex time         perct   
    -------------------------------------------------------------
    Start            1252376733.68141500   -                0.00%
    -------------------------------------------------------------
    No_Partition     1252376741.18355600   7.502141        51.47%
    -------------------------------------------------------------
    Code_Partition   1252376748.25592300   7.072367        48.52%
    -------------------------------------------------------------
    Stop             1252376748.25627400   0.000351         0.00%
    -------------------------------------------------------------
    total            -                     14.574859      100.00%
    -------------------------------------------------------------
    20000 rows inserted...
    

    MySQL: 699 inserts per second
    drizzle: 1372 inserts per second
    As far as inserts go, drizzle is about 2 times faster out of the box than MySQL.

  • If You Miss tr.im use j.mp

    I’ve been using j.mp for two weeks now and it’s filled the void that tr.im left after going out of business.

    j.mp

    Long Live j.mp.

  • Advice for Middle Management

    Your team will sabotage your career worse than any other nemesis at work, if you let them.

    Here’s what you need to know to protect yourself and your company from sabotage:

    Who’s popular? Yeah, I know. It sounds like highschool, but like then it’s still in important and socially real factor that’s now kept track of on social media sites.

    What is your team’s weakness as perceived by those outside? By the team itself? A good manager can appease the two.

    Whose skills are the most respected? Yup you have to get along with this douchebag, if she or he is one. Just create enough space between the two of you.

    Any others?