<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://engineering.linkedin.com"  xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>LinkedIn Engineering</title>
 <link>http://engineering.linkedin.com</link>
 <description></description>
 <language>en</language>
<item>
 <title>Introduction: Technical Paper on LinkedIn&#039;s A/B Testing Platform</title>
 <link>http://engineering.linkedin.com/ab-testing/introduction-technical-paper-linkedins-ab-testing-platform</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;&lt;p dir=&quot;ltr&quot;&gt;
    &lt;a href=&quot;https://engineering.linkedin.com/ab-testing/evolution-ab-testing-platform-linkedin&quot;&gt;XLNT&lt;/a&gt; is the end-to-end
    A/B testing platform used at LinkedIn to not only solve the day-to-day A/B testing needs across the company, but also sophisticated use cases that are
prevalent in a social network setting. With all the    &lt;a href=&quot;https://engineering.linkedin.com/ab-testing/why-experimentation-so-important-linkedin&quot;&gt;lessons learned&lt;/a&gt; from using the platform, we decided to
    take an in-depth look at how we approach A/B testing and write a technical paper. This post is based on our paper and shares how we built the platform,
    dealt with some challenging scenarios and fostered a strong experimental culture.
&lt;/p&gt;
&lt;br /&gt;&lt;p dir=&quot;ltr&quot;&gt;
    &lt;font size=&quot;3&quot;&gt;&lt;strong&gt;The XLNT Platform&lt;/strong&gt;&lt;/font&gt;
&lt;br /&gt;
XLNT was designed to encompass each of the three steps of the testing process: design, deploy and analyze.
&lt;/p&gt;
&lt;ul&gt;&lt;li dir=&quot;ltr&quot;&gt;
        &lt;p dir=&quot;ltr&quot;&gt;
A highlight of our &lt;strong&gt;design&lt;/strong&gt; capability is flexible targeting. Not only does the platform provide 40+ built-in member attributes stored in            &lt;a href=&quot;http://engineering.linkedin.com/tags/voldemort&quot;&gt;Voldemort&lt;/a&gt; for experimenters to leverage, it also allows external attributes to be
            onboarded seamlessly and provides an integrated way for real-time attributes available only in a runtime request to be used.
        &lt;/p&gt;
    &lt;/li&gt;
    &lt;li dir=&quot;ltr&quot;&gt;
        &lt;p dir=&quot;ltr&quot;&gt;
            In the &lt;strong&gt;deploy&lt;/strong&gt; stage, we have a straightforward two-step process to implement an experiment in the application layer and have enabled centralized
service configuration that is totally independent of application code release, leveraging &lt;a href=&quot;http://engineering.linkedin.com/restli/linkedins-restli-moment&quot;&gt;Rest.li&lt;/a&gt; and            &lt;a href=&quot;http://data.linkedin.com/blog/2012/10/driving-the-databus&quot;&gt;Databus&lt;/a&gt;.
        &lt;/p&gt;
    &lt;/li&gt;
    &lt;li dir=&quot;ltr&quot;&gt;
        &lt;p dir=&quot;ltr&quot;&gt;
            Finally, &lt;strong&gt;analyzing&lt;/strong&gt; experiments is fully automated, with the pipeline consuming more than 10TB of data and producing more than 150million summary
            records stored in &lt;a href=&quot;https://engineering.linkedin.com/analytics/real-time-analytics-massive-scale-pinot&quot;&gt;Pinot&lt;/a&gt; on a daily basis. This is
a large scale join and aggregate process enabled by the            &lt;a href=&quot;https://engineering.linkedin.com/big-data/open-sourcing-cubert-high-performance-computation-engine-complex-big-data-analytics&quot;&gt;Cubert&lt;/a&gt;
framework, which consumes application code logs ETLed to our HDFS clusters from            &lt;a href=&quot;http://engineering.linkedin.com/kafka/running-kafka-scale&quot;&gt;Kafka&lt;/a&gt; topics and data for 1000+ engagement metrics, preprocessed by an
            independent pipeline. A highlight of our analysis pipeline is its ability to enable multi-dimensional analysis in certain scenarios for
            experimenters to dig deeper and get more actionable insights.
        &lt;/p&gt;
    &lt;/li&gt;
&lt;/ul&gt;&lt;p dir=&quot;ltr&quot;&gt;
    &lt;font size=&quot;3&quot;&gt;&lt;strong&gt;Beyond the Basics&lt;/strong&gt;&lt;/font&gt;
&lt;br /&gt;
We face several challenging A/B testing scenarios at LinkedIn, some of which are specific to experimentation on social networks.
&lt;/p&gt;
&lt;p dir=&quot;ltr&quot;&gt;
    In an organization running hundreds of experiments daily, interactions pose a serious threat to experiment trustworthiness. We use XLNT to address the
    three most common concerns and use cases related to interactions between experiments. While experiments are fully overlapping and orthogonal by default,
    there are simple solutions to splitting traffic to allow experiments to run disjointly, allow interaction analysis in a full factorial fashion before
    analyzing each factor separately, and enable fractional factorial design, where only certain combinations from different factors are implemented and
    analyzed.
&lt;/p&gt;
&lt;p dir=&quot;ltr&quot;&gt;
    We have enabled testing on guests (based on browser IDs) as well as on other units. A challenge we have resolved is to serve a unified experience for users
    switching between member and guest status, while ensuring we have measurement for both. An even more interesting problem arises when there are different
    experimental units within the same entity type, arising particularly in a social network setting, where the same user can play two different roles with
    each needing to be tested separately. In the paper, we highlight this problem with an example based on a “viewer/viewee” experiment and describe the bias
    variance tradeoff.
&lt;/p&gt;
&lt;p dir=&quot;ltr&quot;&gt;
    Offline experiments are integrated into XLNT as well. The challenge here is to avoid selection bias when we run email experiments, experiments coupled with
    email campaigns, and cohort experiments. We can’t simply use active members as the population set for email experiments. We also have to correct/avoid bias
    if we want to analyze the effect of the experiments and email campaigns together/separately. When running cohort analysis there is a subtilty of
    dynamically updating the cohort selection during the experiment when the selection criteria and the experiment outcome are not independent.
&lt;/p&gt;
&lt;p dir=&quot;ltr&quot;&gt;
    When it comes to network A/B testing, we can’t assume sample responses are independent of the treatment assignment of others. Our solution is based on a
    sampling and estimation framework. In the sampling stage, we partition users into clusters and randomize at cluster level. In the estimation stage, we used
    some more sophisticated estimators. The network A/B tests we have run at LinkedIn based on this sampling and estimation framework have indicated strong
    network effects.
&lt;/p&gt;
&lt;br /&gt;&lt;p dir=&quot;ltr&quot;&gt;
    &lt;font size=&quot;3&quot;&gt;&lt;strong&gt;Fostering an Experimental Culture&lt;/strong&gt;&lt;/font&gt;
&lt;br /&gt;
There are several XLNT features and concepts we introduced at LinkedIn to enable us to take education and evangelization past the &quot;classroom&quot;.
&lt;/p&gt;
&lt;p dir=&quot;ltr&quot;&gt;
    We integrated experiment reports with business reporting by using a unified metric definition across the entire organization. This provides the foundation
    that enables other organizations such as Finance to bake A/B test results into business forecasting.
&lt;/p&gt;
&lt;p dir=&quot;ltr&quot;&gt;
    We also introduced site wide impact, a concept that not only allow us to provide a directional signal, but also the size of the global lift that will occur
    when the winning treatment is ramped to 100 percent. We conceptualized this feature so that we can compute site wide impact leveraging readily available
    summary statistics without having to doubling our computation effort. A paradox is that for metrics like “CTR”, local and site wide impact can disagree
    directionally.
&lt;/p&gt;
&lt;p dir=&quot;ltr&quot;&gt;
    As an effort to simplify multiple testing, we introduced a simple two-step rule of thumb for experimenters to follow that is mathematically equivalent to a
    Bayesian interpretation of people’s prior belief on whether a metric would be impacted.
&lt;/p&gt;
&lt;p dir=&quot;ltr&quot;&gt;
    To drive greater transparency regarding experiment launch decisions, we launched Most Impactful Experiments, a tool we built to bubble up notable impacts
    among all experiments for each product metric. We use a three-step algorithm to control false discovery. A couple of key lessons we learned from building
    the feature are shared in the paper.
&lt;/p&gt;
&lt;br /&gt;&lt;p dir=&quot;ltr&quot;&gt;
    For a more in-depth look at LinkedIn’s A/B testing strategy and technology, read &lt;a href=&quot;http://dl.acm.org/citation.cfm?id=2788602 &quot; target=&quot;_blank&quot;&gt;the entire paper&lt;/a&gt;.
&lt;/p&gt;
&lt;div&gt;
    &lt;br /&gt;&lt;/div&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/ab-testing&#039; rel=&#039;tag&#039;&gt;A/B Testing&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/xlnt&#039; rel=&#039;tag&#039;&gt;xlnt&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/kdd&#039; rel=&#039;tag&#039;&gt;KDD&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Nanyu Chen&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;https://www.linkedin.com/profile/view?id=AAIAAAMlYkUBIffOuX0NByDI_kWIONUeyd5A07g&amp;amp;trk=nav_responsive_tab_profile&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;March 2014&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/Nanyu_profile.jpg&quot; width=&quot;400&quot; height=&quot;400&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Sr Applied Research Engineer&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Thu, 01 Oct 2015 07:00:00 +0000</pubDate>
 <dc:creator>Nanyu Chen</dc:creator>
 <guid isPermaLink="false">399 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/ab-testing/introduction-technical-paper-linkedins-ab-testing-platform#comments</comments>
</item>
<item>
 <title>Creating Community Around Open Source, Working With Legacy Code, Architecture Hoisting and More</title>
 <link>http://engineering.linkedin.com/publisher-platform/creating-community-around-open-source-working-legacy-code-architecture-hoisting</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;&lt;p&gt;LinkedIn’s publishing platform gives professionals a way to share their personal opinions about topical professional news and interests, including our engineers. Here, we regularly round up some of the best pieces written recently by LinkedIn engineers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/building-communities-todd-palino&quot; target=&quot;_blank&quot;&gt;&quot;Building Communities&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/toddpalino&quot; target=&quot;_blank&quot;&gt;Todd Palino&lt;/a&gt;, Staff Site Reliability Engineer at LinkedIn&lt;/strong&gt;
&lt;br&gt;Todd discusses how creating an open and welcoming community is essential to the success and continued development of open source projects. He argues that accepting feedback from others, encouraging discussion, and treating even basic questions or trivial concerns as important contributions ultimately leads to better open source projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/crafting-insanity-working-legacy-code-brendan-drew&quot; target=&quot;_blank&quot;&gt;&quot;Crafting Insanity (or: Working With Legacy Code)&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/brendandrew&quot; target=&quot;_blank&quot;&gt;Brendan Drew&lt;/a&gt;, Staff Software Engineer at LinkedIn&lt;/strong&gt;
&lt;br&gt;Legacy code can drive any engineer crazy, but Brendan discusses how having a measured approach toward working with legacy code can make your job – and the job of everyone else who comes in contact with it later – much easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/architecture-hoisting-david-max&quot; target=&quot;_blank&quot;&gt;&quot;Vigilance, Guide Rails, and Architecture Hoisting&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/davidpmax&quot; target=&quot;_blank&quot;&gt;David Max&lt;/a&gt;, Senior Software Engineer at LinkedIn&lt;/strong&gt;
&lt;br&gt;Details matter. Ask the folks at NASA who lost the Mars Climate Orbiter 15 years ago because they failed to notice a difference between systems that measured in pounds and inches, rather than the metric system. The project’s failure is an example of a common conundrum in large-scale projects: How to reduce risk in a project without putting in too many constraints. David looks at “architecture hoisting” a development system that builds risk mitigation into the core code of a project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/i-have-only-one-regret-should-worked-more-jens-pillgram-larsen&quot; target=&quot;_blank&quot;&gt;&quot;I Have Only One Regret: I Should Have Worked More.&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/jenspillgram?trk=pulse-det-athr_prof-art_hdr&quot;&gt;Jens Pillgram-Larsen&lt;/a&gt;, Senior Engineering Manager, Development Tools at LinkedIn&lt;/strong&gt;
&lt;br&gt;Work-life balance is a constant battle for nearly everyone. Jens discusses how hard work toward something you’re passionate about can actually be an incredibly enriching part of life, rather than its natural opposite.&lt;/p&gt;
&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/publisher-platform&#039; rel=&#039;tag&#039;&gt;publisher platform&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/content&#039; rel=&#039;tag&#039;&gt;content&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Erran Berger&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;https://www.linkedin.com/in/erranberger&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;2009&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/Erran%20Berger%20headshot_9.jpg&quot; width=&quot;176&quot; height=&quot;177&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Head of Engineering, Content Products&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Wed, 30 Sep 2015 19:15:36 +0000</pubDate>
 <dc:creator>Erran Berger</dc:creator>
 <guid isPermaLink="false">400 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/publisher-platform/creating-community-around-open-source-working-legacy-code-architecture-hoisting#comments</comments>
