Archive for September, 2010

Linux Kernel Tuning for C500k

Like the idea of working on large scale problems? We’re hiring talented engineers, and would love to chat with you – check it out!

Note: Concurrency, as defined in this article, is the same as it is for The C10k problem: concurrent clients (or sockets).

At Urban Airship we recently published a blog post about scaling beyond 500,000 concurrent socket connections. Hitting these numbers was not a trivial exercise so we’re going to share what we’ve come across during our testing. This guide is specific to Linux and has some information related to Amazon EC2, but it is not EC2-centric. These principles should apply to just about any Linux platform.

For our usage, squeezing out as many possible socket connections per server is valuable. Instead of running 100 servers with 10,000 connections each, we’d rather run 2 servers with 500,000 connections apiece. To do this we made the socket servers pretty much just socket servers. Any communication between the client and server is passed through a queue and processed by a worker. Having less for the socket server to do means less code, cpu-usage, and ram-usage.

To get to these numbers we must consider the Linux kernel itself. A number of configurations needed tweaking. But first, an anecdote.

The Kernel, OOM, LOWMEM, and You

We first tested our code on a local Linux box that had Ubuntu 64-bit with 6GB of RAM, connecting with several Ubuntu VMs per client using bridged network adapters so we could ramp up our connections. We’d fire up the server and run our clients locally to see just how many connections we could hit. We noticed that we could hit 512,000 with our Java server not even breaking a sweat.

The next step was to test on EC2. We first wanted to see what sort of numbers we could get on “Small” instances, which are 1.7GB 32-bit VMs. We also had to fire up a number of other EC2 instances to act as clients.

We watched the numbers go up and up without a hitch until, seemingly randomly, the Java server fell over. It didn’t print any exceptions or die gracefully—it was killed.

We tried the same process again to see if we could replicate the behavior. Killed again.

Grepping through syslog, we found this line:

Out of Memory: Killed process 2178 java

The OOM-killer killed the Java process. Having watched the free RAM closely, this was odd because we had at least 500MB free at the time of the kill.

The next time we ran it we watched the contents of /proc/meminfo. What we noticed was a steady decline of the field “LowFree”, the amount of LOWMEM that is available. LOWMEM is the kernel-addressable RAM space used for kernel data. Data like socket buffers.

As we increased the number of sockets each socket’s buffers increased the amount of LOWMEM used. Once LOWMEM was full the kernel (instead of simply panicking) found the user process responsible for the usage and promptly killed it so it could continue to function.

On a standard EC2 Small, the configuration is such that the LOWMEM is around 717MB and the rest is “given” to the user. The kernel is smart about reallocating LOWMEM for the user, but not the other way around. The assumption is that the kernel will use very little ram, or at least a predictable finite amount, and the user should be allowed to go crazy. What we needed with our socket server was just the opposite. We needed the kernel to use all the ram it needed—our Java server rarely uses above a few hundred MB.

(For an in-depth rundown, take a look at High Memory In The Linux Kernel)

On a 32-bit system the kernel-addressable RAM space is 4GB. Making sure the proper space reserved for the kernel is important. But on 64-bit (x86-64) Linux the kernel-addressable space is 64TB (terabytes). At the current state of computing this is effectively limitless, and as such you will not even see LowMem in /proc/meminfo because it is all LOWMEM.

So we created some EC2 Large instances (each of which is 64-bit with 7.5GB of RAM) and ran our tests again, this time without any surprises. The sockets were added happily and the kernel took all the RAM it needed.

Long story short, you can only scale to so many sockets on a 32-bit platform.

Kernel Options

Several parameters exist to allow for tuning and tweaking of socket-related parameters. In /etc/sysctl.conf there are a few options we’ve modified.

First is fs.file-max, the maximum file descriptor limit. The default is quite low so this should be adjusted. Be careful if you’re not ready to go super high.

