blog

We're building the discovery engine for the social web. News about the journey.

Otto: unifying deployment, application management, and platform management

At Spindle, our local search results are powered by a low-latency content fetching pipeline, a real-time query service, and a scalable content notification engine. We’re constantly making changes to these backend applications, so we built a system to automate the tedious deployment work for us. Today, we’re releasing that project, Otto, under the open-source Apache 2.0 license. We’ve published Otto along with a full tutorial at https://github.com/spindlelabs/otto.

Fixing deployment

Before we started building Otto, we thought carefully about the properties of our ideal deployment system. That ideal deployment system must offer:

  • Simplicity, transparency, and predictability. It should be easy for an engineer to understand how the system works, what actions it will take, and how those actions will be performed.

  • Painless application version changes. Our most common deployment operation is bumping the version of an application. Because we do this so often, it needs to be easy and fast in both development and in production environments.

  • Easy deployment to new servers. We frequently add and replace servers. Deploying an application to a new server should be as easy and as reliable as deploying a change to an existing server.

  • Fault tolerance. Our application runs on many servers across several datacenters. Network links and individual servers occasionally fail; the system should retry failed deployments as necessary.

  • Technology independence. Our own applications are written in Scala, Python, or Bash, and we also need to deploy third-party applications like elasticsearch and Jenkins. The system should not require special application-level support.

  • Artifact repository independence. The deployment system should be able to download artifacts from a build server such as Jenkins or from an external repository like Amazon S3.

  • Change notification and history tracking. Because we make changes so often, understanding the history of our environment can be critical for troubleshooting a problem or finding the cause of a performance regression.

  • Partial application deployment. It should be possible to deploy a new version of an application to a subset of eligible servers. Consider an experimental performance hotfix: with a partial deployment, engineers can monitor metrics like request latency and error rate before deciding whether to roll out the change to all servers.

  • Rolling application deployment. Deploying a new version of an application shouldn’t upgrade all servers simultaneously; changes should be rolled out gradually to maintain service availability.

  • Safe rollback. If a deployment is aborted, servers that have not yet taken the change should remain unaffected, and servers that have taken the change should be restored to their previous state.

  • Scheduled deployment. The deployment system should support scheduled deployments such as automatically deploying the latest successful daily build to the QA environment every day at 3am.

From deployment to application management

Traditionally, “deployment” has meant one-off, single-shot attempts to put the correct set of bits on the correct set of servers. But we’ve found that our needs are broader: we need application management, not just deployment. Our ideal application management system must offer:

  • Separation of privilege. Our applications should run as unprivileged users to reduce the impact of a compromised application.

  • Configuration drift prevention. An engineer may manually make a one-off change to an individual server’s configuration to address a problem; if the server is replaced, that change will be lost and the problem will reoccur. The system should prevent configuration drift by making it easy for an engineer to record these configuration changes properly and by ensuring that the effective configuration always matches the recorded configuration across all servers.

  • Application runtime management. Startup scripts are notoriously difficult to write, and few startup scripts restart the application after a crash. The system should make it easy to write correct, safe startup scripts, and the system should automatically restart the application if it fails.

  • Easy configuration changes. Often, we’ll need to make a small configuration change such as changing a timeout or a resource limit; we shouldn’t have to deploy a new build of the application to make these changes.

From application management to platform management

As we mentioned, some of these requirements are completely out of scope for the traditional single-shot application deployment tool. But there’s another problem: deploying some of our applications requires updating the server configuration. For example, our front-end application requires the Java virtual machine, nginx, and our SSL certificates; our search server requires software RAID. Our applications can’t run correctly without these changes.

More generally, our applications have platform dependencies: they depend on the correct configuration of software we didn’t write. We’ve shown that we care about application management, not just deployment. But these platform dependencies mean that we’ll need to manage the platform in order to deploy and manage the application. This presents a difficult question: where does the platform management end and application management begin? After all, you don’t know what you do until you know what you don’t do.

At Spindle, we found that we could solve all three problems with the same approach. We built Otto: Otto unifies deployment, application management and platform management (in 250 lines of code!)

Puppet: solid platform management

It turns out that many of our requirements we described above have already been addressed at the platform layer by Puppet. Otto extends Puppet to better support the application layer.