</item>
<item>
 <title>Espresso Onboarding Experiences: InMail</title>
 <link>http://engineering.linkedin.com/espresso-migration-inmail/espresso-onboarding-experiences-inmail</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;&lt;p&gt;
Fast growth is a happy problem to have, but not an easy one to solve. LinkedIn has experienced rapid member growth over the years and many of our engineers have witnessed the corresponding explosive data growth in awe. Until recently, LinkedIn relied on a traditional RDBMS as a primary data store for most of our data. Hundreds of terabytes of data were organized into Oracle shards that were incrementally provisioned as member growth continued. Several problems surfaced including:
&lt;/p&gt;
&lt;ol&gt;
&lt;li style=&quot;margin-bottom:5px;&quot;&gt;&lt;b&gt;Hot Shards&lt;/b&gt; &amp;mdash; Typical Oracle shards were created in the order by which members joined the LinkedIn service.  Members who joined early on tended to accumulate more activities over time.  This resulted in imbalanced traffic across shards, where some shards saw more traffic than others (i.e. hot shards).&lt;/li&gt;
&lt;li style=&quot;margin-bottom:5px;&quot;&gt;&lt;b&gt;Schema Evolution&lt;/b&gt; &amp;mdash; Data schemas need to evolve all the time to incorporate more information as business requirements change. In Oracle databases (or for any other traditional DBMS for that matter), this typically means a DBA running manual maintenance with &lt;code&gt;ALTER TABLE&lt;/code&gt; queries. This is an error prone and time consuming process as millions of rows are read-locked during the maintenance.&lt;/li&gt;
&lt;li style=&quot;margin-bottom:5px;&quot;&gt;&lt;b&gt;Provisioning&lt;/b&gt; &amp;mdash; Creating additional shards were not automatic. Provisioning of a shard translates to manual DBA work, as well as configuration changes from the application team. Coordinating such efforts were often painful. &lt;/li&gt;
&lt;li style=&quot;margin-bottom:5px;&quot;&gt;&lt;b&gt;Cost&lt;/b&gt; &amp;mdash; Specialized hardware and annual software licensing costs were expensive.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Fast forward to 2015, most of the major Oracle systems have been migrated over to Espresso, a horizontally scalable NoSQL database developed internally at LinkedIn.  We have &lt;a href=&quot;https://engineering.linkedin.com/espresso/introducing-espresso-linkedins-hot-new-distributed-document-store&quot;&gt;written extensively about the Espresso design&lt;/a&gt; in an earlier post. Espresso currently powers all of LinkedIn’s member profile data, InMail, and a subset of our homepage and mobile applications.
&lt;/p&gt;
&lt;p&gt;
How did we get to this point? The migration from the legacy Oracle implementation to Espresso is an interesting topic on its own. The effort was more than just transferring bytes from one database to another, but a set of carefully designed features and workflows. We hope to turn this into a series of blog posts pointing out the highlights of this journey. But let’s start with the largest first — InMail.
&lt;/p&gt;

&lt;h2 style=&quot;font-size:1.5em;&quot;&gt;InMail&lt;/h2&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.linkedin.com/static?key=about_inmail&quot;&gt;InMail&lt;/a&gt; is one of the core features that makes LinkedIn an engaging professional network service. It is a messaging service that connects 380M currently registered members, and is by far the largest dataset at LinkedIn. At a high level, each member is associated with one mailbox that contains messages received, sent, and archived. InMail is characterized by several access patterns which make it a unique use case.
&lt;/p&gt;

&lt;ul&gt;
&lt;li style=&quot;margin-bottom:5px;&quot;&gt;&lt;b&gt;Mailbox Search&lt;/b&gt; &amp;mdash; A member’s mailbox contains sent/received/archived messages. The InMail application needs to perform a full-text search over all previous messages.&lt;/li&gt;
&lt;li style=&quot;margin-bottom:5px;&quot;&gt;&lt;b&gt;Maintain Counter&lt;/b&gt; &amp;mdash; Each time a message is received, corresponding counters (e.g. number of messages unread) need to be updated. The update of the message and the counters need to be transactional.&lt;/li&gt;
&lt;li style=&quot;margin-bottom:5px;&quot;&gt;&lt;b&gt;Paginated Results&lt;/b&gt; &amp;mdash; 99% of the time, a member is interested in the N most recent messages. The application displays paginated messages and search results in reverse chronological order. The messages that are very old are rarely accessed. This usage pattern in particular can be utilized for optimizations.&lt;/li&gt;
&lt;li style=&quot;margin-bottom:5px;&quot;&gt;&lt;b&gt;Write Spikes&lt;/b&gt; &amp;mdash; Invitations sent out to a member’s connections can generate a large number of mailbox writes in a relatively short amount of time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 style=&quot;font-size:1.5em;&quot;&gt;Optimizations&lt;/h2&gt;
&lt;p&gt;
Espresso is a horizontally scalable document store with secondary index support. Even without introducing additional features, Espresso design provides necessary functionality for the InMail use cases. However, constantly updating hundreds of millions of mailboxes while maintaining a search index does not come free. Several optimizations were implemented as a result:
&lt;/p&gt;
&lt;h3&gt;Time Partitioned Indexes&lt;/h3&gt;
&lt;p&gt;
For InMail use case, Espresso internally maintains its secondary index using &lt;a href=&quot;https://lucene.apache.org/&quot;&gt;Lucene&lt;/a&gt;, whose segments are stored as MySQL rows. When the application sends a search query for a particular mailbox, Espresso needs to read all index segments stored in &lt;a href=&quot;https://www.mysql.com/&quot;&gt;MySQL&lt;/a&gt; and assemble them together as a Lucene index. For mailboxes with a large number of messages, the cost of index assembly becomes increasingly expensive.
&lt;/p&gt;

&lt;div style=&quot;padding:15px;color:#26c;background-color:#fff;font-size:1.4em;;font-family:&#039;san francisco&#039;, &#039;helvetica&#039;,&#039;helvetica neue&#039;;font-weight:200;text-transform:uppercase;border-left:5px solid #26c;margin-bottom:10px;line-height:1.2em;font-style:italic;&quot;&gt;
Most of the members spend time accessing the most recent N messages.
&lt;/div&gt;

&lt;p&gt;
The problem is alleviated by carefully aligning the system with the user&#039;s data access pattern. Since most of the members spend time accessing the most recent N messages, it makes sense to organize the indexes into a series of time buckets. Each bucket has a fixed size, and once the number of index segments in a given bucket exceeds a value, a new bucket is created. This localizes index access/update to a relatively small bucket, and effectively speeds up the mailbox searches and paginated results.
&lt;/p&gt;

&lt;div style=&quot;margin-left:10%;margin-right:10%&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/mailbox.jpeg&quot; style=&quot;width:100%&quot;&gt;
&lt;/div&gt;

&lt;h3&gt;Group Commits&lt;/h3&gt;
&lt;p&gt;
When the member invitations get sent out in bulk, the InMail application may generate a large number of requests for a mailbox (sent folder) in a relatively short period of time. This may result in hundreds of concurrent requests trying to update the index for the same mailbox. An index update is preceded by acquiring a write lock for the target mailbox, meaning other concurrent requests for the same mailbox are blocked. In a high throughput system, such lock contention typically leads to a thread pool exhaustion. Other requests are now starved.
&lt;/p&gt;

&lt;div style=&quot;padding:15px;color:#26c;background-color:#fff;font-size:1.4em;;font-family:&#039;san francisco&#039;, &#039;helvetica&#039;,&#039;helvetica neue&#039;;font-weight:200;text-transform:uppercase;border-left:5px solid #26c;margin-bottom:10px;line-height:1.2em;font-style:italic;&quot;&gt;
A bursty write pattern like this kept a few Espresso engineers up at night
&lt;/div&gt;

&lt;p&gt;
After a series of design proposals, we have introduced a feature called Group Commit. When a storage node observes high number of concurrent index writes waiting for the same lock, they are grouped together and executed by a single thread. Group commit strategy significantly increases the throughput since the construction of  index — the initial read of multiple index segment rows to assemble an index — is now reduced to once per group rather than per each index update request. Use of single thread also prevents excessive lock contention and starvation. The tradeoff here, of course, is the increased latency since individual requests are now dependent on all requests in the group finishing the execution. The increased latency can be compensated with client timeout adjustment. The benefits for group commit far exceeds the minor latency tradeoff.
&lt;/p&gt;

&lt;h3&gt;Materialized Aggregate&lt;/h3&gt;
&lt;p&gt;
InMail maintains several counters per mailbox. For example, when a new message is written to a mailbox, the number of unread messages is incremented by one. The unread message counter for a mailbox is decremented as one of the unread messages changes its status &lt;code&gt;(isUnread == false)&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
It’s very tempting to think that a transactional write can satisfy this feature. As such, the application could supposedly couple each message insert with a counter increment, and make a &lt;a href=&quot;https://engineering.linkedin.com/espresso/introducing-espresso-linkedins-hot-new-distributed-document-store&quot;&gt;transactional MULTI-PUT&lt;/a&gt; Espresso request. Even though the atomicity of the two writes would be guaranteed in a single cluster, this solution does not work for multiple data center cluster deployments. It is entirely possible that an update originated from a remote data center overwrite the local counter update. Depending on the order of events, this can actually produce a counter drift. &lt;/p&gt;

&lt;div style=&quot;padding:15px;color:#26c;background-color:#fff;font-size:1.4em;;font-family:&#039;san francisco&#039;, &#039;helvetica&#039;,&#039;helvetica neue&#039;;font-weight:200;text-transform:uppercase;border-left:5px solid #26c;margin-bottom:10px;line-height:1.2em;font-style:italic;&quot;&gt;
The workaround is to push the counter computation down to the storage level.
&lt;/div&gt;

&lt;p&gt;
We have defined a declarative mechanism to register trigger-like predicates and aggregate functions (albeit limited) when defining a document schema. As series of updates are performed in each storage node, the aggregates are transactionally recomputed according to the conditions defined by the predicates. The aggregate results (i.e. counters) themselves are not replicated across data centers, as the storage nodes in each data center can simply recompute their own mailbox counters with respect to all local and remote updates. This feature enables Espresso to maintain precise counters across multiple data centers.
&lt;/p&gt;

&lt;p&gt;
The following declaration maintains the number of unread messages through &lt;code&gt;COUNT()&lt;/code&gt; aggregate. For each update, number of rows that meets the predicate condition &lt;code&gt;(isUnread == true)&lt;/code&gt; is computed and written to &lt;code&gt;unreadCount&lt;/code&gt; field. 
&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/anonymous/e13ce0e58942b355666c.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;
The &lt;code&gt;SUM()&lt;/code&gt; is another aggregate that is available in Espresso. For example, it can be used to sum over the total amount of bytes for all messages in a mailbox. 
&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/anonymous/8f5d59da46f28339e76b.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;Personal Data Routing&lt;/h3&gt;
&lt;p&gt;
From a technical standpoint, deployment of a petabyte scale cluster is not inherently different from deploying a smaller cluster. However, deployment of such size needs careful consideration from another dimension &amp;mdash; &lt;a href=&quot;https://en.wikipedia.org/wiki/Capital_expenditure&quot;&gt;CAPEX&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
A typical Espresso cluster is deployed to three data centers, forming a data-everywhere, active/active topology. A write can originate in any data center and convergence will be reached through cross data-center replication. Espresso storage nodes within a data center also has a replica factor of 3, meaning each partition is typically 1 master and 2 slaves. With cost in the equation, the Espresso team needed to answer the hard question &amp;mdash; ‘How much redundancy do we really need?’
&lt;/p&gt;

&lt;div style=&quot;padding:15px;color:#26c;background-color:#fff;font-size:1.4em;;font-family:&#039;san francisco&#039;, &#039;helvetica&#039;,&#039;helvetica neue&#039;;font-weight:200;text-transform:uppercase;border-left:5px solid #26c;margin-bottom:10px;line-height:1.2em;font-style:italic;&quot;&gt;
How much redundancy do we really need?
&lt;/div&gt;