Second, we have the socket buffer parameters net.ipv4.tcp_rmem and net.ipv4.tcp_wmem. These are the buffers for reads and writes respectively. Each requires three integer inputs: min, default, and max. These each correspond to the number of bytes that may be buffered for a socket. Set these low with a tolerant max to reduce the amount of ram used for each socket.

The relevant portions of our config look like this:

fs.file-max = 999999
net.ipv4.tcp_rmem = 4096 4096 16777216
net.ipv4.tcp_wmem = 4096 4096 16777216

Meaning that the kernel allows for 999,999 open file descriptors and each socket buffer has a minimum and default 4096-byte buffer, with a sensible max of 16MB.

We also modified /etc/security/limits.conf to allow for 999,999 open file descriptors for all users.

#<domain>      <type>  <item>         <value>
*               -       nofile         999999

You may want to look at the manpage for more information.

Testing

When testing, we were able to get about 64,000 connections per client by increasing the number of ephemeral ports allowed on both the client and the server.

echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range

This effectively allows every ephemeral port above 1024 be used instead of the default, which is a much lower (and typically more sane) default.

The 64k Connection Myth

It’s a common misconception that you can only accept 64,000 connections per IP address and the only way around it is to add more IPs. This is absolutely false.

The misconception begins with the premise that there are only so many ephemeral ports per IP. The truth is that the limit is based on the IP pair, or said another way, the client and server IPs together. A single client IP can connect to a server IP 64,000 times and so can another client IP.

Were this myth true it would be a significant and easy-to-exploit DDoS vector.

Scaling for Everyone

When we set out to establish half a million connections on a single server we were diving deep into water that wasn’t well documented. Sure, we know that C10k is relatively trivial, but how about an order of magnitude (and then some) above that?

Fortunately we’ve been able to achieve success without too many serious problems. Hopefully our solutions can help save time for those out there looking to solve the same problems.

Verizon Wireless Picks Urban Airship for Push Notifications

Today at the Verizon Developer Conference in Las Vegas, Verizon Wireless announced it has selected Urban Airship as its preferred provider of smart-phone push notifications for mobile apps developed across the Verizon network. Today, two of our company founders will take the stage in front of hundreds of Verizon Wireless developers to explain the benefits of push notifications and how they help organizations add value to their mobile endeavors.

We see this as a huge validation of the new mobile channel, especially the potential of push notifications to deliver ongoing value to mobile apps after they’ve hit the market. Businesses that have integrated our AirMail Push mobile messaging services into their apps have realized tremendous benefits, from increased usage to actual revenue gains.

We’re thrilled to be partnering with Verizon Wireless, who like us, seeks to help developers create and enhance the value of their applications. By expanding the number of tools available, including AirMail Push, to members of the Verizon Developer Community, the carrier is providing cost-efficient options for smart phone developers.

Verizon developers: Welcome! We are looking forward to working with you. We’ll be providing interested parties with tools and resources to guide development, produce higher quality applications and capitalize on Verizon’s powerful mobile device distribution. Here is some info to help you get started.

Push Messaging Overview

Push notifications optimize mobile apps. They strengthen user engagement, open up monetization opportunity and provide valuable insight into the effectiveness of mobile campaigns. Using the Urban Airship mobile services platform also helps developers scale their applications.

Engagement
One of the problems you, like any mobile publisher, face, is how to get your users back into your app once it has become available and downloaded onto their devices. You might see some inertia from your users, who might forget about your app and let it sit unused on their devices. A push notification sends a short message to your users—from within the app—that not only provides information relevant to them but also serves as a reminder for them to go back to the app. Your app users win too; because they opt-in to control which push notifications they want to receive and how they’d like to be notified (via badge update, sound or text alert).

Monetization
The more users use your app, the more they engage with your brand, organization or service. This engagement, of course, opens up revenue-generating opportunities for up-selling additional relevant content to users. It also helps your business develop sponsorship and marketing options. (Of course, the push notification itself is not a medium for direct marketing to users; but savvy publishers can turn that increased user engagement into opportunity.) Mobile messages are also the perfect complement to in-app purchase content delivery – if you have additional content that users might be interested in, what better way to let them know about it than directly from the app?

