Sharded Deployments with MongoDB and Brooklyn, a Framework for Scaling

The nature of distributed architecture requires the user to think through how apps and services may run across multiple cloud services and data centers. Apps are one thing, but running a database in these types of environments carries a different level of complexity.
In this example, we are going to create a more complicated service involving MongoDB and sharding. We will then show you how you can use effectors to scale this service out or in.
MongoDB offers some pretty advanced options for scaling, both horizontally and vertically. So, we’re going to look at how to create a sharded deployment (like that described in the figure above) with the Brooklyn plugin.
Create a Sharded Deployment Service
First, taking advantage of our new ability to specify blueprints in the application manifest, under the Brooklyn section, create a MongoDBShardedDeployment service:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<tt>applications: - name: my-app memory: 512M brooklyn: - name: Sharded MongoDB location: localhost services: - type: brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment id: mongo name: Mongo DB Backend provisioning.properties: minRam: 16gb brooklyn.config: initialRouterClusterSize: 1 initialShardClusterSize: 5 shardReplicaSetSize: 3</tt> |
Notice with the blueprint, you can also specify provisioning properties and configure the sharded deployment. We have specified a minimum of 16GB of RAM with one router, five shards and three nodes per shard in this blueprint. Simply push this blueprint …
1 2 3 4 5 6 7 8 9 |
<tt>$ cf brooklyn push Running the brooklyn command Enter broker: brooklyn Enter username: user Enter password: simple-password ... OK </tt> |
and you have a sharded deployment of MongoDB.
Examine the Sensors
As we saw in part two, you can view the sensors associated with a running service with the sensors command, so let’s do that with this service:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
<tt>$ cf brooklyn sensors brooklyn user simple-password "Sharded MongoDB" Sharded MongoDB --------------- Entity:Mongo DB Backend service.state : RUNNING ... Cluster of MongoDBConfigServer (LocalhostMachineProvisioningLocation{id=Bg7x8Kpi, name=localhost}) service.state : RUNNING mongodb.config.server.addresses : [127.0.0.1:27019 127.0.0.1:27020 127.0.0.1:27021] ... MongoDBConfigServer:buuD service.state : RUNNING host.address : 127.0.0.1 mongodb.server.port : 27019 ... MongoDBConfigServer:v3Uq service.state : RUNNING host.address : 127.0.0.1 mongodb.server.port : 27020 ... MongoDBConfigServer:rHuG host.address : 127.0.0.1 service.state : RUNNING mongodb.server.port : 27021 ... quarantine group.members : [] group.members.count : 0 ... Cluster of MongoDBRouter (LocalhostMachineProvisioningLocation{id=Bg7x8Kpi, name=localhost}) service.state : RUNNING ... MongoDBRouter:JScw service.state : RUNNING mongodb.router.config.shard.count : 5 host.address : 127.0.0.1 mongodb.server.port : 27018 ... quarantine group.members : [] group.members.count : 0 ... Cluster of MongoDBReplicaSet (LocalhostMachineProvisioningLocation{id=Bg7x8Kpi, name=localhost}) group.members.count : 5 service.state : RUNNING ... Cluster of MongoDBServer (LocalhostMachineProvisioningLocation{id=Bg7x8Kpi, name=localhost}) service.state : RUNNING mongodb.server.network.bytesIn : 318844 group.members.count : 3 ... MongoDBServer:GApX mongodb.server.network.bytesIn : 145177 host.address : 127.0.0.1 mongodb.server.network.bytesOut : 883410 mongodb.server.port : 27027 service.state : RUNNING ... MongoDBServer:Ep4N mongodb.server.network.bytesOut : 761446 mongodb.server.network.bytesIn : 87014 mongodb.server.port : 27026 host.address : 127.0.0.1 service.state : RUNNING ... MongoDBServer:EqDn mongodb.server.port : 27035 service.state : RUNNING mongodb.server.network.bytesIn : 86653 mongodb.server.network.bytesOut : 763923 host.address : 127.0.0.1 ... quarantine group.members : [] group.members.count : 0 ... ... quarantine group.members : [] group.members.count : 0 ... OK </tt> |
In this example, there are lots of entities and many more sensors, but a few are worth pointing out: service.state shows whether the entity is running; host.address and mongodb.server.port show how to connect to the individual MongoDB servers, should you need to; and mongodb.server.network.bytesIn and mongodb.server.network.bytesOut show how much traffic is coming in and out.
Scale it Back Using Effectors
So, looking at the sensors, suppose we decide we would like to scale back the number of shards to one. To find out which effector to use for that, we use the effectors command:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<tt>$ cf brooklyn effectors brooklyn user simple-password "Sharded MongoDB" Sharded MongoDB --------------- Application:m6obgkNz m6obgkNz:start Start the process/service represented by an entity parameters: locations The location or locations to start in, as a string, a location object, a list of strings, or a list of location objects m6obgkNz:restart Restart the process/service represented by an entity m6obgkNz:stop Stop the process/service represented by an entity Mongo DB Backend htgPyEms:restart Restart the process/service represented by an entity htgPyEms:start Start the process/service represented by an entity parameters: locations The location or locations to start in, as a string, a location object, a list of strings, or a list of location objects htgPyEms:stop Stop the process/service represented by an entity Cluster of MongoDBReplicaSet (LocalhostMachineProvisioningLocation{id=Bg7x8Kpi, name=localhost}) cfgFazAk:restart Restart the process/service represented by an entity cfgFazAk:start Start the process/service represented by an entity parameters: locations The location or locations to start in, as a string, a location object, a list of strings, or a list of location objects cfgFazAk:stop Stop the process/service represented by an entity cfgFazAk:resizeByDelta Changes the size of the cluster. parameters: delta The change in number of nodes cfgFazAk:resize Changes the size of the entity (e.g. the number of nodes in a cluster) parameters: desiredSize The new size of the cluster cfgFazAk:replaceMember Replaces the entity with the given ID, if it is a member; first adds a new member, then removes this one. Returns id of the new entity; or throws exception if couldn't be replaced. parameters: memberId The entity id of a member to be replaced ... OK </tt> |
The one we need is cfgFazAk:resize so let’s invoke that:
1 2 3 4 5 |
<tt>$ cf brooklyn invoke brooklyn user simple-password "Sharded MongoDB" cfgFazAk:resize --desiredSize 1 Invoking effector cfgFazAk:resize 1 OK </tt> |
Scale it Back Out
And if we need to scale back out again, we simply run the same command again but with the parameter changed:
1 2 3 4 5 |
<tt>$ cf brooklyn invoke brooklyn user simple-password "Sharded MongoDB" cfgFazAk:resize --desiredSize 3 Invoking effector cfgFazAk:resize 3 OK </tt> |
What about increased replication? Just look at the effectors to find the cluster you want to increase and run the same command:
1 2 3 4 5 |
<tt>$ cf brooklyn invoke brooklyn user simple-password "Sharded MongoDB" RaArKduP:resize --desiredSize 5 Invoking effector RaArKduP:resize 5 OK </tt> |
Video
To wrap up this post, once again, here is a video of our plugin in action:
Next Time
In previous posts, we saw the basics of using the Cloud Foundry Service Broker and Plugin to manage Brooklyn services, from creating services in the catalog to adding new items to the catalog; from specifying catalog items in the manifest to specifying new types of services in the catalog. And now we’ve seen a bigger service that we can control using sensors and effectors.
But Brooklyn has more, and in the next part we are going to show you how to deploy an application to Cloud Foundry with multi-cloud, polyglot persistence provided by Apache Brooklyn. See you then.
Cloudsoft is a sponsor of The New Stack.
Feature image via Flickr Creative Commons.