&lt;p&gt;
We found out that the answer to the cost question really hinges upon the following observations.
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Two data centers are sufficient for disaster recovery (well, most localized disasters).&lt;/li&gt;
&lt;li&gt;The CAPEX of adding a data center copy on a petabyte level is very high. Conversely, the savings from keeping number of copies to 2 is difficult to ignore.&lt;/li&gt;
&lt;li&gt;Some datasets are more personal than others. A mailbox is only accessed by the owner of the mailbox. As long as the member traffic is consistently routed to the same data center as his/her mailbox, we can afford to reduce geographic distribution of this dataset. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
For this reason, a strategic decision was made to limit each member&#039;s mailbox copy to two data centers, as opposed to &lt;i&gt;data-everywhere&lt;/i&gt;.
&lt;/p&gt;

&lt;div style=&quot;margin-left:5%;margin-right:5%;&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/logical.jpeg&quot; style=&quot;width:100%;&quot;&gt;
&lt;/div&gt;
&lt;p&gt;
Without going into too much detail, this simply means that the data for a given mailbox will not be found in all data centers.
&lt;/p&gt;

&lt;div style=&quot;padding:15px;color:#26c;background-color:#fff;font-size:1.4em;;font-family:&#039;san francisco&#039;, &#039;helvetica&#039;,&#039;helvetica neue&#039;;font-weight:200;text-transform:uppercase;border-left:5px solid #26c;margin-bottom:10px;line-height:1.2em;font-style:italic;&quot;&gt;
A logical data store backed by at most two data centers.
&lt;/div&gt;

&lt;p&gt;
We have built a routing layer called Personal Data Routing (PDR) for this purpose. Regardless of which data center a request originates from, the service layer is able to lookup a special routing table and forward the request to a logical data store backed by at most two physical data centers. With PDR, we are able to control the degree of redundancy at the data center level. InMail mailboxes are currently divided into two logical stores – USE and USW – and have achieved significant footprint (therefore cost) reduction.
&lt;/p&gt;

&lt;h2 style=&quot;font-size:1.5em;&quot;&gt;Migration&lt;/h2&gt;
&lt;h3&gt;Basic Idea&lt;/h3&gt;
&lt;p&gt;
When the InMail optimizations were tested and ready to go, it was time for the big move. The basic idea of moving data is actually not too different from moving boxes as you would if you were moving to a new house &amp;mdash; we pack, ship, load, cleanup and reorganize. 
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;Pack Boxes&lt;/b&gt; &amp;mdash; ETL data from Oracle to Hadoop, and transform the result into Espresso partitioned data&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ship &amp; Load&lt;/b&gt; &amp;mdash; Copy and load the partitioned Espresso data to all storage node replicas without taking any down time.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Cleanup &amp; Reorganize&lt;/b&gt; &amp;mdash; Remove import related files. Replay the rest of the events (what’s often called delta) from Oracle that have been updated since the ETL generation.
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Coordination and Workflow&lt;/h3&gt;
&lt;p&gt;
As the migration was about to start, there was a sense of urgency shared across teams as the operational complexity, licensing cost, and hardware footprint of maintaining Oracle instances were taking a toll each day. However, the timely migration was not simply a matter of ‘fast execution’, as it required coordinated efforts between multiple teams. It took careful planning from Oracle DBAs, InMail engineers, and Espresso engineers to come up with an optimal schedule. Eventually, the teams have agreed to proceed with the following schedule:
&lt;/p&gt;
&lt;div style=&quot;margin-left:5%;margin-right:5%;&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/workflow.jpeg&quot; style=&quot;width:100%;&quot;&gt;
&lt;/div&gt;
&lt;p&gt;
Although the pipeline looks relatively simple, there were subtle factors to consider in terms of sizing individual batches:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The amount of time spent generating and loading data is directly proportional to the amount of delta catchup required afterwards (that is, more data piles up over time).&lt;/li&gt;
&lt;li&gt;The pipeline is bound by the largest batch in the workflow.&lt;/li&gt;
&lt;li&gt;The pipeline runs optimally if the batches are relatively equal in size.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
We ended up choosing about five Oracle shards for a batch, which is equivalent to about 25 million member mailboxes. At the end of each batch, the stakeholders gathered together to checkpoint and then move to another one. When the pipelined workflow was in full throttle, each team was working fully in parallel. 
&lt;/p&gt;

&lt;h3&gt;ETL from Oracle to Hadoop&lt;/h3&gt;
&lt;p&gt;The process of taking ETL from the Oracle databases was owned by the DBA team. The DBAs took one shard from different Oracle instances so that the ETL can be generated in parallel. Since the shard sizes differ to some degree, there was some mixing-and-matching of the shards so that the total sum would be relatively constant between the batches. The Oracle dump was written to HDFS in a Hadoop cluster for additional transformation.&lt;/p&gt;
&lt;p&gt;The InMail engineering team then ran a &lt;a href=&quot;https://pig.apache.org/&quot;&gt;Pig&lt;/a&gt; script that transformed the Oracle dump into Espresso-ready data. Specifically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monolithic Oracle dump was transformed into partitioned data (1024 for InMail), using the same partitioning hash function from Espresso.&lt;/li&gt;
&lt;li&gt;In addition to the baseline data, secondary index segments were also generated. This was done so that we can enable the index lookup immediately after the import.&lt;/li&gt;
&lt;li&gt;Each partitioned data was converted into tab-delimited data file, which was ready to be loaded into MySQL server with &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; syntax. Binary portion of data were represented using HEX.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Copying and Bulk Loading Data&lt;/h3&gt;
&lt;p&gt;At the time of the migration, the HDFS in use was not able to maintain a high read throughput. A few trial runs also suggested that an increase in concurrency further degrades the HDFS read performance. Espresso cluster was not co-located with the Hadoop cluster, which was another limitation. We looked for a solution where the reads from the HDFS can be kept to a minimum.&lt;/p&gt;
&lt;p&gt;The target Espresso cluster had a replica factor of 3. Instead of all replicas performing the reads, we limited the direct interaction with the HDFS to a single replica per group. After that replica pulled the necessary partitions to its local file system, we let the other two replicas copy from it using compression and network pipes (e.g. &lt;code&gt;tar | gzip | netcat&lt;/code&gt;). This resulted in a hierarchical distribution of input data. The copy between the replicas were dramatically faster than the HDFS read, since it was done within the same network. The slow HDFS performance was eventually overcome with this workaround.&lt;/p&gt;

&lt;div style=&quot;margin-left:5%;margin-right:5%;&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/BulkCopy.003.jpg&quot; style=&quot;width:100%;&quot;&gt;
&lt;/div&gt;

&lt;p&gt;
Once each storage node obtained the partitioned data it requires, the actual load was done by a simple call to MySQL’s ‘&lt;code&gt;LOAD DATA INFILE&lt;/code&gt;’ query. The storage nodes were taking write traffic for the partitions that had completed the migration. We wanted to satisfy two requirements while the bulk load took place. 
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;b&gt;No down time.&lt;/b&gt; No read/write impact to the partitions that have already completed the migration.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;At least two replicas in service.&lt;/b&gt; This guaranteed that mastership handoff can still take place.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Since the bulk load process was I/O intensive in nature and would interfere with the service quality, we decided to take each instance offline to perform the bulk load. With Helix — the distributed system coordination service that Espresso uses — we were able to programmatically disable one storage node after another for the bulk loading maintenance. If the node undergoing maintenance happened to be a master, one of the slave replicas was automatically promoted as a master without service interruption. &lt;/p&gt;

&lt;div style=&quot;margin-left:5%;margin-right:5%;&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/BulkCopy.001.jpg&quot; style=&quot;width:100%&quot;&gt;
&lt;/div&gt;

&lt;p&gt;
After some trial runs, we were fully confident that each replica could run bulk import with high throughput. There were 12 replica groups (slices) for the InMail cluster. We repeatedly took one node out of each slice for maintenance, effectively loading 12 nodes at a time. 
&lt;/p&gt;

&lt;div style=&quot;padding:15px;color:#26c;background-color:#fff;font-size:1.4em;;font-family:&#039;san francisco&#039;, &#039;helvetica&#039;,&#039;helvetica neue&#039;;font-weight:200;text-transform:uppercase;border-left:5px solid #26c;margin-bottom:10px;line-height:1.2em;font-style:italic;&quot;&gt;
At all times, we maintained the full availability with a redundancy factor of at least 2.
&lt;/div&gt;

&lt;h3&gt;Replaying the Delta Writes&lt;/h3&gt;
&lt;p&gt;
After the bulk load, InMail engineers went back to the Oracle shards to collect the new writes (delta) that have been accumulating from the last ETL point. The amount of the delta writes was relatively low, so the catch up phase involved simply replaying the events to the Espresso router. This was done through a small dedicated cluster that was designed to take the Oracle delta writes and replay them as Espresso requests. Once the catch up was fully complete, the InMail team flipped the switch that made Espresso the source of truth for the newly migrated shards. For safety reasons, the dual-write to Oracle and Espresso were maintained throughout the migration process.
&lt;/p&gt;

&lt;h2 style=&quot;font-size:1.5em;&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;
The migration was swift. We’ve migrated 200+ million mailboxes (at the time of migration) in less than three month period while maintaining full availability. At this point, the InMail Oracle instances are fully decommissioned, eliminating complexity, operability problems and costs. &lt;/p&gt;

&lt;div style=&quot;padding:15px;color:#26c;background-color:#fff;font-size:1.4em;;font-family:&#039;san francisco&#039;, &#039;helvetica&#039;,&#039;helvetica neue&#039;;font-weight:200;text-transform:uppercase;border-left:5px solid #26c;margin-bottom:10px;line-height:1.2em;font-style:italic;&quot;&gt;
The migration of InMail was a valuable learning experience for many stakeholders.
&lt;/div&gt;

&lt;p&gt;
Espresso team has learned what it takes to serve the largest dataset at LinkedIn, and was able to introduce creative optimizations as a result. The experience also showcased that Espresso is ready to take on big challenges. Multiple teams have collaborated as one unit, demonstrating how the culture of valuing teamwork can truly have a business impact.
&lt;/p&gt;

&lt;p&gt;
The InMail migration was a team effort. Many thanks to the Oracle DBA team and InMail team (aka COMM team) for great execution. Numerous engineers in the Espresso team had sleepless nights in coming up with the optimizations and working on the migration. We also would like to thank &lt;a href=&quot;https://www.linkedin.com/in/alex&quot;&gt;Alex Vauthey&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/arnoldgreg&quot;&gt;Greg Arnold&lt;/a&gt; for their leadership, and &lt;a href=&quot;https://www.linkedin.com/in/mammadz&quot;&gt;Mammad Zadeh&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/dimitrovivo&quot;&gt;Ivo Dimitrov&lt;/a&gt; for their clear vision and guidance. 
&lt;/p&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/espresso-migration-inmail&#039; rel=&#039;tag&#039;&gt;Espresso Migration InMail&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-embedded-images field-type-image field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/mailbox.jpeg&quot; width=&quot;791&quot; height=&quot;621&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/logical.jpeg&quot; width=&quot;1079&quot; height=&quot;705&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/workflow.jpeg&quot; width=&quot;999&quot; height=&quot;493&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/BulkCopy.003.jpg&quot; width=&quot;876&quot; height=&quot;551&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/BulkCopy.001.jpg&quot; width=&quot;941&quot; height=&quot;377&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Eun-Gyu Kim&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;https://www.linkedin.com/pub/eun-gyu-kim/6/b54/5b2&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Jan 2013&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/0242959_0.jpg&quot; width=&quot;200&quot; height=&quot;200&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Staff Software Engineer&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Tue, 29 Sep 2015 07:00:00 +0000</pubDate>
 <dc:creator>Eun-Gyu Kim</dc:creator>
 <guid isPermaLink="false">398 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/espresso-migration-inmail/espresso-onboarding-experiences-inmail#comments</comments>
</item>
<item>
 <title>Bridging Batch and Streaming Data Ingestion with Gobblin</title>
 <link>http://engineering.linkedin.com/big-data/bridging-batch-and-streaming-data-ingestion-gobblin</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;&lt;style&gt;
  .centered {text-align: center;}
  .captioned {text-align: center; display: block; font-style: italic; font-size: 11px;}
&lt;/style&gt;

&lt;h1&gt;Genesis&lt;/h1&gt;&lt;br&gt;