Information
Push notifications provide unique insight into app user behavior. You can track which messages prompt the most response; what times of day are most effective for sending messages; which devices or time zones or platforms spur the greatest engagement. Understanding your user behavior will help you decide how and when to tailor messaging campaigns to specific users or to users meeting certain patterns. This data helps you glean valuable insight to improve your mobile outreach.

Scale
Urban Airship’s cross-platform infrastructure helps you maximize your reach. From one API, you can send millions of messages across the Android, Blackberry and Apple iOS platforms. At the end of the day, you don’t really care which devices your users carry in their pockets; you just want them to use your app.

Technology
Our solid technology is based on the following principles:

• Provide a simple user and developer experience
• Scale
• Deploy easily as a SaaS solution
• Offer one API to reach any device
• Construct a flexible API upon which developers can build
• Leverage the power of the Amazon EC2 infrastructure
• Build a strong technology foundation using Memcache, Cassandra, Python and Java

How We’ll Work With Verizon Developers

Urban Airship will open its AirMail mobile messaging technology to the Verizon developers network. Any developer considering offering push notifications will be able to work directly with our team of engineers. Urban Airship will also provide code libraries and integration and technical support to guide development and ensure that you successfully integrate our AirMail mobile messaging tools. Our developer resource page has tons of info, including API documentation, to get you started.

Why Urban Airship

We’d like to think it is our warm smiles and generous personalities that wooed the Verizon execs, but we hear it is our demonstrated market leadership in mobile – the nearly 1 billion push messages we’ve delivered to more than 60 million unique devices on three platforms—and of course our solid technology and end-to-end mobile services platform.

Got questions?

