<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Colt McAnlis on Medium]]></title>
        <description><![CDATA[Stories by Colt McAnlis on Medium]]></description>
        <link>https://medium.com/@duhroach?source=rss-6e1a63c4fcd1------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*bW2MamPPP1MeRjVP.jpg</url>
            <title>Stories by Colt McAnlis on Medium</title>
            <link>https://medium.com/@duhroach?source=rss-6e1a63c4fcd1------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 02:05:56 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@duhroach/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Cloud Bigtable & time series data]]></title>
            <link>https://medium.com/@duhroach/cloud-bigtable-time-series-data-eecc32dd9cf2?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/eecc32dd9cf2</guid>
            <category><![CDATA[big-data]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Fri, 01 Feb 2019 07:57:54 GMT</pubDate>
            <atom:updated>2019-02-02T16:02:08.924Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><p>Despite its importance in multiple industries, time series data continues to be one of the more challenging datasets to handle at scale. Time series help us identify trends in data, letting us demonstrate concretely what happened in the past and make informed estimates about what will happen in the future.</p><p>But for TIMESLIDERS, time series data was the backbone of their business, but also the bane of their users. TIMESLIDERS is a mobile-application performance library, built for developers. Their client application would monitor as many performance details about the client device and application as possible, reporting things back like avg network speed, quality of wifi connection, battery life, foreground activity paint rate, etc, etc.</p><p>Clients could then log into a portal and see a plethora of performance statics on how their app was performing around the world, on real devices.</p><p>Sadly, this process of building and displaying these performance tables quickly became a bottleneck, and a less-than-ideal experience for the majority of their clients.</p><p>Thankfully, we didn’t have to look far to find the problem : In order to build their graphs, the very first thing they did was query by timestamp.</p><p>Many schema designers are inclined to define a root table that is timestamp ordered, and updated on every write. Unfortunately, this is one of the least scalable things that you can do with Cloud Bigtable.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fvideoseries%3Flist%3DPLIivdWyY5sqK5zce0-fd1Vam7oPY-s_8X&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DWyv4FWLois4&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FWyv4FWLois4%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/72a22c3173d02935f0e2b93c4b59559c/href">https://medium.com/media/72a22c3173d02935f0e2b93c4b59559c/href</a></iframe><h3>What’s going wrong?</h3><p>Let’s be clear: Storing time-series data in Cloud Bigtable is a natural fit. Cloud Bigtable stores data as unstructured columns in rows; each row has a row key, and row keys are sorted lexicographically.</p><p>There are two commonly used ways to retrieve data from Cloud Bigtable:</p><ul><li>You can get a single row by specifying the row key.</li><li>You can get multiple rows by specifying a range of row keys.</li></ul><p>These methods are ideal for querying time-series data, since you often want data for a given time range (for example, all of the market data for the day, or server CPU statistics for the last 15 minutes). As a result, Cloud Bigtable is functionally a great fit for time series.</p><p>Of course, there’s always a devil in the details, and for time series data, this is no exception. In brief, when a row key for a time series includes a timestamp, all of your writes will target a single node; fill that node; and then move onto the next node in the cluster, resulting in hotspotting.</p><h3>Properly handling time series data</h3><p>Let’s take a simple example from TIMESLIDERS: Storing battery status. Every 100ms or so, their app would log the battery status, creating an entry into Bigtable where the row key consists of the word “BATTERY” plus a timestamp. (for example: BATTERY20150501124501003).</p><p>The problem with this, is that the row key will always increase in sequence, meaning every row will have a high level of adjacency to every other row; And because Cloud Bigtable stores adjacent row keys on the same server node, all writes will focus only on one node until that node is full, at which point writes will move to the next node in the cluster. During this time, you end up with a large level of hotspotting.</p><p>So we need the ability to query a set of timestamped rows for our graph, but need to find a way to do it that doesn’t result in hotspotting.</p><p>Thankfully, there are a few ways to solve this problem.</p><p><strong>Field promotion </strong>involves<strong> </strong>moving fields from the column data into the row key to make writes non-contiguous. For example, TIMESLIDERS could promote the USERID from a column to an element of the row key. This change would solve the hotspotting issue because user identifiers will provide a more uniform distribution of row keys. As a result, writes will be split across multiple nodes in their cluster.</p><p>The advantage of field promotion is that it often makes your queries more efficient as well, making this strategy a clear winner. The (slight) disadvantage is that your queries are constrained by your promoted fields, leading to rework if you don’t promote the right fields.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/683/1*DaJrh5r69mnTzIbHBd32WA.png" /></figure><p>Another option is <strong>Salting,</strong> which<strong> </strong>adds an additional calculated element to the row key to artificially make writes non-contiguous.<strong> </strong>For example, take a hash of the timestamp and divide it by the number of nodes in the cluster (to help balance traffic) and append the remainder to the row key.</p><p>The advantage of salting is its simplicity — it’s essentially a simple hashing function that helps balance access across nodes.</p><p>On the other hand, it does require an extra step when you query for time ranges. You’ll have to do one scan per salt-value, and then recombine the results in your own code. Salting also makes it much harder to troubleshoot performance issues with <a href="https://cloud.google.com/bigtable/docs/keyvis-overview">Key Visualizer for Cloud Bigtable</a>, because it’ll show row keys with a bunch of hashed values instead of human-readable strings.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/738/1*ebUSzHRnvfNjRknbSM4Dsw.png" /></figure><h3>The fix is in!</h3><p>For TIMESLIDERS salting was problematic. Despite a barrage of tests, it was very difficult to choose a salt value that both distributes activity across nodes and still remained valid as their system scaled up and down.</p><p>Aa such, they decided to use field promotion, which allowed them to avoid hotspotting in almost all cases, and tended to make it easier to design a row key that facilitates queries.</p><h3>Oh Hey!</h3><p>It’s worth pointing out that time series data is a common enough challenge with Bigtable, that there exists a 3rd party library that can do all the heavy lifting for you. If you’re not interested in solving all these problems yourself, check out <a href="http://opentsdb.net/">OpenTSDB</a> which can save you a ton of headache later on.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=eecc32dd9cf2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The right Cloud Bigtable index makes all the difference.]]></title>
            <link>https://medium.com/@duhroach/the-right-cloud-bigtable-index-makes-all-the-difference-3bcabe9bd65a?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/3bcabe9bd65a</guid>
            <category><![CDATA[big-data]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Thu, 17 Jan 2019 12:53:29 GMT</pubDate>
            <atom:updated>2019-01-17T12:53:29.461Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><p>From a performance perspective, one of the most important things to consider while designing your Bigtable Schema is how to properly design your index. And our friends at Urban Fitness Forge ran into this headlong recently.</p><p>Urban Fitness Forge is one of the latest in awesome real time fitness tracker products. Their advanced clothing line carries over 50 sensor measurements for the human body, each sampled 10 times a second. After their initial series A funding, they saw a huge boom in usage for users as they were picked up by a local clothing company. The result, too much data for their existing back-ends, which prompted them to move to the ever powerful Cloud Bigtable.</p><p>However, after their migration, they suddenly noticed that it was taking a lot of memory and time to fetch / sort results for their real time updating of statistics. By the time I got involved, their engineering team was in a Code Red to find the problem.</p><h3>Finding the problem</h3><p>UFF’s usage pattern for their data dominantly queried lat/long values to find specific sensors within an area for analysis. Or rather, given how often they ran this query, it was way too slow for their needs.</p><p>Their schema looked similar to what you’d expect. Their key was comprised of long/lat values for a sample inserted with a delimiter in the middle (e.g. “33.749#-84.388”) :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*OzPhvQLzn_bTL6c5prslOw.png" /></figure><p>Performance wise, this simple design was creating a massive bottleneck for them.</p><p>While looking at some logging data, we quickly realized that our scans for data points near Portland, Oregon (USA) ended up also scanning and filtering through data points in Milan &amp; Venice Italy. After some digging, researching, and asking around, we realized that there were three problems working in unison to cause this performance issue:</p><ol><li>These cities are very close to each other in terms of Latitude:</li><li>Bigtable stories entries in their shards lexicographically by their index</li><li>Bigtable doesn’t have explicit support for secondary indexing.</li></ol><p>Let’s break this down a little more.</p><p>Bigtable stories entries in their shards lexicographically by their index, meaning that entries with lexicographically similar keys will be closer to each other in the tablets. Queries that access a single row, or a contiguous range of rows, execute quickly and efficiently. However if need something like a secondary index (like the “LONG” in a “LAT/LONG” pair) then your queries end up in a full table scan, which will be far slower. A full table scan is exactly what it sounds like — every row of your table is examined in turn, which, as your table sizes grow, your performance suffers more.</p><p>This is where point #1 above comes into play. Portland is very close to two other large cities in terms of latitude:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/257/1*MG_ncKldkvsBEWGLfkoNbQ.png" /></figure><p><em>The above image shows Portland, Milan and Venice overlaid on a map, you can see the full interactive map </em><a href="http://www.bytemuse.com/post/interactive-equivalent-latitude-map/"><em>here</em></a><em>.</em></p><p>As such, their storage in rows tends to be <em>very close</em> to each other, despite being geographically very far away. This means a full table scan involves walking through all the table entries that share a latitude value across the globe — A much larger scan size than we were hoping for.</p><h3>Building the right index</h3><p>This continues to highlight an important aspect of Bigtable schema design: choosing a row key that facilitates common queries is of paramount importance to the overall performance of the system.</p><p>For Urban Fitness Forge, that meant trying to create an index such that entities close to each other physically were sorted close to each other in table space, in order to reduce the scan size.</p><p>Thankfully, this has been solved before. A <a href="https://en.wikipedia.org/wiki/Space-filling_curve">space filling curve</a> is a way to organize a 2D space such that adjacent indexes are pseudo similar in physical space (I like<a href="https://www.youtube.com/watch?v=x-DgL49CFlM"> this explanation</a> if you are looking for more).</p><p>For example, if we stored points in a 2D set using a raster index (index = Y*WIDTH+X) we’d end up with something that looked like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/263/1*-D4dJl3DpFWBMFxqRO96Lg.png" /></figure><p>Meanwhile, a space filling curve does this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/292/1*dIDZe56nF2bInvnMp-DbGQ.png" /></figure><p>You can see that in the first example (aka RASTER order) that while 6 looks physically close to 2, it’s a whole row away from it, in terms of index. However, in the Space Filling Curve, the closest index values to 6 are <em>physically</em> close as well.</p><p>The result is a modified index for entities which use a space-filling curve integrated with a timestamp value to create a single, integer based index.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*_9PK18OI8vKBAB3-ar8Ysg.png" /></figure><p>For Urban Fitness Forge, this meant a massive performance improvement for queries that sampled row data via lat/long, as it allowed items which were geographically close to each other, to also be adjacent to each other in the table.</p><h3>Your mileage may vary</h3><p>Now, obviously using a Hilbert space filling curve is not the solution to every Cloud Bigtable index option, but it does highlight the important part:<strong> to get the best performance out of Cloud Bigtable, it’s essential to think carefully about how you compose your row key</strong>. By choosing the correct row key template, you can avoid a painful data migration process later.</p><p>To do this, start by asking how you’ll use the data that you plan to store. For example:</p><ul><li>User information: Do you need quick access to information about connections between users (for example, whether user A follows user B)?</li><li>User-generated content: If you show users a sample of social-style content, such as status updates, how will you decide which status updates to display to a given user?</li><li>Time series data: Will you often need to retrieve the most recent N records, or records that fall within a certain time range? If you’re storing data for several kinds of events, will you need to filter based on the type of event?</li></ul><p>By understanding your needs up front, you can ensure that your row key template, and your overall schema design, provide enough flexibility to query your data efficiently.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3bcabe9bd65a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cloud Bigtable : Getting the geography right]]></title>
            <link>https://medium.com/@duhroach/cloud-bigtable-getting-the-geography-right-645577216516?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/645577216516</guid>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Thu, 03 Jan 2019 14:02:24 GMT</pubDate>
            <atom:updated>2019-01-03T14:02:24.545Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><h3>Cloud Bigtable : Getting the geography right</h3><p>FlightMight was having trouble with Cloud Bigtable performance from their clients around the globe. Their system for monitoring aircraft information meant sampling lots of instrument data hundreds of times a second, submitting it all back to a server for storage and analysis.</p><p>Sadly though, their aircrafts tended to work all over the world, with shoddy connections and quickly changing latency situations, leaving their performance when interfacing with Cloud Bigtable, less than ideal.</p><h3>Location, location location.</h3><p>The issue here is that Cloud Bigtable, in order to be as performant as possible, is local to a specific region. As such, accessing Cloud Bigtable from clients around the world is quickly at the mercy of latency, which is why we recommend that any client accessing Bigtable be, not only in the same region, but specifically, in the same <strong>zone</strong>.</p><p>To show this off, here’s a small test (using a <a href="https://github.com/GoogleCloudPlatform/google-cloud-go/tree/master/bigtable/cmd/loadtest">Cloud Bigtable loadtest tool written in Go</a>) I ran where the client in <strong>us-central1-c </strong>connecting to cluster in:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/1*ojmcakWo3GuYlqbh4GLE-g.png" /></figure><p>Don’t get me wrong, 24ms/26ms 95th read/write percentile is extremely impressive, but we can see that almost doubles when we move the cluster to us-east4-a; and if you have a client that’s connection to Bigtable repeatedly, (say pushing up time-stamped samples) then this overhead starts to add up.</p><h3>Bridging the gap.</h3><p>Now, let’s be clear — This is <strong>not a challenge unique to Cloud Bigtable</strong>. The general challenge lies in the fact that we have a resource that’s geographically separated from our clients, and the latency overhead of repeated transactions can cause performance issues. Here on Cloud Performance Atlas, we’ve seen this same issue with respect to latency in Networking, Cloud Storage, Cloud Datastore and App Engine, so we’ve got a nice set of tools at our disposal.</p><p>Here are a few ideas we tossed around:</p><p>1) <strong>Use more clusters</strong>. From the Cloud Platform Console, if you create additional clusters, Cloud Bigtable will immediately start replicating data between those clusters (and we require the clusters to be in different zones). This is obviously the most straightforward way to solve this problem, as it allows your data to be replicated to geographically diverse locations. On the down side, this solution comes with extra cost, since you’ve got a second cluster running.</p><p>2) <strong>Update the clients to use multithreaded push/pull</strong>. This would mean that the overhead of latency wouldn’t be hurting the performance of the client, although we’d need to build their client robust enough to queue up samples, submit them in batches, and deal with situations where we lose connectivity. In this scenario, the latency is mitigated to the client’s perspective,but we end up with a lot of potential edge cases we might need to discover &amp; code for. (imagine a scenario where push latency is ~80ms, and we’ve got a device that’s sampling information every ~10ms.)</p><p>3) <strong>Use Cloud Pub/Sub &amp; a f1-micro instance</strong>. Cloud Pub/Sub is a fantastic deliver-once service for GCP. If we have our clients push their sample data into Cloud Pub/Sub, then we don’t need to have any overhead for buffering on the client. On the flip-side though, we would need to spin up a permanent Compute Engine VM instance, in the same zone, which pulls the messages from Cloud Pub/Sub, and then submits them to Bigtable directly. The challenge with this setup is multi-fold. Firstly, we’d need to use an f1-micro Compute Engine VM instance in order to keep costs down, which might not have the performance we need for connections (thus we’d need to scale, incurring higher costs). Secondly, this really only works for <em>write</em> operations from the client; reading data would need a separate path, which might involve different complexity to the endpoint.</p><p>4) <strong>Serverless endpoint</strong>. Cloud Functions and App Engine can help offer the positives of #1 / #2 above, without the downsides. For both reads &amp; writes, Cloud Functions and App Engine can both scale to thousands of instances, each one properly connecting to the nodes in a Cloud Bigtable cluster (which, as we’ve talked about, are designed to handle 10k QPS of reads or writes per node if you’re using SSD storage). And placing the serverless systems in the same region as the Cloud Bigtable cluster means that latency, per-request can fall back inside of Google’s High-speed network, which can improve performance.</p><p>And for FlightMight, that was all they needed to hear. They adjusted their clients to push content to Cloud Pub/Sub, which then triggers a Cloud Function that’s deployed in the same zone as their Cloud Bigtable cluster, giving them the performance they need, and lowering their cost.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=645577216516" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using Cloud Bigtable Monitoring UI]]></title>
            <link>https://medium.com/@duhroach/using-cloud-bigtable-monitoring-ui-40d3f4c726d6?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/40d3f4c726d6</guid>
            <category><![CDATA[big-data]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Thu, 03 Jan 2019 13:57:51 GMT</pubDate>
            <atom:updated>2019-01-03T13:57:51.879Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><p>When you’re dealing with something as big and powerful as Cloud Bigtable, it’s important to make sure you’re looking at the right data and tests to ensure performance is awesome. As we talked about before, most of the magic of how Cloud Bigtable handles such scale is all behind the scenes; where frontends can coordinate, balance, and optimize your access patterns by moving tablets of data between various compute nodes as needed.</p><p>Because so much of the heavy lifting of Cloud Bigtable performance happens behind the scenes, it might not be obvious how to figure out whether an instance is performing well. Are you supposed to set a breakpoint in the middle of Cloud Bigtable’s tablet sharding or something? Do you even want to? (Spoiler alert: You don’t.)</p><p>Thankfully, Cloud Bigtable gives you a much easier way to see how your instances are performing over time.</p><p>Thankfully, this is where Cloud Bigtable Monitoring can help out.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FUkQ_kZMG76k%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DUkQ_kZMG76k&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FUkQ_kZMG76k%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/86498f1b17abcdaca8e85bf8311f3939/href">https://medium.com/media/86498f1b17abcdaca8e85bf8311f3939/href</a></iframe><h3>The monitoring UI</h3><p>Cloud Bigtable has a built in monitoring tool that automatically reports how your nodes, clusters, and instances are performing. After your instance is created, you can click the monitoring tab:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/233/1*rU4445-SogR-q7QxzRsf6g.png" /></figure><p>Which will show you things like CPU utilization, error rate, storage utilization, rows read/written read/write requests and read/write throughput; all in a handy graph form so you can see how these values have responded over a historic time series.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xBhXcvJySBPe_A03HlQxdg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nZQIAI9dHr6V4VkMAjU0Vw.png" /></figure><p>Now, having all this data is great, but what’s really important is finding the situations where it actually <em>tells</em> you something. Here’s a few common use cases that are worth keeping an eye on</p><h3>Is it time to add more nodes?</h3><p>As mentioned before, Cloud Bigtable works by keeping a set of front-end nodes which are responsible for routing and balancing traffic to the backend tables. When you create your Cloud Bigtable instances and clusters, you specify the number of nodes you want, and using the monitoring tool, you can quickly see if it’s time to add more nodes.</p><p>On our instances tab, we can take a look at the CPU utilization table, which has a “recommended max” line. This line represents the best practices for CPU utilization, and if you eclipse this line for a number of minutes, it’s generally a good idea to add more nodes to your cluster.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HKVRcFdM6FQyA2f28OPvUA.png" /></figure><p>In addition, once the CPU utilization gets high enough, the nodes become bottlenecked, and we can see, as a result, that both the read throughput and wrote throughput suffer as a result.</p><p>On the non-cpu side, the “Disk Load” graph could also point to a need to add more nodes. If this value is frequently at 100%, you might experience increased latency. Add nodes to the cluster to reduce the disk load percentage.</p><h3>How balanced are my reads/writes?</h3><p>You might see another common performance problem with Cloud Bigtable if reads and writes aren’t evenly distributed across all of your data.</p><p>Despite <a href="https://cloud.google.com/bigtable/docs/schema-design">designing your schema</a> correctly, there are some cases where you can’t avoid accessing certain rows more frequently than others. Cloud Bigtable helps you deal with these cases by taking reads and writes into account when it balances tablets across nodes.</p><p>For example, suppose that 25% of reads are going to a small number of tablets within a cluster, and reads are spread evenly across all other tablets:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/736/1*F3nLsJ3JJ5BcqlTjzmskMQ.png" /></figure><p>Cloud Bigtable will redistribute the existing tablets so that reads are spread as evenly as possible across the entire cluster:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/736/1*saivX-P-2NnA5przlkSPHA.png" /></figure><p>However, there are times when Cloud Bigtable can’t properly spread out the read/write volume across all nodes, and as a result, performance will suffer.</p><p>We can detect this instance in the monitoring tool by keeping an eye on the “CPU Utilization of the hottest node”. If the hottest node is frequently above the recommended value, even when your average CPU utilization is reasonable, you might be accessing a small part of your data much more frequently than the rest of your data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2sgNq1uEvF-pieFwsMPLuw.png" /></figure><p>To fix this, you’ll need to go back and check your <a href="https://cloud.google.com/bigtable/docs/schema-design">schema design</a>, and your access patterns and make sure it supports a more even distribution of reads / writes across each table.</p><h3>Digging deeper with Key Visualizer</h3><p>The monitoring UI is a great way to figure out high level issues with your cluster, and see if there’s things you can address without too much heavy lifting. Often times though, you really need to dig into the specifics of your performance, and for that the <a href="https://cloud.google.com/bigtable/docs/keyvis-overview">Key Visualizer for Cloud Bigtable</a> is exactly the tool for you, as it can provide insights into usage patterns at scale that are difficult to understand otherwise. For example:</p><ul><li>Check whether your reads or writes are creating hotspots on specific rows</li><li>Find rows that contain too much data</li><li>Look at whether your access patterns are balanced across all of the rows in a table</li></ul><p>For an example from <a href="https://cloud.google.com/bigtable/docs/keyvis-patterns">the official documentation</a>, this tool can help you find specific usage patterns, visually, so you can quickly track them down:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/639/1*pIKOKgE6Nuikz5_J8QSM9g.png" /></figure><h3>There’s more to come!</h3><p>Now, it’s worth noting that the values I’ve discussed above are for instances that don’t use replication. If you’re using <a href="https://cloud.google.com/bigtable/docs/configuring-replication">replication</a>, you should check out the <a href="https://cloud.google.com/bigtable/docs/performance">official documentation</a> to keep up-to-date with the best practices and performance thresholds.</p><p>If you’d rather monitor your Cloud Bigtable instances programmatically, we’ve got tools for that, too. You can use Stackdriver Monitoring to <a href="https://cloud.google.com/bigtable/docs/monitoring-instance#stackdriver">keep an eye on usage metrics</a>, and Stackdriver Logging lets you <a href="https://cloud.google.com/bigtable/docs/audit-logging">audit access to your instances</a>. If you’re using our HBase-compatible client library for Java, you can even <a href="https://cloud.google.com/bigtable/docs/hbase-metrics">get client-side performance metrics</a>.</p><p>In upcoming posts we’ll be taking a look at how to properly design your schema, update hotspots, and design your data so you can run as fast as possible. Stay tuned!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=40d3f4c726d6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cloud Bigtable Performance 101]]></title>
            <link>https://medium.com/@duhroach/cloud-bigtable-performance-101-8bf884bc1d1c?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/8bf884bc1d1c</guid>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Fri, 30 Nov 2018 11:33:52 GMT</pubDate>
            <atom:updated>2018-11-30T11:46:11.945Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><p>When it comes to performance at scale, there’s very few products that can truly represent the “at scale” part the way that Cloud Bigtable does. To date, Bigtable is the technology behind the majority of Google products, including Gmail, Maps, Youtube; Each of which serves multi-billion active users.</p><p>What’s really amazing is that this same technology that powers Google’s most popular products is also available for you to use for your applications. But be warned : You’d think with all that scale and performance that it would be the silver bullet to handle all your backend needs, but when it comes to performance, just like anything else, there’s some things it’s good at, and some things it’s not.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fvideoseries%3Flist%3DPLIivdWyY5sqK5zce0-fd1Vam7oPY-s_8X&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DhiENR_wW4gI&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FhiENR_wW4gI%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/7828e3122127c3db7e1f55e832b05b04/href">https://medium.com/media/7828e3122127c3db7e1f55e832b05b04/href</a></iframe><h3>How it works</h3><p>As a massively oversimplified generalization, Cloud Bigtable can be described as three systems working together:</p><ul><li>A frontend server pool.</li><li>A set of compute nodes to handle connections (aka a “Cloud Bigtable Cluster”).</li><li>A scalable backend of storage.</li></ul><p>In more detail, all client requests go through the front-end server pool before they are sent to a Cloud Bigtable node. Each node in the cluster handles a subset of the requests for the entire system, and the frontends will handle balancing these connections depending on the type of action the connection is interested in, and what part of your data it’s wanting to work on.</p><p>To store the underlying data for each of your tables, Cloud Bigtable shards the data into multiple <strong>tablets </strong>(<em>Not a typo! Tablets and tables are different things.</em>), where each tablet contains a contiguous range of rows within the table.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/656/1*WZwAMuyb0bZTv4-2S54F7w.png" /></figure><p>And here’s the important thing when it comes to tablets: they can be reassigned to different nodes in your cluster, on demand, allowing<em> </em>Cloud Bigtable to scale and re-balance seamlessly as your use patterns change.</p><p>For example, as reads/writes to a specific tablet increase, Cloud Bigtable might split a tablet into two or more smaller tablets, either to reduce a tablet’s size or to isolate hot rows within an existing tablet. Likewise, if one tablet’s rows are read extremely frequently, Cloud Bigtable might store that tablet on its own node, even though this causes some nodes to store more data than others.</p><h3>Expected performance</h3><p>Under these typical workloads, Cloud Bigtable delivers highly predictable performance, and according to the official documentation, you can expect to achieve the following performance for each node in your Cloud Bigtable cluster, depending on which type of storage your cluster uses:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*F-R-gTBn0FAjuralsZ_HDw.png" /></figure><p><em>(Standard disclaimer : These performance numbers are guidelines, not hard and fast rules. Per-node performance might vary based on your workload and the typical size of each row in your table. Please </em><a href="https://cloud.google.com/bigtable/docs/performance"><em>see here for latest numbers</em></a><em>)</em></p><p>In general, a cluster’s performance increases linearly as you add nodes to the cluster. For example, if you create an SSD cluster with 10 nodes, the cluster can support up to 100,000 QPS for a typical read-only or write-only workload, assuming that each row contains 1 KB of data.</p><h3>When to/not use it</h3><p>From here, you can clearly see that Cloud Bigtable does not act like relational databases, and more to the point : while it scales amazingly well, and isolates hotspots gracefully, that doesn’t make it a perfect use for every scenario.</p><p>Cloud Bigtable excels at handling very large amounts of data (terabytes or petabytes) over a relatively long period of time (hours or days). This is because Cloud Bigtable needs time to learn your access patterns, and the data needs to be large enough to warrant usage of all nodes in your cluster (otherwise, you might get hotspotting to once cluster).</p><p>Which means that Cloud Bigtable is a great solution for:</p><ul><li><strong>Time-series data</strong>, such as CPU and memory usage over time for multiple servers.</li><li><strong>Marketing data</strong>, such as purchase histories and customer preferences.</li><li><strong>Low Latency Serving</strong>, such as adtech (martech) recommendations, etc.</li><li><strong>Financial data</strong>, such as transaction histories, stock prices, and currency exchange rates.</li><li><strong>Internet of Things data</strong>, such as usage reports from energy meters and home appliances.</li><li><strong>Graph data</strong>, such as information about how users/machines/events are connected to one another.</li></ul><p>On the other side, if you’re storing a small amount (&lt; 300 GB) of data, or if your Cloud Bigtable interactions last for a very short period of time (seconds rather than minutes or hours), Cloud Bigtable won’t be able to balance your data in a way that gives you good performance, and as such, might not be the right technological solution for your application. Fret not! Google Cloud Platform has a great set of other offerings that might offer you what you need, for example:</p><ul><li>If you need relational joins, like for online transaction processing — use <a href="https://cloud.google.com/sql/">Cloud SQL</a></li><li>If you’re using Blobs over 10MB — use <a href="https://cloud.google.com/storage/">Cloud Storage</a></li><li>If you need ACID transactions — use <a href="https://cloud.google.com/datastore/">Cloud Datastore</a> or <a href="https://cloud.google.com/spanner/">Cloud Spanner</a></li><li>If you don’t have much data yet — use <a href="https://cloud.google.com/datastore/">Cloud Datastore</a>, the <a href="https://firebase.google.com/products/realtime-database/">Firebase Realtime Database</a>, or <a href="https://cloud.google.com/sql/">Cloud SQL</a></li></ul><p>If your workload falls into the Cloud Bigtable space, then stay tuned to Cloud Performance Atlas, because we’ve got more content on Cloud Bigtable coming soon!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8bf884bc1d1c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[QUIC and HTTPS Load Balancer]]></title>
            <link>https://medium.com/@duhroach/quic-and-https-load-balancer-53799b0a16ca?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/53799b0a16ca</guid>
            <category><![CDATA[load-balancing]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Fri, 09 Nov 2018 19:30:13 GMT</pubDate>
            <atom:updated>2018-11-09T19:30:13.482Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><p>With the boom of mobile devices across the world, we’ve been seeing a lot of areas where smartphone adoption outpaced the ability for the telecom providers to update their networks. The result is a less-than-fast experience for the users, and a deep need to re-evaluate how our current internet protocols are working on the modern web.</p><p>This is some of the fundamental reasoning behind Google’s development of the QUIC protocol.</p><p><a href="https://www.chromium.org/quic">QUIC</a> (Quick UDP Internet Connections) is a modern transport layer protocol that provides congestion control similar to TCP and security equivalent to SSL/TLS, along with improved performance (reduced connection and transport latency, higher throughput etc).</p><p>And recently the networking group in Google Cloud Platform released QUIC support for the HTTPS load balancers, which means it’s time to take it for a spin, and see what kind of performance we can get ;)</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FdppS9iXzijw%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdppS9iXzijw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FdppS9iXzijw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/4b10c60c3286fecaa79d7cd83fb1119a/href">https://medium.com/media/4b10c60c3286fecaa79d7cd83fb1119a/href</a></iframe><h3>QUIC recap</h3><p>A good way to decrease connection latency for an efficiently routed connection is to make fewer <a href="https://en.wikipedia.org/wiki/Round-trip_time">round-trips</a>. Much of the work on QUIC is concentrated on reducing the number of round-trips required when establishing a new connection, including the <a href="https://en.wikipedia.org/wiki/Handshaking">handshake</a> step, encryption setup, and initial data requests. QUIC clients would, for example, include the session negotiation information in the initial packet. This compression is enhanced by QUIC servers, which publish a static configuration record that is concisely referred to. The client also stores a synchronization cookie it received from the server, enabling subsequent connections to incur zero overhead latency (in the best case)</p><p>One of the motivations for developing QUIC was that in TCP the delay of a single packet induces <a href="https://en.wikipedia.org/wiki/Head-of-line_blocking">head-of-line blocking</a> for an entire set of SPDY streams; QUIC’s improved multiplexing support means that only one stream would pause</p><p>Originally developed <a href="https://chromiumcodereview.appspot.com/11125002">back in 2012</a>, the protocol works by using a set of multiplexed connections between two endpoints using UDP, focusing on SSL support, and reduced application latency.</p><h3>Setting up the test</h3><p><strong>Step 1 : Enable QUIC on our HTTPS load balancer</strong></p><p>If you’ve already got an HTTPs LoadBalancer up and running, enabling QUIC is very straightforward.</p><p>In the cloud console, simply go back to your Load Balancer, and enable the “QUIC negotiation” button in the frontend dialog.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/794/1*eQpdaJQ0COdgUbfMorVbpA.png" /></figure><p><strong>Step 2 : Adjusting the network performance.</strong></p><p>Much like BBR, QUIC works best in connectivity that’s challenged, so much like BBR we’ll allow our clients to simulate a bad network connection using a tc command:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/419/1*7LVXGz_C-df3cvrwQwukGw.png" /></figure><p><strong>Step 3 : the test</strong></p><p>Our test is to fetch 10mb worth of files of various sizes from a GCS bucket through the load balancer, and chart the throughput. We’ll have one client connecting through an HTTP front-end (no QUIC support) with the other client connecting through QUIC.</p><h3>The results</h3><p>The results are pretty clear in this test, QUIC sees a 1.3x improvement in overall performance vs standard HTTPs on the load balancer, which is pretty nice for just setting one flag!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SwMPXpSfHKU13l8gZLcgfw.png" /></figure><h3>Where to use QUIC?</h3><p>As mentioned, QUIC really shines in low-connectivity environments, where packet loss and delay are high. Much like BBR, there’s no downside to turning it on. Your QUIC enabled clients on high-performing networks will get a small boost, here and there, but you’ll see your biggest gains in the regions where connectivity needs some help.</p><p>Likewise, remember that your HTTPS Load Balancer is already getting the benefits of BBR for the Google Front Ends, so turning on QUIC just helps that even more!</p><p>Now it’s worth noting that QUIC requires a client which supports the protocol, so unless you’re writing your own client with support, make sure you check out what browsers support the protocol, to make sure you’re hitting your target market.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=53799b0a16ca" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Reduce latency with Stackdriver Trace]]></title>
            <link>https://medium.com/@duhroach/reduce-latency-with-stackdriver-trace-bb3ddde85e06?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/bb3ddde85e06</guid>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Wed, 17 Oct 2018 12:15:14 GMT</pubDate>
            <atom:updated>2018-10-17T12:15:14.687Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><p>One of my favorite things about <a href="https://cloud.google.com/appengine/">App Engine</a> is that your requests are automatically traced, so you can see where during a request that your execution time is going. Shortly after, I showed a small technique that allowed you to insert custom trace blocks (since most trace data is RPC based).</p><p>Now, I’m really excited to talk about how tracing can be rolled out to all your other systems, even the ones not running on app engine.</p><h3>Recap: Stackdriver Tracing</h3><p>Stackdriver Trace allows you to analyze how customer requests propagate through your application, and is immensely useful for reducing latency and performing root cause analysis.</p><p>Trace continuously samples client requests, which it submits to the Stackdriver service to display their propagation / latency results.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/531/1*IjDrBIIQs81mdv0ulfvpRg.png" /></figure><p>One of the tricks though, is that it doesn’t <em>fully</em> capture your call graph (like a flame chart in Stackdriver Profiler would) but rather focuses on key paths around RPC calls, which generally result in most of your bottlenecks for the average application.</p><h3>Everybody trace now!</h3><p>As mentioned, if you’ve been an App Engine standard developer, chances are you’re familiar with this setup, since your requests have been getting traced automatically for some time now. But tracing (and the exploration of that data) is useful enough, which is why it was time to roll it out to other languages &amp; compute offerings.</p><p>Customers tracing applications on VMs or containers (including Compute Engine, App Engine flexible environment, and Kubernetes Engine, as well as other non-Google services) can use a new set of instrumentation libraries to submit traces to the service, in a number of languages: Java, Python, NodeJs, Golang, .Net, Ruby, and PHP. We use <a href="https://opencensus.io/">OpenCensus</a> (a project created by Google) to capture traces from most of these languages, and more languages will gain OpenCensus as time goes on.</p><h3>What gets traced?</h3><p>The client-side instrumentation automatically patches well-known modules to insert calls to functions that start, label, and end spans to measure latency of RPCs (such as mysql, redis, etc.) and incoming requests (such as express, hapi, etc.). As each RPC is typically performed on behalf of an incoming request, we must make sure that this association is accurately reflected in span data.</p><p>While this happens automatically with the libraries, you can also add custom spans to your code to catch the important bits that fall between.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/943/1*ifBNB4FB1DcL7I2Ep-vXYQ.png" /></figure><h3>More info</h3><p>To get started with Stackdriver APM, simply link the appropriate instrumentation library for each tool to your app and start gathering telemetry for analysis. Stackdriver Debugger and GitHub Enterprise and GitLab, adding to our existing code mirroring functionality for GitHub, Bitbucket, Google Cloud Repositories, as well as locally-stored source code</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bb3ddde85e06" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Application performance management with Stackdriver]]></title>
            <link>https://medium.com/@duhroach/application-performance-management-with-stackdriver-844300899d52?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/844300899d52</guid>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[performance]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Wed, 17 Oct 2018 12:10:43 GMT</pubDate>
            <atom:updated>2018-10-17T12:17:06.796Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><p>Understanding the performance of production systems is notoriously difficult. Not only is it difficult to replicate the exact scenario in which the product is being used in the wild, but adding profiling adds an additional load on the production system, which could inadvertently hurt your performance.</p><p>This is a catch-22, since if you don’t analyze code execution in production, unexpectedly resource-intensive functions increase the latency and cost of web services every day, without anyone knowing or being able to do anything about it.</p><p>This predicament is where many of us find our mental energy : We need to constantly perf-test in prod, but doing so hurts our overall performance.</p><p>The trick to solving this is finding a system which can do profiling across all of your deployments while keeping the overhead low.</p><p>This is where <a href="https://cloud.google.com/profiler/">Stackdriver Profiler</a> comes in.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fvideoseries%3Flist%3DPLIivdWyY5sqK5zce0-fd1Vam7oPY-s_8X&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dcn--Wac4Qxg&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fcn--Wac4Qxg%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/28a5794245e683f85efd50b47df96493/href">https://medium.com/media/28a5794245e683f85efd50b47df96493/href</a></iframe><h3>Stackdriver Profiler</h3><p><a href="https://cloud.google.com/profiler/">Stackdriver Profiler</a> is a statistical, low-overhead, sampling-based profiler that continuously gathers CPU usage and memory allocation information from your production application instances.</p><p>It attributes that information to the source code that generated it, helping you identify the parts of the code that are consuming the most resources, and otherwise illuminating the performance characteristics of the code.</p><p>Plus its got a few other features:</p><ol><li>It analyzes code execution across all environments.</li><li>It runs continually and uses statistical methods to minimize impact on targeted codebases.</li><li>It makes it more cost-effective to identify and re-mediate your performance problems rather than scaling up and increasing your monthly bill.</li></ol><p>Let’s take a look at it a little closer.</p><h3>Using it.</h3><p>Just to show a few things off, I’ve deployed a small Go application in Google Cloud Shell, which imports the `<em>cloud.google.com/go/profiler</em>` package and starts the profiler at the beginning of the application:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tAiRmpLxfiMzJNxiXjogkA.png" /></figure><p>Then we just let the program run. Everything else is being taken care of in the background.</p><p>Next, in the Google Cloud Platform Console dashboard, go to Profiler:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/285/1*O8Wx2hgMKrDjHw0v9DA8cQ.png" /></figure><p>Which will bring you to the profiler interface.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/869/1*Ag3EnD_TWiTcWP_egH0_9g.png" /></figure><p>It then displays this data on a flame chart, presenting the selected metric (CPU time, wall time, RAM used, contention, etc.) for each function on the horizontal axis, with the function call hierarchy on the vertical axis.</p><p>You can do cool stuff like CPU, Heap, mutex usage, thread data and other fun things. The UI lets you combine and scrub this data over a nifty time range.</p><h3>What’s the overhead?</h3><p>Stackdriver Profiler collects profiling data for 10 seconds every 1 minute for a single instance of a configured service in a single <a href="https://cloud.google.com/compute/docs/regions-zones/">Google Compute Engine zone</a>. For example, if your <a href="https://cloud.google.com/kubernetes-engine/">Kubernetes Engine</a> service runs 10 replicas of a pod If, for example, your <a href="https://cloud.google.com/kubernetes-engine/">Kubernetes Engine</a> service runs 10 replicas of a pod, then each pod will be profiled approximately once in 10 minutes.</p><p>The overhead of the CPU and heap allocation profiling at the time of the data collection is less than 5 percent. Amortized over the execution time and across multiple replicas of a service, the overhead is commonly less than 0.5 percent, making it an affordable option for always-on profiling in production systems.</p><h3>More info</h3><p>To get started with <a href="https://cloud.google.com/apm/">Stackdriver APM</a>, simply link the appropriate instrumentation library for each tool to your app and start gathering telemetry for analysis. Stackdriver Debugger and GitHub Enterprise and <a href="https://about.gitlab.com/">GitLab</a>, adding to our existing code mirroring functionality for GitHub, <a href="https://bitbucket.org/">Bitbucket</a>, <a href="https://cloud.google.com/source-repositories/">Google Cloud Repositories</a>, as well as locally-stored source code</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=844300899d52" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Datastore & Sharded counters]]></title>
            <link>https://medium.com/@duhroach/datastore-sharded-counters-2ba6da7475b0?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/2ba6da7475b0</guid>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Fri, 07 Sep 2018 02:22:05 GMT</pubDate>
            <atom:updated>2018-09-08T11:12:35.478Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><p>Nomad Socialite was a new geo-location game, where players traveled all around the world to rack up points, catch the latest in urban events, and meet a whole community at the same time. So, catching a plan to San Fran, hitting the hot new Poké popup, and catching their rare collectible digital item can help rack up some huge points.</p><p>The challenge, however, was that from a producer perspective, it was getting hard to track analytics on all these events to hand back to the proprietors running events. Once the event size got large enough, the analytics system, (which was powered by Datastore) started to slow significantly when updating.</p><p>When you’re talking about Datastore, this type of problem comes up all the time, and is simple to identify: Contention</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fvideoseries%3Flist%3DPLIivdWyY5sqK5zce0-fd1Vam7oPY-s_8X&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DxKLel0KgOkg&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FxKLel0KgOkg%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/603520ffda1694aa9111abd97dd2efd8/href">https://medium.com/media/603520ffda1694aa9111abd97dd2efd8/href</a></iframe><h3>Review, entity contention</h3><p>Simply put, Datastore contention occurs when a single entity or entity group is updated too rapidly. The datastore will queue concurrent requests to wait their turn, but if the number of edits on an entity is too high, things will eventually slow down (as the requests stack up) until time-out errors are thrown.</p><p>The most common way this limitation gets encountered is when you update an entity with every request — for example, <strong>counting the number of views to a page on your site</strong>.</p><p>Or in the case of Nomad Socialite: Updating the analytics data for an event meant keeping a running count of the number of users logged in, and all their related data sets.</p><p>Now, when this happens, there’s lots of ways to address it, from a code perspective (I’ll leave you to <a href="https://cloud.google.com/appengine/articles/scaling/contention">this document </a>for some of the more common ones).</p><p>From my perspective though, there’s only one good solution : Sharding.</p><h3>Sharding to the rescue</h3><p>As we’ve discussed before, <a href="https://medium.com/@duhroach/datastore-lexicographical-contention-fc02fb4864e9">Datastore runs on top of Bigtable</a>, and thus is at the mercy of it’s performance characteristics.</p><p>If you need to update an entity at a higher rate than Bigtable permits, then you can use <em>replication</em> to accomplish your task.</p><p>Sharding effectively duplicates an entity and uses some manual load balancing to write updates to the clones randomly instead of all to the same item. The result is that each clone is partially updated (and the data is not the same between them). When you read, later, fetch all the copies and sum them together on the client. Using this strategy, you would store N copies of the same entity allowing N times higher rate of writes than supported by a single entity.</p><p>To prove this, we wrote a small test and then did a 60 minute Load test via Artillery in order to simulate users. In the Google Cloud console, we can see the execution time looks like for trying to update a single entity counter for users.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/387/1*wh-U_dhhZkIcI66d_W4iQQ.png" /></figure><p>We can also see that in our sharded version, performance is drastically better:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/387/1*aPxVkfBEryVRlD9xyaHL2g.png" /></figure><p>Notice that the execution time drops considerably since there’s less contention on the entities themselves.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2ba6da7475b0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Datastore & Lexicographical contention]]></title>
            <link>https://medium.com/@duhroach/datastore-lexicographical-contention-fc02fb4864e9?source=rss-6e1a63c4fcd1------2</link>
            <guid isPermaLink="false">https://medium.com/p/fc02fb4864e9</guid>
            <category><![CDATA[big-data]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Colt McAnlis]]></dc:creator>
            <pubDate>Thu, 23 Aug 2018 15:40:19 GMT</pubDate>
            <atom:updated>2018-08-23T15:40:19.072Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i8gFMHNLtQJj-DnrepTSjw.jpeg" /></figure><p>Urban IoT was is a sensor and spatial representation company. Their work is simple, they deploy a whole load of sensors in an urban area that monitor everything from noise, temperature, humidity, pressure, (and more) .They were noticing issues when pushing the time stamped data to GCP Datastore, saying that after a while, their reads slowed down significantly on their dashboards.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F26bomQzJHT8%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D26bomQzJHT8&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F26bomQzJHT8%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/c19b0d45d38a3e292787160accd334b8/href">https://medium.com/media/c19b0d45d38a3e292787160accd334b8/href</a></iframe><h3>Stamped out.</h3><p>Cloud Datastore is built on top of Google’s NoSQL database, <a href="https://cloud.google.com/bigtable">Bigtable</a>, and is subject to Bigtable’s performance characteristics. Bigtable scales by sharding rows into separate tablets (aka a contiguous unit of storage); When a Bigtable tablet experiences a high write rate, the tablet will have to “split” into more than one tablet which is the core component that allows Bigtable to properly scale.</p><p>The important point here is this : <em>Sharded rows on separate tablets are lexicographically ordered by key</em>.</p><p>By default, Cloud Datastore allocates keys using a scattered algorithm. As such, when values are randomly or even semi-randomly distributed, tablet splits function well. This is because the work to write multiple values is distributed amongst several Bigtable tablets.</p><p>However when the keys are lexicographically close, (<em>like a monotonically increasing timestamp…</em>) this work gets isolated into a small update window, and slows things down.</p><p>Which, low and behold, was exactly what Urban IoT was doing.</p><h3>Stamped out.</h3><p>Remember that for indexed values, we must write corresponding index rows sharded across tablets. If you’re creating new entities at a high rate with monotonically increasing indexed property (like a timestamp), then you’ll run into hotspotting for reads. The result is that the “eventual consistency” model of datastore will take longer to get “consistent” and as performance worsens, read queries will get longer, and eventually cause timeouts.</p><p>The take-away about this problem is that hitting this condition is really rare.</p><p>To prove this, check out the graph below; It’s a 250QPS load test to datastore, creating entities with keys that are timestamps over a 20 minute window.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/871/1*WuRpkAgisJdElF1mP5gZnA.png" /></figure><p>It’s not until we jack up the QPS to 750, and run the test for at least an hour, that things start to go south:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/732/1*VugfwWuwYwka8S6fJ4tK5w.png" /></figure><p>Sadly though, this is _exactly_ the situation that Urban IoT was in. They had hundreds of thousands of sensors distributed in an urban environment, all creating new timestamped data at an alarmingly high rate.</p><h3>The fix is in.</h3><p>Recall that by default, Cloud Datastore allocates keys using a scattered algorithm Thus you will not normally encounter hotspotting on Cloud Datastore writes if you create new entities at a high write rate using the default ID allocation policy. Typically you only see this type of problem if you’re creating the IDs yourself, and making them linear.</p><p>If you do have a key or indexed property that will be monotonically increasing then you can prepend a random hash to ensure that the keys are sharded onto multiple tablets. This is problematic if you plan on doing queries, as you will need to prefix and unprefix the values, then join the results in memory — but it will reduce the error rate of your writes</p><p>Doing so let us get performance back down to what they would expect @ the 250QPS rate, without those hot spotting issues.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/599/1*rQQqagklVyOo9YgAaTgo1A.png" /></figure><h3>Last note</h3><p>And one more tip:</p><p><strong>Don’t prematurely optimize for this case, since chances are, you won’t run into it.</strong></p><p>It took a couple days of really hammering on Datastore to get our tests to behave the way that Urban IoT was seeing in the wild. So unless you’re in that ballpark, I suggest spending your time in other areas ;)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fc02fb4864e9" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>