&lt;p&gt;
Less than a year ago, we &lt;a href=&quot;https://engineering.linkedin.com/data-ingestion/gobblin-big-data-ease&quot;&gt;introduced Gobblin&lt;/a&gt;, a unified ingestion framework, to the world of Big Data. Since then, we’ve shared ongoing progress through a &lt;a href=&quot;http://www.slideshare.net/ShirshankaDas/linkedin-49299589&quot;&gt;talk&lt;/a&gt; at Hadoop Summit and a &lt;a href=&quot;http://www.vldb.org/pvldb/vol8/p1764-qiao.pdf&quot;&gt;paper&lt;/a&gt; at VLDB. Today, we’re announcing the open source release of &lt;a href=&quot;https://github.com/linkedin/gobblin/tree/gobblin_0.5.0&quot;&gt;Gobblin 0.5.0&lt;/a&gt;, a big milestone that includes &lt;a href=&quot;http://kafka.apache.org/&quot;&gt;Apache Kafka&lt;/a&gt; integration.
&lt;/p&gt;
&lt;p&gt;
Our motivations for building Gobblin stemmed from our operational challenges in building and maintaining disparate pipelines for different data sources across batch and streaming ecosystems. At one point, we were running more than 15 different kinds of pipelines, each with their own idiosyncrasies around error modes, data quality capabilities, scaling, and performance characteristics. Our guiding vision for Gobblin has been to build a framework that can support data movement across streaming and batch sources and sinks without requiring a specific persistence or storage technology. 
&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;
&lt;img style=&quot;border: 0px none ; width: 500px; height: auto; alt=&quot;Gobblin ingest ecosystem&quot; 
src=&quot;http://engineering.linkedin.com/sites/default/files/gobblin-ingest-ecosystem.png
&quot;&gt;
&lt;/p&gt;

&lt;p&gt;
Our first target sink was Hadoop’s ubiquitous HDFS storage system and that has been our focus for most of last year. All of LinkedIn’s data (hundreds of terabytes per day) needs to get aggregated into Hadoop before being combined in interesting ways to build insightful &lt;a href=&quot;https://www.linkedin.com/people/pymk&quot;&gt;data products&lt;/a&gt;, surface meaningful business insights for executive and analyst reporting, and provide &lt;a href=&quot;https://engineering.linkedin.com/ab-testing/xlnt-platform-driving-ab-testing-linkedin&quot;&gt;experimentation-focused analysis&lt;/a&gt;. At LinkedIn, Gobblin is currently integrated with more than a dozen data sources including Salesforce, Google Analytics, Amazon S3, Oracle, &lt;a href=&quot;http://www.slideshare.net/amywtang/li-espresso-sigmodtalk&quot;&gt;LinkedIn Espresso&lt;/a&gt;, MySQL, SQL Server, SFTP, Apache Kafka, patent and publication sources, &lt;a href=&quot;https://commoncrawl.org/&quot;&gt;CommonCrawl&lt;/a&gt;, etc.
&lt;/p&gt;

&lt;h1&gt;Open Source&lt;/h1&gt;&lt;br&gt;

&lt;p&gt;
We open-sourced Gobblin earlier this year and we’re excited by the amount of engagement and activity on &lt;a href=&quot;https://github.com/linkedin/gobblin&quot;&gt;GitHub&lt;/a&gt; as well as our &lt;a href=&quot;https://groups.google.com/d/forum/gobblin-users&quot;&gt;discussion group&lt;/a&gt; since the very early days. In the past few months, contributors from different companies and continents have committed important &lt;a href=&quot;https://github.com/linkedin/gobblin/pull/46&quot;&gt;bug fixes&lt;/a&gt;. Additionally, the community has contributed important features such as a &lt;a href=&quot;https://github.com/linkedin/gobblin/pull/122&quot;&gt;byte-oriented Kafka extractor&lt;/a&gt; and &lt;a href=&quot;https://github.com/linkedin/gobblin/pull/57&quot;&gt;S3 integration&lt;/a&gt;. The 0.5.0 release has two big features: a) production-grade integration with Kafka as a data source and b) &lt;a href=&quot;https://github.com/linkedin/gobblin/wiki/Gobblin%20Metrics%20Architecture&quot;&gt;support&lt;/a&gt; for operational monitoring and metadata integration. 
&lt;/p&gt;

&lt;h1&gt;Bye Bye Camus, Hello Gobblin&lt;/h1&gt;&lt;br&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/linkedin/camus&quot;&gt;Camus&lt;/a&gt; was built by LinkedIn specifically to get Kafka data into Hadoop. However, over the years it has accumulated a fair bit of technical debt which would have taken us quite a bit of work to unwind and would be duplicative of work that we’re already doing in Gobblin. Most of the issues were related to operability, data integrity and flexibility to take advantage of different execution frameworks.&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;
&lt;img style=&quot;border: 0px none ; width: 500px; height: auto; alt=&quot;Gobblin Kafka operator pipeline&quot; 
src=&quot;http://engineering.linkedin.com/sites/default/files/gobblin-kafka-pipeline.png
&quot;&gt;
&lt;/p&gt;

&lt;p&gt;
In the past few months, we’ve integrated Kafka as a supported data source for Gobblin. The figure above illustrates the Gobblin operator pipeline for Kafka ingestion. Compared to Camus, this gives us better support for robust hourly compaction, simpler configuration and overall uniformity in debugging and analysing ingestion performance and failures across all source types. 
&lt;/p&gt;

&lt;p&gt;
At LinkedIn, Gobblin is currently ingesting about a thousand Kafka topics that stream an aggregate of hundreds of terabytes per day. Over the next quarter, we plan to migrate all Camus flows into Gobblin. The current execution framework that we’re running in production is based on MapReduce but this lays the foundation for us to move to different frameworks in the near future. 
&lt;/p&gt;

&lt;h1&gt;What’s Next: The Path to Continuous Ingestion&lt;/h1&gt;&lt;br&gt;
&lt;p&gt;
One of the biggest challenges with building a single ingestion framework for both batch and streaming is dealing with impedance mismatches between the source, the sink and the execution environment.
&lt;/p&gt;

&lt;p&gt;
As described earlier, currently in production, we run MapReduce based batch ingestion jobs every 10 minutes on Hadoop to pull data from Kafka into HDFS and publish the data every hour. This has served us well because these batches are simple idempotent retriable units of work. However there is an interesting efficiency cost to this. Every time a batch gets set up, it needs to acquire schemas for all of the topics it is going to ingest, work with the resource scheduler to set up mappers, once mapper slots are acquired, start up the JVM-s, pull data down for a few mins, persist checkpoints to disk and then tear down. This cycle repeats every 10 minutes. We observed that during really busy periods in the cluster, we were spending a lot of time in the setup phase compared to how long we were actually ingesting. &lt;/p&gt;

&lt;p&gt;This motivated us to move to a classic streaming-based model where we could ingest continuously. However, there is a different efficiency cost here; you can provision your ingestion job to support the average throughput of the aggregate streams but data lag will suffer during peak times. If you provision for maximum throughput, resource utilization will be sub-optimal during off-peak times. Since we run these jobs in a shared hugely multi-tenant Hadoop cluster, we don’t want to hog resources without good reason. The ideal deployment scenario is where we can deploy Gobblin in continuous ingestion mode with the option to elastically expand or shrink the cluster as incoming data increases and decreases to maintain a configurable data lag.
&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;
&lt;img style=&quot;border: 0px none ; width: 500px; height: auto; alt=&quot;Gobblin continuous ingest architecture&quot; 
src=&quot;http://engineering.linkedin.com/sites/default/files/gobblin-continuous-ingest.png
&quot;&gt;
&lt;/p&gt;

&lt;p&gt;
To implement this, we are leveraging two projects, &lt;a href=&quot;http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html&quot;&gt;Apache YARN&lt;/a&gt; for macro-level container allocation and &lt;a href=&quot;http://helix.apache.org/&quot;&gt;Apache Helix&lt;/a&gt; for micro-level resource assignment, fault-tolerance and re-allocation. We’ve &lt;a href=&quot;http://www.slideshare.net/KanakBiscuitwala/finegrained-scheduling-with-helix-apachecon-na-2014&quot;&gt;previously talked&lt;/a&gt; about how these two projects can be combined to create auto-scaling distributed systems. Helix allows us to bin-pack work-units within the acquired YARN containers and supports elastic scaling on demand by releasing or acquiring new containers from YARN depending on the performance requirements. &lt;a href=&quot;https://github.com/linkedin/gobblin/pull/339&quot;&gt;This work&lt;/a&gt; is currently in flight and we’re planning to roll this out in production next quarter. This will bring further latency reductions in our ingestion from streaming sources, enable resource utilization efficiencies and allow us to integrate with streaming sinks seamlessly. The Helix framework allows us the flexibility to support other container management frameworks like &lt;a href=&quot;http://mesos.apache.org/&quot;&gt;Mesos&lt;/a&gt;, &lt;a href=&quot;http://kubernetes.io/&quot;&gt;Kubernetes&lt;/a&gt;, etc. We will welcome contributions from the Open Source community in this direction. Stay tuned for a future blog post with a more in-depth discussion of the design and implementation of this feature.
&lt;/p&gt;

&lt;h1&gt;Team, Community and Outreach&lt;/h1&gt;&lt;br&gt;
&lt;p&gt;
&lt;center&gt;
&lt;img style=&quot;border: 0px none ; width: 500px; height: auto; alt=&quot;Gobblin team at LinkedIn&quot; 
src=&quot;http://engineering.linkedin.com/sites/default/files/gobblin-team-at-linkedin.jpg
&quot;&gt;&lt;/center&gt;
&lt;i&gt;&lt;center&gt;The Gobblin team from left to right: (sitting) Chavdar Botev, Issac Buenrostro, Ying Dai &lt;br&gt;
(standing) Pradhan Cadabam, Min Tu, Ziyang Liu, Yinan Li, Sahil Takiar, Abhishek Tiwari&lt;/center&gt;&lt;/i&gt;
&lt;/p&gt;

&lt;p&gt;
We would like to acknowledge the impactful contributions of &lt;a href=&quot;https://www.linkedin.com/in/narasimhareddyv&quot;&gt;Narasimha Reddy Veeramreddy&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/pub/ken-goodhope/b/753/b6a&quot;&gt;Ken Goodhope&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/pub/henry-haiying-cai/0/246/792&quot;&gt;Henry Cai&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/pub/lin-qiao/4/48b/222&quot;&gt;Lin Qiao&lt;/a&gt; to the Gobblin project over the years. At LinkedIn, we’ve been fortunate to have stellar partners who have all helped make Gobblin a better product. We would like to give a shout out to our data services and Hadoop operations team, the Espresso and Kafka teams, the Bizo and Lynda teams, and the Content ingestion team. Externally, we’re excited to see the community adoption of Gobblin and are working on making it even easier to use and extend. Special thanks to &lt;a href=&quot;https://www.linkedin.com/in/kapilsurlaker&quot;&gt;Kapil Surlaker&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/in/arnoldgreg&quot;&gt;Greg Arnold&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/alex&quot;&gt;Alex Vauthey&lt;/a&gt; from the management team for their constant encouragement and support.
&lt;/p&gt;

&lt;p&gt;
We’re going to be talking about Gobblin, &lt;a href=&quot;https://engineering.linkedin.com/pinot/open-sourcing-pinot-scaling-wall-real-time-analytics&quot;&gt;Pinot&lt;/a&gt;, &lt;a href=&quot;http://kafka.apache.org&quot;&gt;Kafka&lt;/a&gt;, &lt;a href=&quot;http://samza.apache.org&quot;&gt;Samza&lt;/a&gt; and our latest invention Dali at LinkedIn’s second annual &lt;a href=&quot;https://linkedinnyc2015.splashthat.com&quot;&gt;Big Data Perspectives&lt;/a&gt; event at our NYC R&amp;D office in the Empire State building this week. Hope to see you there!
&lt;/p&gt;

&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/big-data&#039; rel=&#039;tag&#039;&gt;Big Data&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/gobblin&#039; rel=&#039;tag&#039;&gt;Gobblin&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/hadoop&#039; rel=&#039;tag&#039;&gt;Hadoop&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/tags/kafka&#039; rel=&#039;tag&#039;&gt;Kafka&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/etl&#039; rel=&#039;tag&#039;&gt;ETL&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/tags/open-source&#039; rel=&#039;tag&#039;&gt;Open Source&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/distributed-systems&#039; rel=&#039;tag&#039;&gt;Distributed Systems&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-embedded-images field-type-image field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/gobblin-ingest-ecosystem.png&quot; width=&quot;1999&quot; height=&quot;747&quot; alt=&quot;Gobblin ingest ecosystem&quot; title=&quot;Gobblin ingest ecosystem&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/gobblin-continuous-ingest.png&quot; width=&quot;1144&quot; height=&quot;764&quot; alt=&quot;Gobblin continuous ingestion architecture&quot; title=&quot;Gobblin continuous ingestion architecture&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/gobblin-kafka-pipeline.png&quot; width=&quot;1999&quot; height=&quot;1101&quot; alt=&quot;Gobblin Kafka operator pipeline&quot; title=&quot;Gobblin Kafka operator pipeline&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/gobblin-team-at-linkedin.jpg&quot; width=&quot;1929&quot; height=&quot;1649&quot; alt=&quot;Gobblin team at LinkedIn&quot; title=&quot;Gobblin team at LinkedIn&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Shirshanka Das&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;https://www.linkedin.com/in/shirshankadas&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;April 2010&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/Shirshanka_Das_01.jpg&quot; width=&quot;2158&quot; height=&quot;2158&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Sr. Staff Software Engineer&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Mon, 28 Sep 2015 07:00:00 +0000</pubDate>
 <dc:creator>Shirshanka Das</dc:creator>
 <guid isPermaLink="false">397 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/big-data/bridging-batch-and-streaming-data-ingestion-gobblin#comments</comments>