Contact us however you’d like. Visit our support site or our IRC chat channel (#urbanairship on irc.freenode.net); we have a contact us form on our site; we host support forums… and we even use email (support@urbanairship.com) and the telephone. There is always more than one way to connect.

More Push Notifications for Less: Updated Urban Airship Pricing

We’re happy to announce a major update to our pricing plans for AirMail Push. Our new pricing model now lets you send up to 1 million push notifications for free! Effective October 1, 2010, you can send up to 1 million push notifications, per month, at no cost.

Our mission at Urban Airship from Day 1 has been to make life easier for developers. As we expand our reliable and easy-to-integrate AirMail Push mobile messaging service onto multiple platforms, we’re helping developers scale to reach larger audiences. We figure we may as well really make life a lot easier by increasing the “free” threshold to accommodate this growth.

So, yeah.  One million. It’s a nice round number, and hey, if you’re pushing 1 million messages in a month to your users, you’re doing something right. You’re probably seeing more engagement with your app users, for one. For another, you’re opening up opportunity for increased revenue from your app. So keep up the good work.

And if you haven’t started using push notifications to connect with your users, why not get started now?

Update: All accounts will be updated automatically to reflect this new pricing beginning Oct. 1, 2010.

Push Notifications on Android: FAQ

Within the past few weeks, we announced the availability of our popular AirMail Push service on the Android platform. Since then, response has been overwhelming. Check it out for yourself. Sign up for an account and give it a try if you like – integration involves dropping two snippets of code into your app and takes about 20 minutes. The docs are right here.

Here, we share with you some of the most common questions about integration, deployment and push in general. Remember, our support team is always here to help. If you want to file a support request, feature request, or suggestion, our support site is for you. We also frequent an IRC channel. It’s #urbanairship on irc.freenode.net. And of course, you can email us at support@urbanairship.com.

Some common questions about AirMail Push for Android from developers

Aren’t push notifications already available on the Android?
As covered in TechCrunch, AirMail Push for Android works with 99.8% of all Android devices (anything running 1.5 or newer). Rather than relying on C2DM in Froyo (which only reaches 4.5% of devices) for push notifications on Android, you can integrate AirMail Push to target nearly every phone on the platform. Plus, you’ll be able to send the same notification to apps on iOS and BlackBerry—from one call to our API.

Some background
When Apple announced it was going to be offering push notification services, it was a boon to app developers. Without Multitasking on iPhone 3.0 OS, there was no way for a developer to communicate directly with the app. Now, with Push baked in to iOS, Apple has provided an open socket for developers to communicate directly with the app – plus, it is the only way to communicate with an app that is not running. Apple didn’t provide a whole lot other than the open socket connection, and that’s how our company was formed, by providing the server- and client- side infrastructure for developers to leverage the service. As of today, we have powered nearly 1 billion messages to the iOS platform.

Blackberry wasn’t far behind. They built a similar type of service, and bundled it with their devices, and we again provide the infrastructure to make it work.

The Android platform lacks this type of built-in service. There is nothing baked into the OS that developers can leverage to send push notifications. Many apps appear to have push notifications, but the apps are constantly polling a server, and when a user has all this polling going on with multiple apps, there’s a big drain on battery life. Another drawback is that the notification is nothing close to real time- it just depends on how often the app wakes up to check for new information.

The AirMail Control Panel (also called the helper app) is the missing piece of the puzzle. When a user has it installed, the device is ready to receive notifications as they occur, and our service sends them to the device in milliseconds. Whereas with iOS we forward the message to Apple and with Blackberry we forward to RIM, with Android, we handle the messaging from end to end.

Why do we need to download a helper app to make push notifications work?
We thoroughly investigated many different service models, and we feel the
stand-alone application approach is best for both the application developer and the end user. Our main motivation, in terms of the interface and design, was to make things logical to the end user. We wanted a way for end users to control the experience of receiving notifications, so they can choose which apps send them push notification, set the method by which the notifications reach them (alert via sound for example) or disable them altogether. This functionality, enabled by the control panel in Android AirMail Push, is similar to how it works in iOS (and as opposed to BlackBerry and C2DM, which offer no such controls). Plus, we’ll be able to easily expand functionality — for example, quiet time will be added in a version coming soon.

Second, due to the sandbox system in Android, sharing a connection across apps would create a security hole—when you have the first app open the connection, every app on the device would be trusting the first app not to do anything untoward.

For more details on the technical reasons why we chose to launch AirMail as a help app on the Android platform, please read this, from our CTO.

Why do I want to add push notifications to my app in the first place?
Push notifications help you communicate with users. Using AirMail Push mobile messaging, you can interact with the users who have installed your apps on their mobile devices, be they Apple iOS, Android or BlackBerry devices. You can contact them in real-time, instantly, with breaking news updates, messages from their friends, sports scores or stock moves – the uses are endless. Plus, whether the phone is carried in a pocket, handbag or briefcase, your message reaches users where they are. This direct-to-pocket experience provides enormous potential for your content.

How does AirMail Push impact the battery life of an Android device?
AirMail Push lowers your app’s battery profile relative to polling and enables instant delivery. You can push a message plus a payload triggering about anything you want. It’s pretty cool. We haven’t noticed any drop in battery usage during our (very long) testing phase. That was one of our primary concerns :)

How many connections can your servers handle?
Each instance of the layer of our infrastructure that manages the connections can handle several hundred thousand connections.

Can you describe the integration with your Android libraries?
You can see the integration story around the push library here. We provide a drop-in library for you that communicates with AirMail Control panel via intents. The library is up on GitHub.

Does your app handle the notification or does it just broadcast an Intent?
Our app handles notifications by default, but if you don’t want it to handle the alerting and want to do it yourself (this was a requirement by some of our larger customers) you can by specifying only an “extra” value. We’ll pass that data along and your app can parse it.

Are the messages secure?
Yes, all notifications are encrypted.

Can UrbanAirship use the Google push architecture for 2.2 devices?

We can, and may, shift our libraries to do so as C2DM matures and is available on more devices, but for now our goal is to offer a singular solution that works well across all devices.