Scaling applications
One of the killer features of computing in the cloud is that it (should) seamlessly allow you to scale up or down your applications to meet your needs and whims. Juju not only makes it simple to deploy applications, but crucially makes it easy to manage them too. It won't anticipate you getting slashdotted or on the front page of hacker news (yet), but it does mean that when you do you can reliably scale your applications to meet the demand.
Adding Units
The general usage to scale an application up is via the add-unit
command:
juju add-unit [options] <application-name>
The command options are:
Options:
-m, --model (= "")
Model to operate in. Accepts [<controller name>:]<model name>
-n, --num-units (= 1)
Number of units to add
--to (= "")
The machine and/or container to deploy the unit in (bypasses constraints)
Scaling behind a Load Balancer
In many cases you just can't add more units to an application and have it magically scale - you need to use a load balancer. In this case you can just deploy a proxy in front of your units; let's deploy a load balanced MediaWiki:
juju deploy haproxy
juju deploy mediawiki
juju deploy mysql
juju add-relation mediawiki:db mysql
juju add-relation mediawiki haproxy
juju expose haproxy
The haproxy charm configures and installs an HAProxy (http://haproxy.1wt.eu/) application, the widely used TCP/HTTP load balancer. When you add a relation between the MediaWiki instance and HAProxy, it will be configured to load balance requests to that application. Note that this means the web traffic should be directed to the HAProxy instance. Running:
juju status haproxy
will return the public IP for the load balancer. This is the IP you want to point your DNS to.
Now that you are behind a load balancer, you can grow the MediaWiki instances behind the proxy as you see fit, let's add 5 more:
juju add-unit -n 5 mediawiki
You don't need to worry about manually adding your units to the load balancer. You've made the relationship at the application level, so the new units know exactly how to relate. Juju is also smart enough to ensure that the new units are installed and configured before adding them to the load balancer, ensuring minimal user disruption of the application.
Scaling Charms with built in Horizontal scaling
Some charms have native scaling built in. For instance, the WordPress charm has built in load balancing. In this case, scaling up applications is really as simple as requesting more instances. Note that this feature is charm specific, not all charms can scale this way. Consider the following setup for a WordPress:
juju deploy mysql
juju deploy wordpress
juju add-relation mysql wordpress
juju expose wordpress
When you notice the WordPress instance is struggling under the load, you can simply scale up the application:
juju add-unit wordpress
This will cause a new instance to be run and configured to work alongside the currently running one. Behind the scenes, Juju is adding an instance to the model and provisioning the specified application onto that instance/machine.
Now suppose your MySQL application needs hyperscale, you can use the -n
or
--num-units
options to add-unit
to specify the desired number of units you
want added to the application. For example, to scale up your application by 100
units simply do:
juju add-unit -n 100 mysql
or you can use --num-unit
which has the same result, but is more readable:
juju add-unit --num-unit 100 mysql
Co-location
As with the juju deploy
command, it is possible to co-locate applications on
machines.
If you would like to add a unit to a specific machine just append the --to
option, for example:
juju add-unit mysql --to 23
...adds a unit to machine 23,
juju add-unit mysql --to 24/lxc/3
...adds a unit to lxc container 3 on host machine 24.
It is worth noting that not all applications will happily co-exist and it is much safer to create a new container when co-locating:
juju add-unit mysql --to lxc:25
...add unit of mysql to a new lxc container on host machine 25
Constraints
The add-unit
command deploys a machine matching the constraints of the
initially deployed application. For example, if MySQL was deployed with the
defaults (i.e. no --constraints
option) you would have MySQL on an instance
that matches the closest to 1 Gigabyte of memory and 1 CPU available. If you
would like to add a unit with more resources to the MySQL application you will
first need to issue a add-machine
with the desired constraint followed by a
add-unit
. For example, the following command adds a 16 Gigabyte unit to the
MySQL application (note in this example juju status
returns machine 3 for the
add-machine
command):
juju add-machine --constraints="mem=16G"
juju add-unit mysql --to 3
Scaling Back
Sometimes you may want to scale back some of your applications, and this too is easy with Juju.
The general usage to scale down an application is with the remove-unit
command:
juju remove-unit [options] <unit> [...]
For example, the following scales down the MediaWiki application by removing a specific unit:
juju remove-unit mediawiki/1
If you have scaled-up the MediaWiki application by more than one unit you can remove multiple units in the same command:
juju remove-unit mediawiki/1 mediawiki/2 mediawiki/3 mediawiki/4 mediawiki/5
Note: The unit numbers may not necessarily be sequential, see the notes on machine/unit numbering
The remove-unit
command can be run to remove running units safely. The
running applications should automatically adjust to the change. If the machine
the removed unit was running on is not being used as a controller, or hosting
other Juju managed containers, it will be destroyed automatically.
Note:
If a machine has no running units, controllers or containers, and
hasn't been removed automatically, it can be removed with the remove-machine
command. For example, to remove machine 1 that the unit mediawiki/1
was
housed on, use the command:
juju remove-machine 1
For more information on removing applications, please see the section on destroying applications.