Puppet provides solid platform management. With Puppet, administrators move from scripting sequences of imperative operations to simply declaring the desired system state and letting Puppet handle the details. Consider, for example, configuring nginx to support our front-end web application. A traditional script would copy our SSL certificates, invoke the package manager to install nginx 1.2.4, and then restart the service. With Puppet, the administrator instead models the desired state of the system by specifying resources (“the Debian package named nginx”), attributes (“version 1.2.4”, “is installed”), and dependencies (“ensure the SSL certificates are present before installing nginx”, “restart nginx if the certificates have changed”). Then Puppet brings the server into compliance with the administrator’s model. If the certificates change, Puppet will notice that the system is out of compliance, replace the files, and then restart nginx; it’s not necessary to write a one-off imperative script to log into every server, change the certificates, and then restart nginx manually.

Puppet has comprehensive support for managing platform resources such as files, mount points, packages, and cron jobs. Puppet offers a straightforward domain-specific language for crafting models, and the DSL hides OS-specific implementation details like the underlying package manager. Puppet is popular, powerful, and well-documented, and several companies offer commercial support.

Here’s an example of a simple Puppet model:

 user { 'dave':
  ensure     => present,
  uid        => '507',
  gid        => 'admin',
  shell      => '/bin/zsh',
  home       => '/home/dave',
  managehome => true,
 }

This model specifies, among other things, that the user “dave” should exist and his shell should be zsh. When the model is applied to a new server, Puppet will create the user:

  # puppet apply dave.pp
 notice: /User[dave]/ensure: created
 

If this model is immediately reapplied, Puppet will make no changes: it will interrogate the system and find it in compliance with the model, so no changes will be necessary. If the administrator changes dave’s shell to bash and then reapplies the model, Puppet will change dave’s shell to bring the system into compliance with the model.

Puppet for applications

Out of the box, Puppet offers unparalleled platform management. Otto extends Puppet with application deployment and management support. In particular, Otto adds application models; these application models include support for deployment (retrieving the application artifact), runtime management (starting, stopping, and restarting the application), and configuration. With Otto, we can model our applications the same way we modeled users:

  class { 'spindle::frontend':
    jenkinsProjectName => 'master-checkin',
    jenkinsBuildID => '104'
  }

When this model is applied to a new machine, Puppet will download build 104 of our frontend application from the master-checkin project on our Jenkins server. It will install and configure all dependencies including nginx and the Java virtual machine. If a different build of the application was already installed, it is updated to build 104 and any other configuration differences are resolved.

Within the definition of spindle::frontend, we define our static assets, nginx configuration, SSL certificates, and the Scala application that handles dynamic requests. (For a concrete example, see the sample application definition included with the Otto source code.) The Scala application definition includes a definition for the Java virtual machine and details of how to retrieve the artifact from our build server. We also include a script to start the frontend application; after all dependencies have been satisfied, Otto starts the application and ensures that it continues running.

To deploy the next build of the frontend, we just change 104 to 105. The most straightforward way to make this change is to edit the model file directly, but we could also find the build number by querying a database or calling out to external code (using extlookup(), generate(), or an external node classifier). With these features, you could implement partial deployment (“only 1 in 4 servers should run the experimental hotfix”), continuous deployment (“always run the latest successful build”), triggered deployment (“deploy the new build when traffic is less than 10 QPS over the last 15 minutes”), and automatic rollback (“revert the latest change if the error rate increases by 50%”). These external lookup features are provided by Puppet, not Otto; by building on Puppet’s solid platform management, Otto creates a powerful application deployment and management system.

Similarly, to deploy a configuration change, we just make the change in the Puppet model. Puppet detects the change, atomically updates the configuration file, and then notifies the application of the change by restarting it. Otto takes advantage of Puppet’s existing support for file management and change notification to eliminate application configuration drift.

If Puppet notices that a server is not running the correct build of the application, it will download the new build and install it. If that download fails, it will log an error and abort the change; it will make no further modifications to the server. Therefore, the existing version of the application will continue to run. The next time Puppet runs (by default, once every 30 minutes), it will again notice the conflict and attempt to resolve it. Because Otto is built on Puppet, it can handle the failure automatically.

Puppet has a full model of the system’s desired state. Therefore, it can install a new application just as easily as it can modify an existing application. So no special support is required for Otto to deploy an application on a freshly-installed server.

Otto in practice

We have been using Otto in production for close to a full year. We deploy new code and configuration with Otto several times a day.

We store our Puppet configuration in git. Because Puppet is configured with flat text files, we can use the standard Git toolkit to view the history of our configuration and to send notifications whenever a developer makes a change. Git also makes it easy for us to roll back a change by reverting the appropriate commit.

We use a masterless Puppet configuration: each server is responsible for applying its own configuration, so we don’t have to maintain a dedicated Puppet master. We use Ubuntu cloud-init to bootstrap our servers with Puppet as soon as they are provisioned.