</item>
<item>
 <title>Rewinder: Interactive Analysis of Hadoop&#039;s Computational Resources</title>
 <link>http://engineering.linkedin.com/hadoop/rewinder-interactive-analysis-hadoops-computational-resources</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;


&lt;span style=&quot;font-style: italic;&quot;&gt;Co-authors:&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;table style=&quot;border: medium hidden ; width: 100%;&quot; border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;2&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;vertical-align: top; text-align: center;&quot;&gt;
            &lt;a href=&quot;https://www.linkedin.com/in/tejathotapalli&quot;&gt;&lt;img style=&quot;border: 0px none ; width: auto; height: 100px;&quot; alt=&quot;Teja&quot; src=&quot;https://media.licdn.com/media/p/5/005/034/041/349b069.jpg&quot; /&gt;&lt;/a&gt;
            &lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&lt;a href=&quot;https://www.linkedin.com/in/tejathotapalli&quot;&gt;Teja Thotapalli&lt;/a&gt;&lt;/span&gt;
            &lt;br /&gt;&lt;/td&gt;

         &lt;td style=&quot;vertical-align: top; text-align: center;&quot;&gt;
            &lt;a href=&quot;https://www.linkedin.com/in/itsmebrian&quot;&gt;&lt;img style=&quot;border: 0px none ; width: auto; height: 100px;&quot; alt=&quot;Brian&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/me.png&quot; /&gt;&lt;/a&gt;
            &lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&lt;a href=&quot;https://www.linkedin.com/in/itsmebrian&quot;&gt;Brian Jue&lt;/a&gt;&lt;/span&gt;                 
            &lt;br /&gt;&lt;/td&gt;

         &lt;td style=&quot;vertical-align: top; text-align: center;&quot;&gt;
            &lt;a href=&quot;https://www.linkedin.com/in/tuhtran&quot;&gt;&lt;img style=&quot;border: 0px none ; width: auto; height: 100px;&quot; alt=&quot;Tu&quot; src=&quot;https://media.licdn.com/media/p/5/005/04a/392/33102d0.jpg&quot; /&gt;&lt;/a&gt;
            &lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&lt;a href=&quot;https://www.linkedin.com/in/tuhtran&quot;&gt;Tu Tran&lt;/a&gt;&lt;/span&gt;
            &lt;br /&gt;&lt;/td&gt;

         &lt;td style=&quot;vertical-align: top; text-align: center;&quot;&gt;
            &lt;a href=&quot;https://www.linkedin.com/in/sandhyaramu&quot;&gt;&lt;img style=&quot;border: 0px none ; width: auto; height: 100px;&quot; alt=&quot;Sandhya&quot; src=&quot;https://media.licdn.com/media/p/3/005/02b/076/30d17f9.jpg&quot; /&gt;&lt;/a&gt;               
            &lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&lt;a href=&quot;https://www.linkedin.com/in/sandhyaramu&quot;&gt;Sandhya Ramu&lt;/a&gt;&lt;/span&gt;
            &lt;br /&gt;&lt;/td&gt;
      &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;p&gt;As LinkedIn continues to grow in size and stature, the data volume being generated continues to increase at an exponential rate.  In order to gain insights from the massive amounts of structured and unstructured data at LinkedIn, we leverage the Hadoop framework, which has the power to store and process all kinds of large datasets.  Hadoop&#039;s multi-tenancy architecture allows us to address the challenges of a shared storage/compute environment and maintain resource provisioning and service level guarantees for tenants.&lt;/p&gt;

&lt;p&gt;One of the responsibilities of our Hadoop Application Operations team is to monitor  and maintain the bulk the of the data on grid, including many of the business engagement workflows that consume the datasets.  It&#039;s a precarious balance between  ensuring that the data is generated and propagated across the grid clusters while also adhering to the dataset consumption timings of the user.  Keeping track of each  individual job, their immediate and overall resource utilization, coupled with the potential contention hurdles they may face, can be a daunting task.  This blog post explains why we needed to create a tool that could help us better manage the operational  aspects of our Hadoop application.&lt;/p&gt;

&lt;h1&gt;The Problem: Too Many Flows, Not Enough Insights&lt;/h1&gt;
&lt;br /&gt;&lt;p&gt;As an operational team supporting many flows and jobs running on the Hadoop cluster, we often felt the need for insights into how resources were being allocated.  These insights will help analyze the behavior of the job.  For example, if the cluster is busy for one hour, that can be attributed to a job&#039;s long run time.&lt;/p&gt;

&lt;p&gt;Currently, the &lt;a href=&quot;http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html&quot;&gt; ResourceManager and Job History Server&lt;/a&gt; are the only two venues that provide visibility into resource utilization and they each have limitations.  The ResourceManager can only show the resource utilization of the cluster at present time, not in recent past.  Job History Server provides information about the resource ask by that application but for only MapReduce jobs.  While this information is necessary in understanding how things unfolded, it can be a tedious task to stitch together different job activities and their associated allocation of resources to provide a holistic view of resource utilization.&lt;/p&gt;

&lt;h1&gt;Our Solution: Rewinder&lt;/h1&gt;

&lt;p style=&quot;text-align:center&quot;&gt;
&lt;img style=&quot;border: 0px none ; width: 200px; height: auto; alt=&quot; logo=&quot;&quot; src=&quot;https://engineering.linkedin.com/sites/default/files/image07.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In order to help assuage the operational aspect of the Hadoop applications running on the grid clusters, we developed Rewinder, named for the ability to allow us to go back any minute in time.  As a method to garner insights into the resource utilization, Rewinder sifts through the sea of application data and surfaces the reasons behind how the computation resources are utilized and how they may affect job processing.&lt;/p&gt;

&lt;p&gt;Rewinder collects raw information about how the memory and vCore resources are being utilized in a grid cluster using a rich set of YARN Rest APIs.  This raw information is aggregated to give visibility at varying granularities, namely the entire cluster, queue and user.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;The Rewinder tool is comprised of four components :&lt;/b&gt;&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Extractor : &lt;/strong&gt; A high frequency job that runs every minute and uses the YARN Rest API to get the raw data, which is essentially the resource utilization of each running Application Master. This also does some basic aggregation.&lt;/li&gt;
   &lt;li&gt;&lt;strong&gt;Reporter : &lt;/strong&gt; A nightly job that feeds on the existing raw data and generates reports with the desired the insights.&lt;/li&gt;
   &lt;li&gt;&lt;strong&gt;Housekeeper : &lt;/strong&gt; A nightly job that runs the basic housekeeping activities like purging old data and creating new table partitions.&lt;/li&gt;
   &lt;li&gt;&lt;strong&gt;Trigger : &lt;/strong&gt; The actual driver program that uses Java Quartz Scheduler to maps out all the above components.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;As of now, all the data is stored in a &lt;a href=&quot;http://www.mysql.com/&quot;&gt;MySQL DB&lt;/a&gt;.  Currently for our dev cluster data is 14GB and stores 70 days worth of data.  We are adding on average 600 thousand records (2GB) of data to the database every day.&lt;/p&gt;

&lt;img style=&quot;width: 100%; height: 100%;&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-components.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;One of the challenges we were facing was determining how much memory was being consumed by an application.  Every minute, Rewinder captures the resource allocation for each application and calculates its consumption rate, denoted both in megabytes per minute and in the number of vCores per minute.&lt;/p&gt;

&lt;p&gt;It&#039;s important to note that the API does not expose the actual resource consumption, rather it shows the allocated resources from the entire pool.  Once allocated, they cannot be claimed by anyone else until it flows back to pool, consequently, we collect this information at the lowest grain (Application Master) that can be rolled up to multiple levels to gain insights.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Here are a few examples of Rewinder&#039;s capabilities :&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;You can easily go to any minute in a day, and see what jobs are running and how the
resources are being shared among multiple applications, user and queue.&lt;/li&gt;
&lt;/ul&gt;&lt;img style=&quot;width: 100%; height: 100%;&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-time-traveling.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;For any given time frame, you can see how the resources are shared among users in a queue.  This bubbles up the top resource consuming users.  This also let us do a given user vs. rest of the world comparison.  You can also see how many applications are in waiting state and the top ten resource consumers.&lt;/li&gt;
&lt;/ul&gt;&lt;img style=&quot;width: 100%; height: 100%;&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-analyzer-memory.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Rewinder provides insight into how applications waiting for resources are piling up.&lt;/li&gt;
&lt;/ul&gt;&lt;img style=&quot;width: 100%; height: 100%;&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-analyzer-non-running-apps.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The tool also generates reports on resource utilization per user, answering questions like :
      &lt;ul&gt;&lt;li&gt;What does resource utilization look like over the past 30 days?&lt;/li&gt;
         &lt;li&gt;Where does the user rank in resource utilization?&lt;/li&gt;
         &lt;li&gt;How many applications does that user submit every day?&lt;/li&gt;
         &lt;li&gt;What is the average wait time and run time of applications?&lt;/li&gt;
         &lt;li&gt;What time and which queues does the user submit most of his jobs?&lt;/li&gt;
         &lt;li&gt;What are the top resource-consuming jobs?&lt;p&gt;&lt;/p&gt;&lt;/li&gt;
      &lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img style=&quot;width: 100%; height: 100%;&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-achievements.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;In each queue or grid, we can see what a general resource utilization looks like on the weekday as well as the weekend.  We can also see the top resource consumers and the average wait times for the applications submitted in the queue.&lt;/li&gt;
&lt;/ul&gt;&lt;img style=&quot;width: 100%; height: 100%;&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-resource-utilization-jj.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;width: 100%; height: 100%;&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-resource-utilization-aj.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;What&#039;s Next?&lt;/h1&gt;
&lt;br /&gt;&lt;p&gt;We are always looking for ways to improve Rewinder so that it becomes an increasingly effective tool for our users.  Our next steps include making the tool itself more streamlined with additional features that tie a top level Hadoop flows as defined in &lt;a href=&quot;http://data.linkedin.com/opensource/azkaban&quot;&gt;Azkaban&lt;/a&gt; with the underlying task level information to make it more complete.&lt;/p&gt;


&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/hadoop&#039; rel=&#039;tag&#039;&gt;Hadoop&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/tags/operations&#039; rel=&#039;tag&#039;&gt;operations&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-embedded-images field-type-image field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/image07.png&quot; width=&quot;675&quot; height=&quot;772&quot; alt=&quot;&quot; title=&quot;Time traveling elephant&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-components.png&quot; width=&quot;1358&quot; height=&quot;636&quot; alt=&quot;&quot; title=&quot;Rewinder&amp;#039;s data flow across its components&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-analyzer-memory.png&quot; width=&quot;1776&quot; height=&quot;1594&quot; alt=&quot;&quot; title=&quot;The grid resources and their respective allocations&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-analyzer-non-running-apps.png&quot; width=&quot;1764&quot; height=&quot;880&quot; alt=&quot;&quot; title=&quot;The breakdown of non running applications across a time series&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-achievements.png&quot; width=&quot;1710&quot; height=&quot;1580&quot; alt=&quot;&quot; title=&quot;A comparison of how the user&amp;#039;s usage compares in relation to all other Hadoop users&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-time-traveling.png&quot; width=&quot;1562&quot; height=&quot;1168&quot; alt=&quot;&quot; title=&quot;Rewinder has the ability to playback the resource allocation across any prior time slice&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-resource-utilization-jj.png&quot; width=&quot;1798&quot; height=&quot;1546&quot; alt=&quot;Suzu&quot; title=&quot;Weekday vs weekend resource allocation breakdown&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rewinder-resource-utilization-aj.png&quot; width=&quot;1792&quot; height=&quot;1540&quot; alt=&quot;Moo Moo&quot; title=&quot;Weekday vs weekend resource allocation breakdown&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/me.png&quot; width=&quot;145&quot; height=&quot;168&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Vamshi Hardageri&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;http://www.linkedin.com/in/vamshihardageri&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;March 07, 2012&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/Screen%20Shot%202015-09-21%20at%2011.46.52%20AM.png&quot; width=&quot;356&quot; height=&quot;362&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Sr. Data Operations Engineer&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Wed, 23 Sep 2015 07:00:00 +0000</pubDate>
 <dc:creator>Vamshi Hardageri</dc:creator>
 <guid isPermaLink="false">395 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/hadoop/rewinder-interactive-analysis-hadoops-computational-resources#comments</comments>
