Author: Brian Yin

  • Protecting Data in Public Cloud and Hybrid Cloud

    Protecting Data in Public Cloud and Hybrid Cloud

    Backup, business continuity (BC) and disaster recovery (DR) have all been a critical part of IT for more than 30 years—ever since we began relying on technology to run our businesses. Traditional solutions were designed for the world of on-premises infrastructure and structured applications and relational databases. But the world is changing. In the last blog, I talked about the era of digital transformation and the impetus it has on rethinking and reinventing the fundamental backup and recovery architecture for workloads moving to the cloud and applications being born in the cloud.

    The Motivations Leading to Reinvent Backup and Recovery

    Application and data platforms are undergoing the biggest transformation since the dawn of computing. There are several forces at work:

    • New applications. The third-generation applications are geo-distributed, scale across multiple systems, are always on and typically deployed in a cloud-first model.
    • Existing applications are moving to the cloud. They aren’t going away, but companies are moving some or all of them to the cloud. They still need backup and recovery.
    • RPO and RTO windows are shrinking: Enterprises want “always-on” and gone are the days when you could do nightly backups.
    • Smaller companies will go all-in on public cloud. SMBs don’t want to be in the business of IT. They’ve been driving the rapid growth of cloud applications and platforms.
    • Enterprises will build hybrid clouds. Enterprises will deploy applications and data across on-premises and public cloud environments. Scale, compliance and other factors mean they’ll need to keep some systems on-premises.
    • Everyone will use multiple clouds. No one will bet their business on one cloud or one provider. Even now, enterprises are splitting workloads across clouds or cloud and on-premises. Development and test may use one cloud, while the same application might be deployed in a private cloud or a different public cloud.

    Cloud’s Impact on Backup, Recovery and Continuity

    Cloud gives organizations much more agility, operational savings and a pay-as-you go model. Public cloud providers can also build much more resilient infrastructure. Amazon guarantees 99.95 percent availability for EC2 and 99.99 percent for S3; S3 is designed for 11 nines of data durability, with multiple availability zones. Because the cloud is so reliable—and cheap—it’s quickly becoming a backup target for on-premises data. But that shouldn’t trick us into believing backup and recovery are “built-in” when we run applications in the cloud. Even Amazon itself recommends backup services for all AWS-native applications and cloud databases.

    While service availability and data resiliency addresses infrastructure business continuity and disaster recovery, it doesn’t provide point-in-time recovery or application-level intelligence for backup and recovery. As good as the cloud platforms are, they don’t protect against logical errors. And research shows 8 out of 10 errors are logical errors—data corruption, user errors.

    But Won’t Existing Backup Products Work in the Cloud?

    As we noted above, traditional backup and recovery products don’t meet the needs of cloud applications—even for existing applications that have moved to the cloud, and not just because they were built in a different era. Cloud and distributed architectures present several other challenges:

    • Cloud breaks the media server based architecture of traditional solutions. Cloud applications and data don’t reside on a specific array or disk, so you can’t easily backup what you can’t see. Backups also don’t capture configuration data in the cloud, such as AWS Cloud Formation templates.
    • Cloud doesn’t speak the same language. Legacy solutions talk to tape, disk or virtual disks. Backup and recovery in the cloud means integrating with the right protocols, such as the S3 API or Google Cloud Storage.
    • Backup appliances can’t be moved to the cloud. Existing backup appliances that work extremely well on-premises can’t be picked up and moved to the cloud.
    • Traditional backup agents won’t scale. If you could get a backup agent running in the cloud, it wouldn’t scale well across dozens or possibly hundreds of nodes.
    • VM is not the right layer of abstraction: Look for technologies that provide a scalable application-centric view of data management and data protection, introspect application data and use global semantic de-duplication to achieve storage efficiencies, instead of relying on traditional de-duplication techniques. The benefit of this approach is fine-grained and highly space-efficient data protection that can span clouds over network links.
    • Cloud Gateway or Migration Services: Unidirectional only.

    The problem of backup and recovery of cloud applications is novel there are three critical things a cloud backup and recovery architecture should have:

    • Elastic compute only. The architecture should scale efficiently on elastic compute instances. There shouldn’t be any CapEx costs for servers or appliances.
    • No media servers. Backing up large scale out databases requires direct a parallel streaming architecture for data movement between the database and secondary storage. Legacy backup architectures rely on media servers that would quickly become choke points. Direct parallel streaming also allows the data to remain available in native formats.
    • Semantic deduplication. Scale-out application databases typically have a 3x replication factor. If you backup individual nodes or even manage to snapshot the whole database, two-thirds of the backup data is redundant. Over time, backups will be 75 percent to 80 percent inefficient without semantic deduplication that works across a distributed architecture.

    — Brian Yin

  • Don’t Be Samsung: Here’s How You Can Protect Yourself

    Don’t Be Samsung: Here’s How You Can Protect Yourself

    Imagine a factory building 100,000 units a day, and you can see how a small error can have huge consequences. Now imagine that factory is a database.

    The world’s top smartphone maker this month pulled the plug on its $882 Galaxy Note 7 after phones overheated and caught fire, concluding in a disastrous recall for Samsung that could cost the company as much as $17 billion and shutter a global revenue stream. In an unprecedented move, Samsung has told mobile carriers to halt sales or exchanges of the device, requested that users to shut off their phones and issued a mass recall while the South Korean manufacturer investigates reports of fires in original and replacement Note 7s.

    This a scant two months after the Galaxy Note 7’s launch, a device that one TechCrunch consumer electronics expert raved as “undoubtedly one of the most iconic handsets around.” While it is not clear what caused these fires, there is speculation that it was due to a faulty component that interacts with the battery, rather than the battery itself.

    It goes without saying that there are ample opportunities for error in the assembly of a smartphone. The complicated, highly coordinated process is fraught with thousands of input touchpoints, from hard- and software components to tightly controlled manufacturing processes to manual labor. And though there may be countless checks and balances in place, mistakes do happen. What may seem to be an innocuous error, such as not sufficiently tightening a screw or the shorting of a circuit, in this case has led to epic consequences.

    The truth is, these instances happen more often than we think, and to technologies even more vital to the population than a personal smartphone.

    Consider today’s era of big data and cloud applications, where enterprise applications ingest and process vast amounts of information from various sources, often in real time, to deliver critical analytics, contextual information or business insights.

    This data has weight. It can influence whether fleets of airplanes are grounded at gates all across the country. It can restrict customers from accessing funds from online banking. It can dictate whether millions of online retail dollars go unspent. The reliance on accurate data, and its grip on lives and business, is growing at an exponential rate—like ever-widening ripples in a lake.

    To support all of this data, new applications (such as real-time analytics, internet of things, ecommerce and others) are developed and deployed on scale-out, non-relational databases or ported from traditional relational databases.

    But, like the manufacturing gaffs experienced by Samsung, corruptions and operational errors by developers occur in enterprise IT environments. Enterprises know this, and billions have been invested in traditional backup and recovery and data protection products to protect against such “err” moments. However, the irony is that data protection products like those that exist for traditional relational databases do not exist for today’s modern, next-generation scale-out databases supplying the new types of data that increasingly control our lives. We’re essentially trusting that the Ma Bell rotary phone repairman will be able to recover personal data—such as contacts, photos and messages—after your Galaxy Note 7 starts smoldering.

    So how did we get from the world’s most explosive phablet to distributed databases and big data? Because, like the Galaxy Note 7, the tiniest data error can rapidly expand into magnificent, catastrophic consequences.

    Enterprises are adopting cloud applications that gather large amounts of data at a high-ingestion rate and process that data in real-time to deliver actionable insights. These applications are deployed on non-relational databases. As migration to cloud and multi-cloud application environments increases, enterprises also must be able to manage and recover at scale without data loss or corruption and with minimal application downtime.

    However, enterprises today face a significant gap in addressing their data protection requirements. Their most valuable data, often needed 24/7 and without fail, runs absent any point-in-time backup options for that ‘“Houston, we have a problem”’ moment. Most studies suggest that more than half of data downtime and loss is triggered by human error, corruption or virus attacks. And yes, while native replication helps enterprises meet business continuity and disaster recovery requirements by providing protection from hardware failures or even natural disasters, it is insufficient (meaning it cannot scale) to meet next-gen enterprise data protection demands. Case in point: If a minor schema corruption impacts the primary data copy, it causes a multitudinous ripple effect that impacts all replicas down the line. Yet, even without protection, industries continue to adopt and deploy scale-out database systems at an accelerated pace.

    So just as Samsung witnessed an error replicate itself into such a massive meltdown of global proportions that it threatens to kill an entire product line, organizations also must understand how replication-based protection mechanism can actually act like a virus—spreading a corruption uncontrollably across non-relational, cloud databases.

    Samsung’s troubles won’t end with the simple recall of a single product, and their predicament should resonate. There will be punitive measures, and perhaps even a total enterprise shift from the smartphone market. It is not an enviable position, but is does offer a clear example of how a peripheral manufacturing error can swell to engulf an entire brand.

    For enterprises rushing to deploy scale-out databases, let Samsung serve as a warning: that deploying any infrastructure that could potentially lead to exponential, irreversible corruption of all data copies is a recipe for harm (if not disaster). As enterprises make the switch to next-gen applications running on scale-out, non-relational databases, an assembly line e-stop needs to be built in, in the form of a point-in-time, version-friendly data protection solution.

    Data corruption is not a matter of “if,” but “when.” So have a kill switch ready.

    errors-replicating-image

    — Brian Yin

  • PyMongo Pointers: How to Make Robust and Highly Available Mongo Queries

    PyMongo Pointers: How to Make Robust and Highly Available Mongo Queries

    In today’s clusters made of commodity servers, failures are the norm. Having your code fail because one data node happened to be down when you were querying it is frustrating and no fun. Based on my experience hardening our product, I wanted to share a few quick and easy pointers that can help make your MongoDB queries more robust to node failures. Let’s get started.

    Background for Beginners

    Note: If you are completely new to MongoDB, I would recommend reading the following links. They should give you a high-level understanding of the components that make up a MongoDB cluster.

    Let’s first start by understanding PyMongo and its advantages. As you already know, Python is a high-level programming language that provides code readability with object-oriented programming. Its ease of syntax and code written are more readable and smaller than code written in other languages. And MongoDB is a document-oriented scalable database designed for handling big data applications (such as content management systems). Since MongoDB supports dynamic schemas, it also provides the flexibility of storing any kind of data into your database without any rigidity.

    So, in case you have never used PyMongo before, the PyMongo distribution contains tools for interacting with MongoDB databases with Python. It is the most efficient tool for working with MongoDB using the utilities of Python. PyMongo was created to incorporate the advantages of Python as a programming language and MongoDB as a database. Since Python provides an easy-to-implement way of programming and MongoDB can handle large document repositories, the PyMongo tool can be of great use, since it provides the best of these two technologies.

    At the very core of PyMongo is the MongoClient object, which is used to make connections and queries to a MongoDB database cluster. It can be used to connect to a standalone mongod instance, a replica set or mongos instances. To specify which mongo endpoints to contact, you simply pass in the endpoints into the host argument of the object. For example, if we had a standalone mongod node on 10.0.0.3 listening on port 27017, you can contact that node as follows:

    import pymongo
    client = pymongo.MongoClient(host=“10.0.0.3:27017”)

    The node passed into the host is called a seed node. Once you initialize the MongoClient, it will connect to the specified seed node in the background. With some basics, let’s talk about how to make your queries more robust!

    Tip 1: Increase Your Host Seed List

    The first tip is very simple, but quite useful. Instead of passing in a single seed node, pass in a list of seed nodes. Passing in a list of seed nodes gives the MongoClient object more endpoints to contact in case the connection to one of the input nodes is down. This not only makes initializing a mongo connection more robust, but also makes the client robust to later connection failures occurring after initialization. Code-wise, it would look like the following:

    client = pymongo.MongoClient(host=“10.0.0.3:27017”) # Fragile; single point of failure 
    client = pymongo.MongoClient(host=[”10.0.0.3:27017”, “10.0.0.3:27018”, “10.0.0.3:27019”]) # More robust; can contact two other nodes in case one goes down

    Note that all nodes in your seed list must be part of the same logical group. For example, the seed list must contain mongod nodes belonging to the same replica set, or mongos query routers connected to the same config servers, or config servers in the same sharded cluster. Mixing these up will result in unpredictable behavior.

    Tip 2: If at First You Don’t Succeed, Try, Try Again

    After initializing a connection to a mongo node, the connection may fail at any time. This can be caused by a large variety of factors, ranging from network connectivity issues to actual mongo node failures. If one of these failures occurs, the next time a query is issued, the MongoClient will try to contact the unavailable node, determine it is unreachable, and then throw an exception. Afterward, the MongoClient object will automatically try to connect in the background to another live node in the seed list you provided, meaning your subsequent queries are likely to succeed. However, your code is still left with an exception to handle.

    A clean and easy way to handle these situations is to wrap all your queries in a retry decorator that will catch the exception and then retry your query. Here is some sample code:

    def retry(num_tries, exceptions):
        def decorator(func):
            def f_retry(*args, **kwargs):
                for i in xrange(num_tries):
                    try:
                        return func(*args, **kwargs)
                    except exceptions as e:
                        continue
            return f_retry
        return decorator
    # Retry on AutoReconnect exception, maximum 3 times
    retry_auto_reconnect = retry(3, (pymongo.errors.AutoReconnect,))
    @retry_auto_reconnect
    def get_count(client, db, collection):
        return client[db][collection].count()

    By wrapping your queries in a retry decorator, you can make them more robust to node failures and other temporary failures such as primary re-elections. Granted, this method isn’t a guarantee your queries will succeed in all cases as it assumes that there are other healthy nodes in the cluster to fail over to. However, assuming a relatively stable cluster, this method handles a large number of failures.

    Tip 3: Catch the Right Exceptions

    In the above example, we retried on AutoReconnect exceptions, which is raised when a connection to a database is lost. While this is one of the exceptions to catch, it is by no means complete. Other exceptions can be found in the pymongo documentation (see link below). A couple ones you may want to also catch include:

    • pymongo.errors.ConnectionFailure: thrown whenever a connection to a database cannot be made (actually the super-class of AutoReconnect above)
    • pymongo.errors.ServerSelectionTimeoutError: thrown whenever the query you issue cannot find a node to serve the request (e.g. issuing a read on primary, when no primary exists)

    These two exceptions are useful in both unsharded and sharded MongoDB clusters. However, there is some additional complexity in handling node failures for sharded clusters. In sharded clusters, most of your queries should be sent through the mongos because it can route your queries to the appropriate shard. If the mongos instance fails, then aConnectionFailure will be raised. However, what happens if your connection to the mongos is healthy, but the mongos fails to make a connection to a replica set? In these cases, the mongos will aggregate all the errors and send back an error which is then raised as an OperationFailure.

    While it may seem simple to just also retry OperationFailures, it’s not quite that clean because OperationFailures can represent a large variety of errors, ranging from retryable errors such as primary re-elections to non-retryable errors such as authentication errors. You can distinguish between different types of errors by examining the code field of the error. Although at some point in time there was a list of error codes and their meanings, they have since become outdated and removed (see SERVER-24047), which means you’ll have to do some trial and error to discover which codes you should retry on.

    Conclusion

    Hopefully, these tips were helpful for all you MongoDB lovers! If you have any questions, comments, or have your own tips to share, feel free to comment below and get the discussion flowing.

    — Brian Yin