Otto has preserved our sanity in an environment with more backend applications than backend engineers. Today, we’re releasing Otto under the open-source Apache 2.0 license. We’ve published the source code at https://github.com/spindlelabs/otto. We’ve included a sample application as well as a tutorial for deploying and managing it. We hope you find Otto as useful as we have!

Alex Lambert

Rolling Out

Over the past few months we’ve worked hard to accelerate our geographic rollout, and today we’re happy to announce Spindle 2.2, with availability in five new regions: Denver – Boulder; Las Vegas; Portland, OR; Research Triangle, NC; and Washington, D.C.! This is our first five-city release, and comes hot on the heels of Spindle’s Los Angeles rollout, our single largest city by data size. I want to share a little about why this is an important step for Spindle.

Downtown LA

A Little Background

Our place database is one of our most valuable assets, and correct listing information — location, category, website, social network accounts — is critical to the way Spindle evaluates whether a post is interesting and relevant at a particular time and place. We use a number of data sources to build our business listings, including Factual Places, Facebook’s Graph API, and our own web crawler, among others.

While these sources are a great start, our unified listings still require a fair amount of de-duplication, validation, and enrichment before they’re ready for primetime. To this end, we employ a data hygiene approach that blends algorithmic correction, crowdsourced judgment via CrowdFlower, expert validation by our in-house Data Quality team, and feedback submitted from within the app. To give some idea of the scope of this effort, in just our first 12 cities we maintain 3.6M place listings, with another 800K listings in process for two cities we’re adding very soon.

An Audacious Goal

While preparing our first three cities — Boston, San Francisco, and New York — we invested considerable manual effort cleansing and analyzing the idiosyncrasies in our place data. We recognized early on that this approach wouldn’t scale, but it was necessary to understand which elements of the data processing pipeline we could automate or crowdsource. Earlier this year, we set ourselves a bold goal: To bring down the cost of preparing a city by a full order of magnitude, and reduce per-city time to market by at least 50%. We’re happy to say that, through a series of optimizations and the automation of previously labor-intensive processes, we’ve achieved this goal and continue to pick up the pace of our rollout. Look for more major cities coming very soon!

Check out the latest version of Spindle, and let us know what you think!

— Alex J.

Spindle Expands to Los Angeles

Few cities offer the diverse possibilities of Los Angeles: You can surf in the morning, check out unique shops during the day, have dinner at a world-class restaurant, and catch an amazing band at night. But in a city as dynamic as LA, it’s sometimes hard to discover the best stuff happening. That’s why Spindle is excited to announce availability in Los Angeles, including the LA basin, Orange County, and Santa Barbara!

Downtown LA

Spindle helps you experience more of LA by casting a wide net for the most relevant, timely, and useful updates from all kinds of places — restaurants, bars, shops, music venues, galleries, parks, and other organizations. Unlike other local apps, Spindle’s results update constantly, so what you see on a weekday afternoon will be totally different from what you see on a Saturday morning.

And you don’t even need to open Spindle to stay tuned into what’s happening in LA. When you Favorite the places you care about and create search alerts about your interests — for example, “live music” or “free yoga class” — Spindle monitors nearby updates and sends timely and interesting notifications so you don’t miss out!

Download Spindle today, and please let us hear your thoughts!

— Alex J.

Announcing Spindle 2.0

Early feedback tells us that you enjoy browsing Spindle’s feeds to discover what’s happening, but there are times when you want to search for something more specific. So as we worked on our latest version, our goal was to give you greater power and control over how you find and navigate results, and get notified about what’s happening nearby. Today we’re excited to announce Spindle 2.0, with keyword search, maps, and search alerts, plus expanded coverage that now includes Austin, Chicago, and Seattle!

image

A Better Way to Search

Unlike other services that just deliver stale business recommendations or allow you to search a fixed list of places by name, our new keyword search feature lets you tap the always-fresh stream of local updates to find exactly what interests you. And with our new maps, you can pan, zoom, and swipe to pinpoint exactly where great stuff is happening.

Whether you’re looking for a “free yoga class,” a “craft beer” on tap, “live jazz,” a restaurant promotion where “kids eat free,” or a place to watch tonight’s “Celtics game,” you can find a needle in the haystack with Spindle search.

At Your Service

Spindle takes another leap forward with search alerts, coupling the app in your pocket with a cloud-based search service that runs continually on your behalf. When you create search alerts, Spindle monitors nearby updates and sends timely notifications if places mention the topics you’re tracking. It’s a great way to find out when things you care about are happening nearby, without even opening the app.

Download Spindle 2.0 today, and let us hear your thoughts!