</item>
<item>
 <title>Video: Tools Team Revolutionizes Software Development </title>
 <link>http://engineering.linkedin.com/tools/video-tools-team-revolutionizes-software-development</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;&lt;p&gt;
In the last four years, we’ve dramatically revamped the way we release software. One of the leaders of our tools team
&lt;a href=“https://www.linkedin.com/in/jenspillgram” target=“_blank”&gt;Jens Pillgram-Larsen&lt;/a&gt; shares what changed, what the future will hold and how his team evolved along the way.

&lt;p&gt;


&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/mooIgWZLNleCjO&quot; width=&quot;425&quot; height=&quot;355&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; style=&quot;border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen&gt; &lt;/iframe&gt; &lt;div style=&quot;margin-bottom:5px&quot;&gt; &lt;strong&gt; &lt;a href=&quot;//www.slideshare.net/linkedin/linkedin-tools-engineer-looks-to-revolutionize-software-development&quot; title=&quot;LinkedIn Tools Engineer Looks to Revolutionize Software Development&quot; target=&quot;_blank&quot;&gt;LinkedIn Tools Engineer Looks to Revolutionize Software Development&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href=&quot;//www.slideshare.net/linkedin&quot; target=&quot;_blank&quot;&gt;LinkedIn&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;
&lt;/p&gt;
&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/tools&#039; rel=&#039;tag&#039;&gt;tools&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/engineering-culture&#039; rel=&#039;tag&#039;&gt;engineering culture&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Baron Roberts&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;https://www.linkedin.com/pub/baron-roberts/0/159/65b&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;April 2013&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/392c9bb.jpg&quot; width=&quot;90&quot; height=&quot;90&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Staff Software Engineer&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Tue, 22 Sep 2015 07:00:00 +0000</pubDate>
 <dc:creator>Baron Roberts</dc:creator>
 <guid isPermaLink="false">382 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/tools/video-tools-team-revolutionizes-software-development#comments</comments>
</item>
<item>
 <title>The Evolution of A/B Testing Platform at LinkedIn</title>
 <link>http://engineering.linkedin.com/ab-testing/evolution-ab-testing-platform-linkedin</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;&lt;p&gt;     
&lt;em&gt;“Doubt the conventional wisdom unless you can verify it with reason and experiment” - Steve Albini&lt;/em&gt; 
&lt;/p&gt; 
&lt;p&gt;
     At LinkedIn, we experiment with new ideas before trusting our instincts. Experimentation plays an important role in product innovation and business growth. It is an essential ingredient to greater member happiness, stronger business impact and higher talent productivity. 
&lt;/p&gt;
&lt;p&gt;     
XLNT, an internal LinkedIn platform built to help make data-driven A/B testing decisions, has gained its popularity among various teams and products –     everyday, hundreds of experiments are running and being studied on XLNT. Over the past year, XLNT has evolved significantly to a full-fledged platform     covering &lt;a href=&quot;http://engineering.linkedin.com/ab-testing/why-experimentation-so-important-linkedin&quot;&gt;many aspects of A/B testing&lt;/a&gt;. We have developed     many powerful and yet easy-to-use features to help better run A/B tests and analyze results.
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Flexibility: Custom Experimental Unit&lt;/strong&gt; 
&lt;/p&gt;

&lt;p&gt;
Traditionally, we&#039;ve focused A/B testing efforts on our members in order to improve their experience using LinkedIn. We are, however, extremely focused on     growth as well, and try to give guests users the best experience possible so they&#039;ll want to sign up. We do this by letting guests use certain features,     like applying for jobs, without signing up and making sure that once they do sign up, the process is easy and fluid. In addition, we aim to provide     relevant jobs and informative job descriptions to our audience.With this in mind, we have expanded A/B testing practice to custom experimental units and     leveraged XLNT to test products outside our core member platform. With flexible experiment units, we can optimize how we engage guest users, send emails     and present jobs through experimentation on XLNT. Analyzing experiments on guest, emails, jobs, and other custom experiment units has never been easier. 
&lt;/p&gt; 

&lt;p style=&quot;text-align:center&quot;&gt; 
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/flexible_unit_2.jpg&quot; alt=&quot;flexible experiment unit on XLNT&quot; align=&quot;middle&quot; width=&quot;550&quot;&gt; 
&lt;/p&gt;

&lt;p&gt;     
&lt;strong&gt;Transparency: Metrics You Follow and Ramp Alert&lt;/strong&gt; 
&lt;/p&gt; 

&lt;p&gt;     LinkedIn is a fairly large company with various product teams. Every product team is likely to run multiple experiments at one time. As you can imagine, a     member in one product area can never possibly be aware of all the experiments that other teams are running. Product owners of LinkedIn have set up, monitor     and experiment on their essential metrics on XLNT. However, all the products and features on LinkedIn potentially interact and influence each other.     Without a proper channel, locating the source of impact is just as difficult as finding a needle in a haystack. 
&lt;/p&gt; 

&lt;p&gt;     To provide such a channel, XLNT has developed a feature called “Metrics You Follow”. The “Metrics You Follow” page is the place where LinkedIn employees     can subscribe to metrics and get a list of the experiments that are impacting these metrics. The list of experiment are selected and ranked by a     multi-criteria algorithm that takes into account experiment population, effect size and metric intrinsic volatility. “Metrics You Follow” bridges the gap     between metric followers and experiment owners. 
&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt; 
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/mie2.jpg&quot; alt=&quot;MIE on XLNT&quot; align=&quot;middle&quot; width=&quot;550&quot;&gt; 
&lt;/p&gt;


 &lt;p&gt;     
At the end of an A/B experiment, a decision to ramp up or terminate has to be made. Before the decision is made, the experiment owner should review the A/B     test results. However, a bad experiment that negatively impacts a metric could be ramped up and it is up to XLNT to alert the experiment “owner” and the     metric owner and start the communication between them. Ramp alert feature notifies the experiment owner upon ramp-up request. The metric owner will be     notified immediately when an experiment that negatively impacts this metric ramps up in production. With better communication and transparent information,     bad experiments can be caught at the early stages. 
&lt;/p&gt; 

&lt;p style=&quot;text-align:center&quot;&gt; 
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/ra2.jpg&quot; alt=&quot;Ramp Alert on XLNT&quot; align=&quot;middle&quot; width=&quot;200&quot;&gt; 
&lt;/p&gt;


&lt;p&gt;    
 &lt;strong&gt;Data Driven Decision Making: Post Experiment Power&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;     Statistical power measures an experiment’s statistical sensitivity to detect an effect that actually exists. The statistical power of an experiment is     essential for business decision-making. An experiment that is underpowered could have a large negative impact without us knowing it. To help run better A/B     tests and make more data driven decisions, we have developed the post experiment power feature on XLNT. Prior to running an experiment, the minimal     experiment impact (also commonly known as effect size) one wishes to detect are determined and will be used to calculate the statistical power. The post     experiment power feature on XLNT not only surfaces the current power values for the comparison between treatment and control, but also provides     recommendation on how to achieve enough power if the current power is low. These recommendations are based on the metric’s historical data and current     experiment information and can be at experiment level or metric level. The experiment level recommendation tries to achieve enough power for all the     important metrics that the every team should be aware of when running an experiment. The metric level recommendation specifically aims to achieve enough     power for the metric of interest. These recommendations encourage users to make more informed decisions on the experiments. 
&lt;/p&gt; 
&lt;p style=&quot;text-align:center&quot;&gt; 
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/power1.jpg&quot; alt=&quot;Power Feature on XLNT&quot; align=&quot;middle&quot; width=&quot;200&quot;&gt; 
&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt; 
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/power2.jpg&quot; alt=&quot;Power Feature on XLNT&quot; align=&quot;middle&quot; width=&quot;550&quot;&gt; 
&lt;/p&gt;


&lt;p&gt;     &lt;strong&gt;Customized and On-demand Analysis: XLNT on Demand&lt;/strong&gt; &lt;/p&gt; &lt;p&gt;     The large-scale unified data pipeline generates standard A/B test reports for all experiments and satisfies most of the needs for experimentation. One     unified report      does not answer all the questions about one experiment. Users sometimes want to deep dive into an experiment and perform advanced analyses, for example,     cohort analysis. XLNT on demand, a tool we recently built, provides such customized and on-demand analysis for an experiment. It allows for customized date     range, customized metrics, customized dimensions and even customized members for experiment analysis. Users can also run complex cohort analyses on XLNT on     demand. XLNT on demand leverages most of the cool features on XLNT so it eliminates most of the need for ad-hoc A/B testing analysis. 
&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt; 
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/xod.jpg&quot; alt=&quot;XLNT On Demand&quot; align=&quot;middle&quot; width=&quot;550&quot;&gt; 
&lt;/p&gt;


&lt;p&gt;     Hundreds of experiments are running on XLNT each day and the number of metric we support has grown to over one thousand. With a goal of providing     easy-to-use, accurate and comprehensive A/B testing solution at scale, more great features are to come as XLNT evolves.
 &lt;/p&gt; 

&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/ab-testing&#039; rel=&#039;tag&#039;&gt;A/B Testing&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-embedded-images field-type-image field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/power2.jpg&quot; width=&quot;1600&quot; height=&quot;492&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/ra.jpg&quot; width=&quot;596&quot; height=&quot;994&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/xod.jpg&quot; width=&quot;975&quot; height=&quot;370&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/power1.jpg&quot; width=&quot;451&quot; height=&quot;390&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/flexible_unit_2.jpg&quot; width=&quot;1414&quot; height=&quot;692&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/mie2.jpg&quot; width=&quot;1903&quot; height=&quot;995&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/ra2.jpg&quot; width=&quot;926&quot; height=&quot;998&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Weitao Duan&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;https://www.linkedin.com/in/weitaoduan&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;07/2014&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/WeitaoDuan.jpg&quot; width=&quot;300&quot; height=&quot;300&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Senior Data Scientist&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Mon, 21 Sep 2015 07:00:00 +0000</pubDate>
 <dc:creator>Weitao Duan</dc:creator>
 <guid isPermaLink="false">393 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/ab-testing/evolution-ab-testing-platform-linkedin#comments</comments>
</item>
<item>
 <title>T-Rex, Luigi, Pac-Man and More: Check Out the New Global Ops Space</title>
 <link>http://engineering.linkedin.com/culture/t-rex-luigi-pac-man-and-more-check-out-new-global-ops-space</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;&lt;style&gt;
  .centered {text-align: center;}
  .captioned {text-align: center; display: block; font-style: italic; font-size: 11px;}
&lt;/style&gt;

&lt;p&gt;
When I say “Global Operations” are you picturing rows of grey cubicles and occasional heads popping up over the walls? If so, you’ve never seen the Global Ops space at LinkedIn. The team recently moved into a new location that was pretty plain, but now looks like scenes from Jurassic World, Super Mario, and a Las Vegas lounge, thanks to our recent Rock Your Space contest.

&lt;p&gt;
When the team relocated into the three-story building, we announced that each quarter of a floor – twelve groups in all – would get a budget, design lead, and 10 weeks to decorate their space. The designs were intended as long-term additions and we encouraged teams to let their creativity shine. In late July, we invited judges from across LinkedIn to evaluate the spaces for originality, effort, teamwork, and overall presentation. 

&lt;p&gt;
The end-results were pretty fantastic, as you can see in the photos below. The Media Productions Team came in first place, with “XL Media Playground,” an interactive space that showcased some of the team’s projects including digital mapping, drones, video editing, green screens, and of course, a bar serving media themed drinks.

&lt;p class=&quot;centered&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/IMG_4489.JPG&quot; width=&quot;450&quot;/&gt;&lt;br/&gt;
&lt;/p&gt;

&lt;p&gt;
Other themes around the building included the LinkedIn Barcade (our runners up!), Jurassic World, Vegas Club Lounge, and Super Mario Brothers. Check out some of the awesome decor we get to see every day:

&lt;p class=&quot;centered&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/rockyourspace7.jpg&quot; width=&quot;450&quot;/&gt;&lt;br/&gt;
&lt;/p&gt;

&lt;p class=&quot;centered&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/rockyourspace6.JPG&quot; width=&quot;450&quot;/&gt;&lt;br/&gt;
&lt;/p&gt;

&lt;p class=&quot;centered&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/rockyourspace5.JPG&quot; width=&quot;450&quot;/&gt;&lt;br/&gt;
&lt;/p&gt;

