2011-02-12

python!

After a break, I've decided to pick up a new project - learn python. I have a specific work goal in mind - create a small application to create, manage, remove, map, etc. CloudFront distributions that use a custom origin server, i.e. not S3, across multiple AWS accounts. It seems that boto is way to go. It has an uphill battle - the AWS provided SDKs are really quite easy to use and are well documented.

EDIT: Gah! Talking about leaping before looking! I pull up the boto API reference page on cloudfront and I see the following:
This module is not well tested. Paging of distributions is not yet supported. CNAME support is completely untested. Use with caution. Feedback and bug reports are greatly appreciated.
Sounds not quite ready for a) learning python b) using at work. <sigh> Learning python is still the next project, but I won't be using it for this concept.

2011-01-28

Splitting traffic with an F5 BigIP LTM iRule

Another item filed under "notetoself" - how to split traffic by URI with an iRule applied to a virtual server on an F5 BigIP LTM.

when CLIENT_ACCEPTED {
set default_pool [LB::server pool]
}
when HTTP_REQUEST {
if { [HTTP::uri] starts_with "/path/to/split/off" } {
pool pool_to_split_to
} else {
pool $default_pool
}
}
Normally, I am against this type of hack. I believe that content should have a unique location - if there's two URLs that can get you to the same bit of content, people will use them interchangeably and it will cause nothing but headaches. However, in this case the $default_pool content is a Tomcat stack running a custom framework backed by Oracle and the pool_to_split_to is a LAMP stack running drupal backed by MySQL e.g. they couldn't be any different. This is the best way to unify the URL to access both without creating unnecessary extra hops across the network (say, using apache's mod_proxy_http).

2011-01-26

Autoscaling revisited

Shortly after writing my previous post about AWS autoscaling, Amazon updated the autoscaling methodology. Instead of triggers they now use autoscaling policies and alarms from CloudWatch to initiate the policy actions. So here's how I create and remove policies and alarms from an autoscaling group. Note: you can't have both triggers and policies on a group, you have to remove the triggers first before adding the policies.

#
# create policies that will scale the group up and down
# note: cooldown is how many seconds to wait before
# applying the policy again
#
export COOLDOWN=300
export SCALEUP=`as-put-scaling-policy $ASGROUP-scaleUp \
--auto-scaling-group $ASGROUP \
--cooldown $COOLDOWN \
--adjustment=1 \
--type ChangeInCapacity`
if [ $? -eq 0 ]; then echo OK - $SCALEUP; else echo ERROR; fi

export SCALEDOWN=`as-put-scaling-policy $ASGROUP-scaleDown \
--auto-scaling-group $ASGROUP \
--cooldown $COOLDOWN \
--adjustment=-1 \
--type ChangeInCapacity`
if [ $? -eq 0 ]; then echo OK - $SCALEDOWN; else echo ERROR; fi

#
# create alarms to implement policies
#

#
# example: Latency on the ELB
#
mon-put-metric-alarm \
--alarm-name $ASGROUP-HighLatency \
--namespace "AWS/ELB" \
--metric-name Latency \
--statistic Average \
--period 60 \
--comparison-operator GreaterThanThreshold \
--threshold 5.0 \
--unit Seconds \
--evaluation-periods 5 \
--dimensions "LoadBalancerName=$LBNAME" \
--alarm-actions $SCALEUP
if [ $? -eq 0 ]; then echo OK; else echo ERROR; fi

mon-put-metric-alarm \
--alarm-name $ASGROUP-LowLatency \
--namespace "AWS/ELB" \
--metric-name Latency \
--statistic Average \
--period 60 \
--comparison-operator LessThanThreshold \
--threshold 0.5 \
--unit Seconds \
--evaluation-periods 5 \
--dimensions "LoadBalancerName=$LBNAME" \
--alarm-actions $SCALEDOWN
if [ $? -eq 0 ]; then echo OK; else echo ERROR; fi


And to clean up:

mon-delete-alarms --alarm-name $ASGROUP-HighLatency --force
mon-delete-alarms --alarm-name $ASGROUP-LowLatency --force
as-delete-policy $ASGROUP-scaleUp --auto-scaling-group $ASGROUP --force
as-delete-policy $ASGROUP-scaleDown --auto-scaling-group $ASGROUP --force

2010-11-11

Dumping memcached

I needed to see if memcached was getting the values I thought it was getting. Everyone knows about "stats" to see if it is getting activity, but I looked around and found that it is possible to get some of that data out without knowing how your app stores the data. So I wrote a script to do it:

#!/bin/sh
HOST="localhost"
if [ "$1" != "" ]; then HOST=$1; fi
COUNT=100
if [ "$2" != "" ]; then COUNT=$2; fi
for slab in `echo "stats items" | nc $HOST 11211 | grep :number | cut -d: -f2 -`
do
for item in `echo "stats cachedump $slab $COUNT" | nc $HOST 11211 | grep "^ITEM" | cut -d" " -f2 -`
do
echo "get $item" | nc $HOST 11211
done
done

Ratings and Recommendations by outbrain