— Alex J.

The Oscars on Spindle

Looking to get out and have some fun during the Oscars? Spindle is here to help. Here are a few ideas to get you started. 

Boston

  • King’s Back Bay is having an Oscars Pajama Party at 7pm with a chance to win Netflix for a year - more
  • Sweet Caroline’s is throwing a party and offering free appetizers - more.
  • Trident Booksellers & Cafe has champagne and big screens starting at 7pm - more.
  • The Brattle Theatre has a few seats left for their showing - more.
  • Drink has become a viewing lounge for the evening - more.
  • Kinsale Irish Pub and Restaurant is having an Oscar Karaoke Party at 8:30 - more.
  • Georgetown Cupcake has a special treat for the Oscars - more

New York City

  • The Cornerstone Tavern is throwing a party and taking ballots - more.
  • Lavo NYC has a black tie screening at 8pm - more
  • The Mad Hatter Saloon has $5 Oscartini’s and draft beers - more
  • Maxwell’s Bar & Restaurant has $5 Bloody Marys & Mimosas. $4 tap beers - more.
  • Chelsea Wine Vault is 10% off for people hosting a party at home - more
  • 508 Gastrobrewery has a fixed price. 2 items and all you can drink for $45 - more.
  • Gramercy Park Bar & Grill has $20 bottomless wine and several other discounted drinks - more
  • The City Winery is showing the Oscars in their Barrel Room - more

San Francisco

  • OMG is throwing a party. Starts at 4pm - more.
  • Moby Dick Bar is offering 2 for 1 sex on the beach cocktails - more.
  • The Roxie Theatre is screening the Oscars. Doors open at 3:45 - more.
  • Extreme Pizza is offering 25% off for anyone watching at home - more.
  • Prospect Restaurant is offering complimentary prosecco - more

Check Spindle to see everything else that’s happening nearby - so much more to choose from. 

Why Spindle Chose Responsive Design

Most people first experience Spindle by either visiting our website from a press piece, or opening a place page that a friend shared on Facebook or Twitter. And about 25% of new visitors are using a mobile browser on a phone (19%) or tablet (6%). We know first impressions last, so we’re using responsive web design (RWD) techniques to ensure that our site looks great and works well however you access it.

What Exactly Is Responsive Design?

In the most basic terms, RWD is an approach to developing flexible web pages. The design of each page is automatically adjusted and optimized for the screen size using CSS and media query targeting. Because we don’t have to maintain separate sites, resources, or redirects, it’s much easier to manage and update a RWD structure. And on the social web where links can travel anywhere — emailed on a desktop, opened on an iPhone, posted to Facebook and viewed on an Android — RWD is the best way to guarantee that everybody has an optimal page viewing experience.

Approach

When we started creating our RWD structure, we needed to make some early information hierarchy and layout decisions. With their limited bandwidth and screen real estate, phones present the most limiting form factor; so we designed the smallest screen layouts first, forcing us to prioritize the information that’s most important in a mobile context.

For example, on our mobile landing pages we decided it was important to prioritize peoples’ shared notes and content; so those elements occupy the space “above the fold.” As the page widens on larger form factor devices, these elements maintain priority, but an additional column appears, allowing us to present business listing information above the fold.

Once we had a finalized scaffolding to guide us through the design phase, we began to think about the best way to construct pages. We decided to base the page structure on the Twitter Bootstrap grid system, a well supported and documented framework that allowed us to hit the ground running with page layout.

Transferring static designs into flexible pages can get a bit tricky, so we created mock-ups for 3 primary form factors that cover the broadest range of current users: portrait iPhone, portrait iPad, and roughly a 15” monitor. Following the mock-up phase, remaining design tasks like selecting exact media query breakpoints were done while developing in the browser.

On top of Twitter Bootstrap we chose to write SCSS, a CSS-extension syntax that makes for a quicker and more manageable development cycle. With the addition of mix-ins from Compass and an Object Oriented CSS (OOCSS) approach, we could write and reuse common styles — things like colors and shadows — much more efficiently than with standard CSS alone.

When constructing the pages we wrote visual styles using CSS3 as much as possible, but bitmap images were still required for some elements, like the Spindle logo and certain icons. Because we know that people are viewing our site on Apple devices with retina displays, we employ HiDPI images. There are many different ways to render @2x images in the web, but we decided on Retina.js for its light footprint, easy implementation and hands-off support for in-line images.

Overall we are pretty happy with the way the pages came out. Feel free to click around and resize your browser to see how the responsive layout updates on the fly, and let us know if you have any questions or feedback.

Steve