&lt;p class=&quot;centered&quot;&gt;
&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/rockyourspace4.jpg&quot; width=&quot;450&quot;/&gt;&lt;br/&gt;
&lt;/p&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/culture&#039; rel=&#039;tag&#039;&gt;culture&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/tags/operations&#039; rel=&#039;tag&#039;&gt;operations&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-embedded-images field-type-image field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/IMG_4489.JPG&quot; width=&quot;1600&quot; height=&quot;1200&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rockyourspace7.jpg&quot; width=&quot;1032&quot; height=&quot;581&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rockyourspace6.JPG&quot; width=&quot;960&quot; height=&quot;720&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rockyourspace5.JPG&quot; width=&quot;1600&quot; height=&quot;1200&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/rockyourspace4.jpg&quot; width=&quot;1328&quot; height=&quot;747&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Christie DeBlasio&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;https://www.linkedin.com/in/cdeblasio&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;June 2014&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/AAEAAQAAAAAAAAMkAAAAJDRmYTZkYTcyLWQwZDUtNDM4Ni05YWZkLWNhN2E2NmRlOGUyMQ.jpg&quot; width=&quot;295&quot; height=&quot;295&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Executive Assistant, Global Operations&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Thu, 17 Sep 2015 18:18:37 +0000</pubDate>
 <dc:creator>Christie DeBlasio</dc:creator>
 <guid isPermaLink="false">394 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/culture/t-rex-luigi-pac-man-and-more-check-out-new-global-ops-space#comments</comments>
</item>
<item>
 <title>Jumping the Gender Gap, A World Without CSS, Antifragile Software Systems, and Other Must Reads</title>
 <link>http://engineering.linkedin.com/publisher-platform/jumping-gender-gap-world-without-css-antifragile-software-systems-and-other-must</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;&lt;style&gt;
  .centered {text-align: center;}
  .captioned {text-align: center; display: block; font-style: italic; font-size: 11px;}
&lt;/style&gt;

&lt;p&gt;&lt;i&gt;LinkedIn’s publishing platform gives professionals a way to share their personal opinions about topical professional news and interests, including our engineers. Here, we regularly round up some of the best pieces written recently by LinkedIn engineers.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/dont-let-being-only-girl-stop-you-thankyourmentor-tiffany-lim&quot; target=&quot;_blank&quot;&gt;&quot;&#039;Don&#039;t Let Being the Only Girl Stop You!&#039; -- #ThankYourMentor&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/tiffanywlim&quot; target=&quot;_blank&quot;&gt;Tiffany Lim&lt;/a&gt;, Software Engineer at LinkedIn&lt;/strong&gt;
&lt;br&gt;Tiffany remembers fifth grade, the first time she realized there was a gender gap and how she overcame her fear of being the only girl in the science club. Her elementary school teacher encouraged her to persevere in a male-dominated industry, advice Tiffany has held onto throughout her engineering career. The best mentors don&#039;t just believe in you, Tiffany writes, they show you how to believe in yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/world-without-css-bradley-cypert&quot; target=&quot;_blank&quot;&gt;”A World Without CSS”&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/bradcypert?trk=pulse-det-athr_prof-art_hdr&quot; target=&quot;_blank&quot;&gt;Bradley Cypert&lt;/a&gt;, UI Engineer at LinkedIn&lt;/strong&gt;
&lt;br&gt;What if CSS was never invented and we had to live in an (internet) world with unstylized websites? Bradley argues that, while browsers and individual programs might have created their own styling, it would be a nightmare of different styles and standards for developers.

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/my-experience-scale-system-pengfei-jason-li&quot; target=&quot;_blank&quot;&gt;&quot;The &#039;Runner&#039;s High&#039; Moment in Programming&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/jasonpengfeili&quot; target=&quot;_blank&quot;&gt;Pengfei (Jason) Li&lt;/a&gt;, Senior Software Engineer at LinkedIn&lt;/strong&gt;
&lt;br&gt;Running is therapeutic for many people. There&#039;s no better feeling than overcoming the struggle of a harder-than-anticipated run and coming out on top. Jason draws a parallel between between running and programming. Projects don&#039;t always go according to plan and sometimes reaching the finish line can seem like an impossible task, but a difficult journey there makes the end result that much sweeter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/xctest-helper-methods-kyle-sherman&quot; target=&quot;_blank&quot;&gt;&quot;XCTest Helper Methods&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/kyledsherman?trk=pulse-det-athr_prof-art_hdr&quot;&gt;Kyle Sherman&lt;/a&gt;, Software Engineer (SlideShare) at LinkedIn&lt;/strong&gt;
&lt;br&gt;Kyle offers advice for anyone writing unit tests in Xcode. If you are writing a helper method that gets called from numerous tests using the XCTest framework, you may have noticed that if something fails and the code is within your helper method, you will just see a failure in the helper method and not any information about which line in which test it failed. Kyle offers up his solution.

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/managing-css-transitions-javascript-through-kevin-greene&quot; target=&quot;_blank&quot;&gt;&quot;Managing CSS Transitions with JavaScript through Functional Composition&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/pub/kevin-greene/71/969/a44?trk=pulse-det-athr_prof-art_hdr&quot;&gt;Kevin Greene&lt;/a&gt;, Web Developer at LinkedIn&lt;/strong&gt;
&lt;br&gt;As websites add more animations and transitions, web developers are required to manage the CSS through JavaScript. Kevin offers up simple, pure coding language to handle this.

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/antifragile-software-systems-jens-pillgram-larsen&quot; target=&quot;_blank&quot;&gt;&quot;Antifragile Software Systems&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/jenspillgram?trk=pulse-det-athr_prof-art_hdr&quot; target=&quot;_blank&quot;&gt;Jens Pillgram-Larsen&lt;/a&gt;, Senior Engineering Manager at LinkedIn&lt;/strong&gt;
&lt;br&gt;It&#039;s impossible to build a perfect software system that never fails. We all know this, intuitively and experientially. Instead of trying to achieve perfection, we should strive to build the perfect process—one that is Antifragile. Jens explains why an Antifragile system is one that becomes better when it is stressed and how it is the system equivalent of adopting a growth mindset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/developer-happiness-david-max&quot; target=&quot;_blank&quot;&gt;&quot;Developer Happiness&quot;&lt;/a&gt;
&lt;br&gt;By &lt;a href=&quot;https://www.linkedin.com/in/davidpmax&quot; target=&quot;_blank&quot;&gt;David Max&lt;/a&gt;, Senior Software Engineer at LinkedIn&lt;/strong&gt;
&lt;br&gt;A person’s perspective on a project or task at work can vary wildly depending on their job title. David takes a look at a recent project where his team moved a task over to a scalable distributed architecture in order to utilize more processing power. The project worked, but resulted in software engineers who were frustrated by the constraints of the new computing framework. David argues that engineers can become better at their jobs by understanding the architecture of the software they work with, which will help them realize why restraints on certain architecture are there and how they can work within them.&lt;/p&gt;
&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/publisher-platform&#039; rel=&#039;tag&#039;&gt;publisher platform&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/content&#039; rel=&#039;tag&#039;&gt;content&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Erran Berger&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;https://www.linkedin.com/in/erranberger&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;2009&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/Erran%20Berger%20headshot_8.jpg&quot; width=&quot;176&quot; height=&quot;177&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Head of Engineering, Content Products&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Fri, 11 Sep 2015 07:00:00 +0000</pubDate>
 <dc:creator>Erran Berger</dc:creator>
 <guid isPermaLink="false">392 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/publisher-platform/jumping-gender-gap-world-without-css-antifragile-software-systems-and-other-must#comments</comments>
</item>
<item>
 <title>The Many Facets of &#039;Faceted Search&#039;</title>
 <link>http://engineering.linkedin.com/faceting/many-facets-faceted-search</link>
 <description>&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot; property=&quot;content:encoded&quot;&gt;
&lt;p&gt;
&lt;a href=&quot;https://en.wikipedia.org/wiki/Faceted_search&quot;&gt;Faceted search&lt;/a&gt; is a vital part of LinkedIn’s search experience. It’s a key feature in the exploratory searches done by job seekers, recruiters and market analysts when trying to find the information they need on LinkedIn. It provides structure to search results, which enables fast navigation and discovery.
&lt;/p&gt;
&lt;p&gt;
When it comes to a great search experience, there are two elements that matter most: correctness and performance. Conventional approaches to faceted search sacrifice either too much correctness or don’t perform fast enough.
&lt;/p&gt;
&lt;p&gt;
This post covers a new approach to faceted search based on inverted index, this is compared to the conventional forward index-based approach. We outline technical challenges and superiority of the new approach when dealing with very large data sets. We also include some practical results from the largest LinkedIn search index to back up our ideas. It is important to note that this post assumes a basic familiarity with the inverted index-based approaches to search.
&lt;/p&gt;

&lt;h1&gt;What is faceted search?&lt;/h1&gt;
&lt;/p&gt;
Faceted search is best explained through an example. In the screenshot below, there are two facets, &#039;Location&#039; and &#039;Current Company&#039;, each with multiple facet values. Some facet values like &#039;LinkedIn&#039;, &#039;Greater New York City Area&#039; and &#039;San Francisco Bay Area&#039; are selected. If the original query was &#039;Software Engineer&#039;, the facet selections mean the actual results include software engineers from the New York City Area or the Bay Area and who work at LinkedIn.
&lt;p/&gt;

&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/search_page.png&quot; /&gt;

&lt;p&gt;
In the above example, the astute reader would have noticed that multiple facet value selections within the same facet are treated as an OR, i.e. the selections for &#039;Location&#039; indicate we want engineers in New York City OR the Bay Area. The counts reflect these semantics: a selection of a facet value within a facet like &#039;Location&#039; will not affect the counts of other locations. If this were not true, the counts of all other locations would become 0 once we select a location like &#039;San Francisco Bay Area&#039;. This is not very useful or intuitive. 
&lt;/p&gt;

&lt;h1&gt;The challenges of faceted search&lt;/h1&gt;
&lt;p&gt;
The LinkedIn search stack, called &lt;a href=&quot;https://engineering.linkedin.com/search/did-you-mean-galene&quot;&gt;Galene&lt;/a&gt;, supports early termination by providing features like static rank along with special retrieval queries (which we will discuss in future posts). Early termination enables us to do typeahead searches using an inverted index, and enables queries with lots of hits to execute fast. For example, in typeahead we index two-letter prefixes, which match millions of documents per shard. There is no cost-effective way to provide millisecond latencies for those queries if we were to retrieve and score all documents. 
&lt;/p&gt;
&lt;p&gt;
On the other hand, early termination doesn&#039;t work well with the standard approach for faceting. The standard way to discover facet values and compute their counts is to use forward index while scoring documents. Facet values are put in priority queues and several facet values with highest counts are selected to ultimately be displayed on the search page left rail. 
&lt;/p&gt;
&lt;p&gt;
If we terminate a search without retrieving all documents, we will have inaccurate counts for low cardinality facet values if we use this forward index based approach. This challenge is compounded if we want to estimate the counts of high cardinality facet values through some sort of sampling. 
&lt;/p&gt;
&lt;p&gt;
In summary, doing facet counting using the forward index means that we cannot do two things at the same time:
&lt;ul&gt;
	&lt;li&gt;Approximate facet counts for large cardinality facet values to improve performance&lt;/li&gt;
	&lt;li&gt;Guarantee exact values for low counts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The last requirement is very important as typically when count is low (something which fits on a couple of search pages) the numbers should be exact while discrepancies in high numbers don&#039;t matter too much, i.e. it doesn&#039;t matter if we have 10200 or 10215 results, but it matters if we have 5 or 6 results.
&lt;/p&gt;

&lt;h1&gt;Our solution&lt;/h1&gt;
&lt;p&gt;
Thus we had to come up with a different algorithm for faceting. We chose to use inverted index posting lists to count facet values. Using the inverted index for facet counting allows us to guarantee exact counts for low cardinality, while at the same time allowing us to estimate the counts for high cardinality values, providing a significant performance boost. Our approach also retains the option for us to early terminate when scoring documents.
&lt;/p&gt;
&lt;p&gt;
First, we split the faceted search problem into two components: discovery and counting. Facet discovery is the process of deciding which values to display for a given facet. For example, the &#039;Current Company&#039; facet requires us to &#039;discover&#039; a list of companies that we are going to display. This list is based on the input query, so the companies shown for the query &#039;Software Engineer&#039; will be different from the companies shown for the query &#039;Mechanical Engineer&#039;.
&lt;/p&gt;
&lt;p&gt;
Our decision was to use forward index to discover facet values during scoring and to use the inverted index to count them. These two steps are sequential as counting can&#039;t start until at least some facet values are discovered.
&lt;/p&gt;

&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/architecture_0.png&quot; /&gt;

&lt;p&gt;
The typical search cluster setup consists of multiple index partitions hosted on search nodes and a broker, which does a fan-out request and gathers results. When faceting is involved, the broker typically does two requests: the first one performs regular scoring and discovers facet values along the way. Once the broker gathers all facets values the search nodes it issues a subsequent request to count the top N values for each facet.
&lt;/p&gt;

&lt;h1&gt;Facet discovery&lt;/h1&gt;
&lt;p&gt;
When using early termination search query is typically augmented to retrieve most relevant documents while skipping non-relevant ones. This way, facet values from non-relevant documents might be skipped during the retrieval stage or they can be discarded during top N selection on broker, which introduces relevance component into the way we select facet values to display.
&lt;/p&gt;
&lt;p&gt;
The problem arises when a facet selection is made. In this case we can not use search query to discover facets as facet selection becomes a part of it while it should not be considered during discovery of a selected facet.
&lt;/p&gt;
&lt;p&gt;
Let&#039;s say we have facet value LinkedIn selected for Current Company facet. Let&#039;s also say that our early termination limit is 100 and we need at least 50 documents to discover facets. Essentially we need to execute the following queries:
&lt;ol&gt;
	&lt;li&gt;(+Engineer +LinkedIn) [100]&lt;/li&gt;
	&lt;li&gt;+Engineer [50]&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
	&lt;li&gt;&#039;+&#039; means that a clause is required. When having two or more clauses it can be thought as boolean AND.&lt;/li&gt;
	&lt;li&gt;[100] and [50] are early termination limits&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Query 1 will be used for scoring as well as for discovery of facets other than Current Company. Query 2 will be used for discovery of Current Company facet.
It&#039;s possible to multiplex these two queries into a single one:
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;(+Engineer ?LinkedIn[100]) [50]&lt;/li&gt;
&lt;/ol&gt;
&lt;/pre&gt;
&lt;ul&gt;
	&lt;li&gt;&#039;?&#039; means that a clause is optional. When having two or more clauses it can be thought as boolean OR. In this case it&#039;s combined with a required clause, so it becomes fully optional, meaning it doesn&#039;t have to match at all.&lt;/li&gt;
	&lt;li&gt;[100] means early termination limit on ?LinkedIn clause.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The query above retrieves same documents as two separate queries but doing it much more efficiently in a single pass. The necessity of multiplexing becomes evident when having two or more facets selected. Fortunately similar logic can be applied in this case as well.
&lt;/p&gt;

&lt;h1&gt;Using the inverted index for facet counting&lt;/h1&gt;
&lt;p&gt;
To use the inverted index for facet counting, we created a special counting query which can be executed like any other query that utilizes the posting lists of the inverted index. For example, the following query will count the engineers in Google, Facebook and LinkedIn by essentially traversing the posting lists for the terms &#039;Engineer&#039;, &#039;Google&#039;, &#039;Facebook&#039;, and &#039;LinkedIn&#039;:
&lt;/p&gt;
&lt;pre&gt;
FACETS Google Facebook LinkedIn QUERY Engineer
&lt;/pre&gt;
&lt;p&gt;
The result of this query will be a set of (facet value, facet count) pairs. QUERY means the original query issued by a user, in this case &#039;Engineer&#039;, and is called the query condition. When counting, each search node essentially executes the following query:
&lt;/p&gt;
&lt;pre&gt;
+Engineer +(?Google ?Facebook ?LinkedIn)
&lt;/pre&gt;
&lt;p&gt;
This query matches only documents which contribute to at least one facet value count. For each matched document, we increment the count of the corresponding facet value. Since we have an &#039;OR&#039; expression, each matched document can increment multiple facet value counts.
&lt;/p&gt;

&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/posting_lists.png&quot; /&gt;

&lt;p&gt;
Consider the example above. It shows an inverted index with 4 terms and 4 documents with docids 1 - 4. The circled docids indicate that the counting query produced a match.
&lt;/p&gt;

&lt;p&gt;
The first document matches query condition and it also matches &#039;Google&#039;. The second document matches only &#039;Google&#039; and will not be counted. The third document matches the query condition and &#039;LinkedIn&#039;. The fourth document matches everything. The counting query will match documents 1, 3, and 4. After counting is finished it will produce the following counts: Google 2, Facebook 1, LinkedIn 2.
&lt;/p&gt;

&lt;p&gt;
When facet values are selected, the facet counting query becomes more complicated. But it still can be constructed and executed in a single pass similar to the above, matching only those documents which contribute to at least one facet value count.
&lt;/p&gt;

&lt;h1&gt;Counting approximation&lt;/h1&gt;
&lt;p&gt;
The approach above is correct, but will result in poor performance for queries which match millions of documents per shard.
&lt;/p&gt;
&lt;p&gt;
It is here where the use of the inverted index pays dividends: since the inverted index posting lists come with skip lists, we can leverage this to sample a subset of the index and produce estimated counts for large cardinalities. 
&lt;/p&gt;
&lt;p&gt;
When using sampling, the counting query can be rewritten to:
&lt;/p&gt;
&lt;pre&gt;
+Engineer 
+(
    ?(+Google +Google_Sampling) 
    ?(+Facebook +Facebook_Sampling) 
    ?(+LinkedIn +LinkedIn_Sampling) 
    ?Engineer_Sampling
)
&lt;/pre&gt;
&lt;p&gt;
There are many ways to implement sampling iterator. We&#039;ve experimented with quite a few different approaches, but the following one is quite performant and provides very good accuracy in the same time.
&lt;/p&gt;
&lt;p&gt;
The idea is to compute facet value count as:
&lt;/p&gt;

&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/formula1.png&quot; /&gt;

&lt;p&gt;
where D(x) is a facet value density function. It&#039;s a continuous function defined on [0,max doc] and takes values in a range [0, 1].
&lt;/p&gt;
&lt;p&gt;
For performance sake we use linear interpolation to approximate D(x), which provides decent enough accuracy. We split document id space into R equal ranges of size S = max doc / R. Sampling iterator then returns up to F first documents from each range. As document id space is contiguous the implementation of the sampling iterator boils down to several arithmetic operations. We then calculate density value D(x) for the beginning of each range r as M(r) / F, where M(r) is amount of documents matched against corresponding facet value iterator in a range r. Finally we integrate density function D(x) to compute facet count:
&lt;/p&gt;

&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/formula2.png&quot; /&gt;

&lt;p&gt;
Since this approach actually retrieves documents from the entire posting list, it works very well regardless of the distribution of documents. This is important because we have observed that our static rank tends to make posting lists dense at the front and sparse at the end, e.g. a posting list with document ids 1, 2, 4, 6, 20, 100, 1000 can be very typical.
&lt;/p&gt;

&lt;h2&gt;Example&lt;/h2&gt;

&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/graph.png&quot; /&gt;

&lt;p&gt;
Let&#039;s say we have document ids in 0-400 range. We split them into R = 4 equal intervals, 100 documents each. We consider 40 first documents from each interval to compute density function D(x).
&lt;/p&gt;
&lt;p&gt;
Let&#039;s say that:
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;first interval matched 10 documents with facet count iterator&lt;/li&gt;
	&lt;li&gt;second - 5 documents&lt;/li&gt;
	&lt;li&gt;third - 2 documents&lt;/li&gt;
	&lt;li&gt;fourth - 1 document&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
We calculate square under function D(x) by evaluating 400/2/40/4*(10 + 5 + 5 + 2 + 2 + 1 + 1 + 0) = 32.5
&lt;/p&gt;
&lt;p&gt;
This way the final approximated count is reported to be 33.
&lt;/p&gt;

&lt;h1&gt;Results&lt;/h1&gt;
&lt;p&gt;
The following study was done based on a query logs from the main member search product on LinkedIn. We applied our approximation algorithm for each query and compared results against the algorithm with approximations turned off. 
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Capacity: total runtime decreased by a factor of 7&lt;/li&gt;
	&lt;li&gt;Latencies: p50 decreased 1.2 times, p90 - 1.4 times, p95 - 2.6 times, p99 - 11.5 times&lt;/li&gt;
&lt;/ul&gt;

&lt;img src=&quot;http://engineering.linkedin.com/sites/default/files/results.png&quot; /&gt;

&lt;p&gt;
This plot above displays percentage of error for the estimated counts. X is the exact count we would get if not using any approximations. Y axis is the percentage error of the approximation. The plot shows that our error is never more than 30% with p95 = 5% and p99 = 17% It&#039;s important to realize that approximations start only upon configured threshold (45 in the plot above) so the error rate for exact count less than 45 is guaranteed to be 0%.
&lt;/p&gt;
	
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;
To summarize, our goal with the new faceting was threefold:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;To retain the the option of early terminating searches when the result set is large.&lt;/li&gt;
	&lt;li&gt;To guarantee exact counts for low cardinality facet values.&lt;/li&gt;
	&lt;li&gt;To improve the performance of counting large facet values by providing estimated&lt;/li&gt; counts.
&lt;/ul&gt;
&lt;p&gt;
We achieved these goals by splitting the faceting operation into two separate phases: discovery and counting. We used the traditional forward index scan approach for discovery, and used an inverted index traversal with sampling for the counting phase. With this approach we were able to achieve the right balance of correctness and performance. 
&lt;/p&gt;
&lt;p&gt;
Results show tremendous gains in capacity and high percentile latencies. The key to this approach is the flexibility it provides to tune different knobs to make different tradeoffs between correctness and performance.
&lt;/p&gt;

&lt;h1&gt;Acknowledgements&lt;/h1&gt;
&lt;p&gt;
Many thanks to search infrastructure engineers, who worked on faceting, especially &lt;a href=&quot;https://www.linkedin.com/in/apurva1618&quot;&gt;Apurva Mehta&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/in/niranjanbalasubramanian&quot;&gt;Niranjan Balasubramanian&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/pub/yingchao-liu/49/bab/111&quot;&gt;Yingchao Liu&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/in/jessechang&quot;&gt;Choongsoon Jesse Chang&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/pub/michael-chernyak/1/54/34b&quot;&gt;Michael Chernyak&lt;/a&gt;.
&lt;/p&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/faceting&#039; rel=&#039;tag&#039;&gt;Faceting&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/taxonomy/term/78&#039; rel=&#039;tag&#039;&gt;Search&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/galene&#039; rel=&#039;tag&#039;&gt;Galene&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/information-retrieval&#039; rel=&#039;tag&#039;&gt;Information Retrieval&lt;/a&gt;&lt;/span&gt;&lt;span class=&#039;tag&#039;&gt;&lt;a href=&#039;/infrastructure&#039; rel=&#039;tag&#039;&gt;infrastructure&lt;/a&gt;&lt;/span&gt;&lt;div class=&quot;field field-name-field-embedded-images field-type-image field-label-hidden&quot;&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/search_page.png&quot; width=&quot;580&quot; height=&quot;421&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/architecture_0.png&quot; width=&quot;400&quot; height=&quot;243&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/posting_lists.png&quot; width=&quot;400&quot; height=&quot;433&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/formula1.png&quot; width=&quot;98&quot; height=&quot;52&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/formula2.png&quot; width=&quot;580&quot; height=&quot;52&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item odd&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/results.png&quot; width=&quot;580&quot; height=&quot;408&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/graph.png&quot; width=&quot;400&quot; height=&quot;251&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-author field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Dmytro Ivchenko&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-profile-url field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author&amp;#039;s LinkedIn Profile URL:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;https://www.linkedin.com/in/dmytroivchenko&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-linkedin-since field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;LinkedIn Since:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;05/2012&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-avatar field-type-image field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Avatar:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;img typeof=&quot;foaf:Image&quot; src=&quot;http://engineering.linkedin.com/sites/default/files/avatar.jpg&quot; width=&quot;400&quot; height=&quot;400&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-title field-type-text field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Author Title:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;Sr Staff Engineer&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-content-for field-type-taxonomy-term-reference field-label-above&quot;&gt;
      &lt;div class=&quot;field-label&quot;&gt;Content For:&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;field-items&quot;&gt;
          &lt;div class=&quot;field-item even&quot;&gt;&lt;a href=&quot;/blog&quot; typeof=&quot;skos:Concept&quot; property=&quot;rdfs:label skos:prefLabel&quot; datatype=&quot;&quot;&gt;Blog&lt;/a&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;/div&gt;
</description>
 <pubDate>Thu, 10 Sep 2015 07:00:00 +0000</pubDate>
 <dc:creator>Dmytro Ivchenko</dc:creator>
 <guid isPermaLink="false">390 at http://engineering.linkedin.com</guid>
 <comments>http://engineering.linkedin.com/faceting/many-facets-faceted-search#comments</comments>
</item>
</channel>
</rss>
