<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://www.niceideas.ch/roller2/roller-ui/styles/rss.xsl" media="screen"?><rss version="2.0" 
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:atom="http://www.w3.org/2005/Atom" >
<channel>
  <title>niceideas.ch</title>
  <link>https://www.niceideas.ch/roller2/badtrash/</link>
      <atom:link rel="self" type="application/rss+xml" href="https://www.niceideas.ch/roller2/badtrash/feed/entries/rss?cat=Big+Data" />
    <description>Technological Thoughts by Jerome Kehrli</description>
  <language>en-us</language>
  <copyright>Copyright 2025</copyright>
  <lastBuildDate>Tue, 23 Dec 2025 06:13:50 -0500</lastBuildDate>
  <generator>Apache Roller 5.1.2</generator>
        <item>
    <guid isPermaLink="true">https://www.niceideas.ch/roller2/badtrash/entry/modern-information-system-architectures</guid>
    <title>Modern Information System Architectures</title>
    <dc:creator>Jerome Kehrli</dc:creator>
    <link>https://www.niceideas.ch/roller2/badtrash/entry/modern-information-system-architectures</link>
        <pubDate>Mon, 13 Dec 2021 06:04:45 -0500</pubDate>
    <category>Big Data</category>
    <category>architecture</category>
    <category>big-data</category>
    <category>hadoop</category>
    <category>kubernetes</category>
    <category>microservices</category>
    <category>newsql</category>
    <category>nosql</category>
    <atom:summary type="html">&lt;p&gt;
For forty years we have been building &lt;i&gt;Information Systems&lt;/i&gt; in corporations in the same way, with the same architecture, with very little innovations and changes in paradigms:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On one side the &lt;b&gt;Operational Information System&lt;/b&gt; which sustains day-to-day operations and business activities. On the Operational Information Systems, the &lt;i&gt;3-tiers&lt;/i&gt; architecture and the relational database model (RDBMS - Relational Database Management System / SQL) have ruled for nearly 40 years.
&lt;/li&gt;
&lt;li&gt;On the other side the &lt;b&gt;Decision Support Information System&lt;/b&gt; - or &lt;i&gt;Business Intelligence&lt;/i&gt; or &lt;b&gt;Analytical Information System&lt;/b&gt; - where the &lt;i&gt;Data Warehouse&lt;/i&gt; architecture pattern has ruled for 30 years.
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1d146989-ed7b-4480-bd8c-651f4085375b&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px;&quot; alt=&quot;legacy Information System Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1d146989-ed7b-4480-bd8c-651f4085375b&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;legacy / Information Systems Architecture for 40 years&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Of course the technologies involved in building these systems have evolved in all these decades, in the 80s COBOL on IBM hosts used to rule the Information Systems world whereas Java emerged quickly as a standard in the 2000s, etc.
&lt;br&gt;
But while the technologies used in building these information systems evolved fast, their architecture in the other hand, the way we design and build them, didn&apos;t change at all. The relational model ruled for 40 years along the 3-tiers model in the Operational world and in the analytical world, the Data Warehouse pattern was the only way to go for decades.
&lt;/p&gt;

&lt;p&gt;
The relational model is interesting and has been helpful for many decades. its fundamental objective is to optimize storage space by ensuring an entity is stored only once (3rd normal form / normalization). It comes from a time when storage was very expensive. 
&lt;br&gt;
But then, by imposing normalization and ACID transactions, it prevents horizontal scalability by design. An Oracle database for instance is designed to run on a single machine, it simply can&apos;t implement relational references and ACID transactions on a cluster of nodes.
&lt;br&gt;
Today storage is everything but expensive but Information Systems still have to deal with RDBMS limitations mostly because ... that&apos;s the only way we used to know.
&lt;/p&gt;

&lt;p&gt;
On the Decision Support Information System (BI / Analytical System), the situation is even worst. in Data warehouses, data is &lt;i&gt;pushed&lt;/i&gt; along the way and transformed, one step at a time, first in a staging database, then in the Data Warehouse Database and finally in Data Marts, highly specialized towards specific use cases. 
&lt;br&gt;
For a long time we didn&apos;t have much of a choice since implementing such analytics in a &lt;i&gt;pull&lt;/i&gt; way (data lake pattern) was impossible, we simply didn&apos;t have the proper technology. The only way to support high volumes of data was to &lt;i&gt;push&lt;/i&gt; daily increments through these complex transformation steps every night, when the workload on the system is lower.
&lt;br&gt;
The problem with this &lt;i&gt;push&lt;/i&gt; approach is that it&apos;s utmost inflexible. One can&apos;t change his mind along the way and quickly come up with a new type of data. Working with daily increments would require waiting 6 months to have a 6 months history. Not to mention that the whole process is amazingly costly to develop, maintain and operate.
&lt;/p&gt;

&lt;p&gt;
So for a long time, RDBMSes and Data Warehouses were all we had.
&lt;/p&gt;

&lt;p&gt;
It took the Internet revolution and the web giants facing limits of these traditional architectures for finally something different to be considered. The &lt;b&gt;Big Data revolution&lt;/b&gt; has been the cornerstone of all the evolutions in Information System architecture we have been witnessing over the last 15 years.
&lt;/p&gt;

&lt;p&gt;
The latest evolution in this software architecture evolution (or revolution) would be micro-services, where finally all the benefits that were originally really fit to the analytical information system evolution finally end up overflowing to the operational information system. 
&lt;br&gt;
Where Big Data was originally a lot about scaling the computing along with the data topology - bringing the code to where the data is (data tier revolution) - we&apos;re today scaling everything, from individual components requiring heavy processing to message queues, etc.
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/f74719c9-f6f5-4f48-9bf2-ae584c02525f&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px;&quot; alt=&quot;Microservices Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/f74719c9-f6f5-4f48-9bf2-ae584c02525f&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Example of modern IS architecture: Microservices&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
In this article, I would want to present and discuss how Information System architectures evolved from the universal 3 tiers (operational) / Data Warehouse (analytical) approach to the Micro-services architecture, covering Hadoop, NoSQL, Data Lakes, Lambda architecture, etc. and introducing all the fundamental concepts along the way.
&lt;/p&gt;

</atom:summary>        <description>&lt;p&gt;
For forty years we have been building &lt;i&gt;Information Systems&lt;/i&gt; in corporations in the same way, with the same architecture, with very little innovations and changes in paradigms:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On one side the &lt;b&gt;Operational Information System&lt;/b&gt; which sustains day-to-day operations and business activities. On the Operational Information Systems, the &lt;i&gt;3-tiers&lt;/i&gt; architecture and the relational database model (RDBMS - Relational Database Management System / SQL) have ruled for nearly 40 years.
&lt;/li&gt;
&lt;li&gt;On the other side the &lt;b&gt;Decision Support Information System&lt;/b&gt; - or &lt;i&gt;Business Intelligence&lt;/i&gt; or &lt;b&gt;Analytical Information System&lt;/b&gt; - where the &lt;i&gt;Data Warehouse&lt;/i&gt; architecture pattern has ruled for 30 years.
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1d146989-ed7b-4480-bd8c-651f4085375b&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px;&quot; alt=&quot;legacy Information System Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1d146989-ed7b-4480-bd8c-651f4085375b&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;legacy / Information Systems Architecture for 40 years&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Of course the technologies involved in building these systems have evolved in all these decades, in the 80s COBOL on IBM hosts used to rule the Information Systems world whereas Java emerged quickly as a standard in the 2000s, etc.
&lt;br&gt;
But while the technologies used in building these information systems evolved fast, their architecture in the other hand, the way we design and build them, didn&apos;t change at all. The relational model ruled for 40 years along the 3-tiers model in the Operational world and in the analytical world, the Data Warehouse pattern was the only way to go for decades.
&lt;/p&gt;

&lt;p&gt;
The relational model is interesting and has been helpful for many decades. its fundamental objective is to optimize storage space by ensuring an entity is stored only once (3rd normal form / normalization). It comes from a time when storage was very expensive. 
&lt;br&gt;
But then, by imposing normalization and ACID transactions, it prevents horizontal scalability by design. An Oracle database for instance is designed to run on a single machine, it simply can&apos;t implement relational references and ACID transactions on a cluster of nodes.
&lt;br&gt;
Today storage is everything but expensive but Information Systems still have to deal with RDBMS limitations mostly because ... that&apos;s the only way we used to know.
&lt;/p&gt;

&lt;p&gt;
On the Decision Support Information System (BI / Analytical System), the situation is even worst. in Data warehouses, data is &lt;i&gt;pushed&lt;/i&gt; along the way and transformed, one step at a time, first in a staging database, then in the Data Warehouse Database and finally in Data Marts, highly specialized towards specific use cases. 
&lt;br&gt;
For a long time we didn&apos;t have much of a choice since implementing such analytics in a &lt;i&gt;pull&lt;/i&gt; way (data lake pattern) was impossible, we simply didn&apos;t have the proper technology. The only way to support high volumes of data was to &lt;i&gt;push&lt;/i&gt; daily increments through these complex transformation steps every night, when the workload on the system is lower.
&lt;br&gt;
The problem with this &lt;i&gt;push&lt;/i&gt; approach is that it&apos;s utmost inflexible. One can&apos;t change his mind along the way and quickly come up with a new type of data. Working with daily increments would require waiting 6 months to have a 6 months history. Not to mention that the whole process is amazingly costly to develop, maintain and operate.
&lt;/p&gt;

&lt;p&gt;
So for a long time, RDBMSes and Data Warehouses were all we had.
&lt;/p&gt;

&lt;p&gt;
It took the Internet revolution and the web giants facing limits of these traditional architectures for finally something different to be considered. The &lt;b&gt;Big Data revolution&lt;/b&gt; has been the cornerstone of all the evolutions in Information System architecture we have been witnessing over the last 15 years.
&lt;/p&gt;

&lt;p&gt;
The latest evolution in this software architecture evolution (or revolution) would be micro-services, where finally all the benefits that were originally really fit to the analytical information system evolution finally end up overflowing to the operational information system. 
&lt;br&gt;
Where Big Data was originally a lot about scaling the computing along with the data topology - bringing the code to where the data is (data tier revolution) - we&apos;re today scaling everything, from individual components requiring heavy processing to message queues, etc.
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/f74719c9-f6f5-4f48-9bf2-ae584c02525f&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px;&quot; alt=&quot;Microservices Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/f74719c9-f6f5-4f48-9bf2-ae584c02525f&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Example of modern IS architecture: Microservices&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
In this article, I would want to present and discuss how Information System architectures evolved from the universal 3 tiers (operational) / Data Warehouse (analytical) approach to the Micro-services architecture, covering Hadoop, NoSQL, Data Lakes, Lambda architecture, etc. and introducing all the fundamental concepts along the way.
&lt;/p&gt;



&lt;p&gt;
&lt;b&gt;Summary&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;a href=&quot;#sec1&quot;&gt;1. Introduction&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec2&quot;&gt;2. The Web giants and Big Data&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec21&quot;&gt;2.1 The Era of Power&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec22&quot;&gt;2.2 The Web Giants&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec23&quot;&gt;2.3 Data Deluge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec24&quot;&gt;2.4 The Moore Law&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec25&quot;&gt;2.5 The Death of the Moore Law&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec26&quot;&gt;2.6 Fundamentals of Big Data - the Web giants new paradigms&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec3&quot;&gt;3. The CAP Theorem&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec31&quot;&gt;3.1 The origins of NoSQL&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec311&quot;&gt;3.1.1 Flat files as data store&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec312&quot;&gt;3.1.2 RDBMS and the relational model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec313&quot;&gt;3.1.3 criticism of the relational model&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec32&quot;&gt;3.2 Horizontal scalability&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec321&quot;&gt;3.2.1 Scaling up&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec322&quot;&gt;3.2.2 Scaling out&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec33&quot;&gt;3.3 Data Distribution&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec34&quot;&gt;3.4 Properties of a distributed system&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec341&quot;&gt;3.4.1 Eventual consistency&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec4&quot;&gt;4. NoSQL / NewSQL&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec41&quot;&gt;4.1 NoSQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec42&quot;&gt;4.2 NewSQL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec5&quot;&gt;5. Hadoop and Data Lakes&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec51&quot;&gt;5.1 What is Hadoop ?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec52&quot;&gt;5.2 Hadoop Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec53&quot;&gt;5.3 Hadoop Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec54&quot;&gt;5.4 The DataLake Architecture pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec6&quot;&gt;6. Streaming Architectures&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec61&quot;&gt;6.1 Complex Event Processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec62&quot;&gt;6.2 Lambda Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec63&quot;&gt;6.3 Kappa Architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec7&quot;&gt;7. Big Data 2.0&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec71&quot;&gt;7.1 Alternatives to Hadoop &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec72&quot;&gt;7.2 Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec8&quot;&gt;8. Micro-services&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec81&quot;&gt;8.1. Micro-services discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec9&quot;&gt;9. Conclusion&lt;/a&gt;&lt;/li&gt;


&lt;/ul&gt;


&lt;a name=&quot;sec1&quot;&gt;&lt;/a&gt;
&lt;h2&gt;1. Introduction &lt;/h2&gt;

&lt;p&gt;
As stated in the summary above, the way we build information systems really didn&apos;t evolve in so many decades. The technologies used underneath have evolved of course, a long way from COBOL to Java and Angular, but the architectures in use - the &lt;i&gt;3-tiers model&lt;/i&gt; on the operational information system and the &lt;i&gt;data warehouse pattern&lt;/i&gt; on the decision support system (a.k.a analytics system) - haven&apos;t evolve in more than 30 years.
&lt;br&gt;
The &lt;i&gt;Software Architecture&lt;/i&gt; is defined as the set of &lt;b&gt;principal design decision&lt;/b&gt; about the system. Software architecture is kind of the blueprint for the system&apos;s construction and evolution. Design decisions encompass the following aspects of the system under development: Structure, Behaviour, Interactions, Non-functional properties. (Taylor 2010)
&lt;br&gt;
And then again, the technologies under the hood, from the operating systems to the User Interfaces through the programming languages, have evolved drastically. We all remember 3270 green-on-black terminal screens and can only consider the terrific evolution to the fancy HTML5/bootstrap screens we see today.
&lt;br&gt;
But the design of the Information system components, their interactions and the technical processes in between didn&apos;t evolve at all!
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1d146989-ed7b-4480-bd8c-651f4085375b&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px;&quot; alt=&quot;legacy Information System Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1d146989-ed7b-4480-bd8c-651f4085375b&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Information Systems Architecture for 40 years&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
I find it amazing to consider that if you put COBOL, 3270 and a few terms like that on this schema instead of the web elements you literally get what would have been the high-level architecture schema 40 years ago.
&lt;br&gt;
As stated above, RDBMS - Relational Database Management Systems - have a lot of limits and some benefits, namely the standardized querying language - SQL - and the optimization of storage space. But in today&apos;s digital world, the benefits don&apos;t stand up to the drawbacks, mostly the impossibility to scale.
&lt;br&gt;
The Data Warehouse pattern in use for 30 years on the analytical Information System is also a poor fit for today&apos;s pace of development of digital services. It is much too inflexible not to mention the cost in developing and maintaining it.
&lt;/p&gt;

&lt;p&gt;
It took the web giants to face the limits of these current architecture paradigms and invent new ways of building information systems to finally see some evolutions in the way we are building them in corporations. The first evolutions came to the analytics system side with Big Data technologies and overflowed later to the operationnal IS side with NoSQL, streaming architectures and eventually micro-services.
&lt;/p&gt;

&lt;p&gt;
In this article I want to present these evolutions from an historical perspective. We&apos;ll start with the Web giants and the Big Data revolution, cover NoSQL and Hadoop, run through Lambda and Kappa architectures, and end up discussing Kubernetes and Micro-services.
&lt;/p&gt;


&lt;a name=&quot;sec2&quot;&gt;&lt;/a&gt;
&lt;h2&gt;2. The Web giants and Big Data&lt;/h2&gt;

&lt;p&gt;
The web giants have been the first to face the limits of traditional architectures in an unacceptable way. Can you imagine google running their Search Engine on an IBM mainframe ? Can you imagine what that would be for a machine and how much money (licensing fees) they would need to leave to IBM every year for running such a host ? 
&lt;br&gt;
Can you imagine Amazon running their online retail business on an Oracle database with hundreds of millions of users connected and querying the DB at any time ? Can you imagine the price of a computer that would be able to support such volumes of data and concurrent requests ?
&lt;/p&gt;

&lt;p&gt;
The Web giants had to invent both &lt;i&gt;new data storage technologies&lt;/i&gt; and &lt;i&gt;programming paradigms&lt;/i&gt; to run their business and support their volume of activities.
&lt;br&gt;
But let&apos;s start with the beginning.
&lt;/p&gt;


&lt;a name=&quot;sec21&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.1 The Era of Power&lt;/h3&gt;

&lt;p&gt;
As an prequel to introducing Big Data, let&apos;s have a look at these both situations:
&lt;/p&gt;
&lt;br&gt;


&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/3acf2fe9-36ae-4b3b-a26c-81ba64780676&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px;&quot; alt=&quot;The Era of Power&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/3acf2fe9-36ae-4b3b-a26c-81ba64780676&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;The Era of Power&lt;/i&gt;
&lt;br&gt;
Source: &lt;a href=&quot;https://pages.experts-exchange.com/processing-power-compared &quot;&gt;https://pages.experts-exchange.com/processing-power-compared &lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
These two computers are separated by only 30 years of technological evolutions. 
&lt;br&gt;
The computer on the left is a Cray II. When it came out in 1985, it was a revolution since it was the fastest machine in the world, the first multi-processor computer from Seymour Cray and included many unique technological evolutions.
&lt;br&gt;
The computer on the right is a Samsung S6 Smartphone. It&apos;s 30 years younger that the Cray 2.
&lt;/p&gt;

&lt;p&gt;
It&apos;s 30 years younger only and around 15 times more powerful that the Cray 2. While the later was by far bigger than a human being, the Samsung S6 fits in the palm. The Cray 2 has 4 processors while the S6 packages 8 processors.
&lt;br&gt;
Considering how the hardware technology progressed over one generation is mind-blowing.
&lt;/p&gt;

&lt;p&gt;
Another comparison is even more impressive, 50 years before the Samsung S6, a computer has been used to send people to the moon. The S6 is a million times more powerful in terms of raw computing power than that very computer.
&lt;br&gt;
We have today a device so small that it fits in our palm, incredibly powerful, which enables us to be &lt;i&gt;interconnected everywhere, all the time and for every possible need&lt;/i&gt;. This is the definition of the &lt;i&gt;digitization&lt;/i&gt;
&lt;br&gt;
The smartphones are really an amazing piece of technology, but much more impressive are the apps behind and the services they enable us to use. This leads us to the Web Giants.
&lt;/p&gt;


&lt;a name=&quot;sec22&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.2 The Web Giants&lt;/h3&gt;

&lt;p&gt;
The Web giants have been the first to face the limits of traditional architectures and the usual way information systems were built.
&lt;/p&gt;
&lt;br&gt;


&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/ea67caee-b68f-48cc-9db3-8ca352e2f9cd&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 700px;&quot; alt=&quot;The Web Giants&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/ea67caee-b68f-48cc-9db3-8ca352e2f9cd&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;The Web Giants&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
And the revolution came from them. They had to find new technical solutions to business-critical challenges such as :
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Google: &lt;/b&gt; Index the whole web, and keep a response time to any request below one second - or how to keep the search free for the user ?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Facebook: &lt;/b&gt; Interconnect billions of users, display their feeds in near-real-time and understand how they use their product to optimize ads ?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Amazon: &lt;/b&gt; How to build a product recommendation engine for dozens of millions of customers, on millions of products ?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;EBAY : &lt;/b&gt; How to do a search in ebay auctions, even with misspelling ?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
These are just oversimple examples of course and the challenges faced by the web giants go much beyond such simple cases.
&lt;br&gt;
These business challenges are backed by technical challenges such as:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to invert a square matrix that doesn&apos;t fit in memory in a reasonable time ?&lt;/li&gt;
&lt;li&gt;How to query a database containing trillions of documents in real-time ?&lt;/li&gt;
&lt;li&gt;How to read billions of files of multiple megabytes in a reasonable time ?&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
At the end of the day, it all boiled down to finding ways to manage volumes of data bigger by several orders of magnitude than the volumes of data that IT systems were used to manipulate so far.
&lt;/p&gt;


&lt;a name=&quot;sec23&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.3 Data Deluge&lt;/h3&gt;

&lt;p&gt;
So the most striking problem they had to solve is getting prepared and ready for the &lt;b&gt;Data Deluge!&lt;/b&gt;
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/5666cd1f-0852-4db7-8d56-910d659d8820&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 700px;&quot; alt=&quot;The Data Deluge&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/5666cd1f-0852-4db7-8d56-910d659d8820&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Data Deluge!&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Not only do we generate more and more data, but we have today the means and the technology to analyze, exploit and mine it and extract meaningful business insights.
&lt;br&gt;
The data generated by the company’s own systems can be a very interesting source of information regarding customer behaviours, profiles, trends, desires, etc. But also external data, Facebook, twitter logs, etc.
&lt;/p&gt;


&lt;a name=&quot;sec24&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.4 The Moore Law&lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;The Moore Law:&lt;/b&gt;&lt;i&gt;The number of transistors and resistors on a chip doubles every 24 months&quot;&lt;/i&gt; (Gordon Moore, 1965)
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/e5e9bb30-1ca4-47f6-bd06-f3403dd38fd2&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;The Moore Law&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/e5e9bb30-1ca4-47f6-bd06-f3403dd38fd2&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;The Moore Law &lt;b&gt;Click to enlarge&lt;/b&gt;-&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
For a long time, the increasing volume of data to be handled by any given corporation in its Information System was not an issue at all.
&lt;br&gt;
The volume of data increases, the number of user increases, etc. but the processing abilities increases as well, sometimes even more.
&lt;br&gt;
The Moore law was there to cover our ass. The corporation CTO just had to buy a new machine to host the Information System every few years.
&lt;/p&gt;
&lt;br&gt;


&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/c568d819-5337-424c-8d3f-f202abe75079&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 650px;&quot; alt=&quot;IT computing abilities exponential growth&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/c568d819-5337-424c-8d3f-f202abe75079&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;For the 40 years, the IT component capabilties grew exponentially&lt;/i&gt;
&lt;br&gt;
Source: &lt;a href=&quot;http://radar.oreilly.com/2011/08/building-data-startups.html&quot;&gt;http://radar.oreilly.com/2011/08/building-data-startups.html&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
This model has hold for a very long time. The cost are going down, the computing capacities are rising, one simply needs to buy a new machine to absorb the load increase.
&lt;br&gt;
This is especially true in the mainframe world. There wasn’t even any need to make the architecture of the systems (COBOL, etc.) evolve for 30 years.
&lt;br&gt;
Even outside the mainframe world. The architecture patterns and styles we are using in the operational IS world haven’t really evolve for the last 30 years. Despite new technologies such as Web, Web 2.0, Java, etc. of course. I’m just speaking about architecture plans and styles.
&lt;/p&gt;


&lt;a name=&quot;sec25&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.5 The Death of the Moore Law&lt;/h3&gt;

&lt;p&gt;
But everything has an end.
&lt;br&gt;
Let&apos;s consider a fifth dimension, too often left aside when considering the evolutions of computer technologies and hardware architectures: the throughput of the connection between the data on the disk (long term storage) and the memory (i.e. hard drive controllers mostly, but also buses, etc.)
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/d37e83aa-67e1-4a8d-a0a0-d737c2964e4a&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;The death of the moore law&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/d37e83aa-67e1-4a8d-a0a0-d737c2964e4a&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;The death of the Moore Law&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Issue: the throughput evolution is always lower than the capacity evolution.
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;b&gt;How read/write more and more data through an always thicker pipe?&lt;/b&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
The throughput has become the biggest concern in &lt;b&gt;scaling&lt;/b&gt; computer / platform hardware &lt;b&gt;up&lt;/b&gt;. It did not progress in terms of efficiency in a way comparable to the four other dimensions.
&lt;br&gt;
We are able to store &lt;b&gt;more and more data&lt;/b&gt;, of course, but we are &lt;b&gt;less and less able to manipulate this data&lt;/b&gt; efficiently.
&lt;br&gt;
In practice, fetching all the disk data on a computation machine to fit it in RAM to process it is becoming more and more difficult.
&lt;/p&gt;



&lt;a name=&quot;sec26&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.6 Fundamentals of Big Data - the Web giants new paradigms&lt;/h3&gt;

&lt;p&gt;
In order to workaround the limits of traditional architectures, the web giants invented new architecture paradigms and new ways of building information systems by leveraging on three fundamental ideas:
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/3fbee390-21ba-4be0-816b-5d01d8bae46f&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 750px;&quot; alt=&quot;Fundamentals of Big Data&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/3fbee390-21ba-4be0-816b-5d01d8bae46f&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Fundamentals of Big Data - the Web giants new paradigms&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
In details:
&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;
&lt;b&gt;Key idea 1 : distribution&lt;/b&gt; - Since its impossible to fit the data in the RAM of one single machine, split it and distribute it on as many different machines as are required. 
&lt;br&gt;
Distribution means &lt;i&gt;partitioning&lt;/i&gt; the dataset - also called &lt;i&gt;sharding&lt;/i&gt; it sometimes - but also always &lt;i&gt;replicate&lt;/i&gt; the partitions or shards. We&apos;ll see exactly why and how later.
&lt;/li&gt;

&lt;li&gt;
&lt;b&gt;Key idea 2 : Horizontal scalability&lt;/b&gt; - Just as we split the data, let&apos;s split the computation and distribute it on as many nodes as are required to support the workload, even if it means multiple datacenters.
&lt;/li&gt;

&lt;li&gt;
&lt;b&gt;Key idea 3 : Data tier revolution&lt;/b&gt; - So we distribute both the data on a cluster of computers - or nodes - and the processing as well. We end up using the data nodes as processing nodes. This is the data tier revolution, which is in complete opposition to what was usually done so far in traditional architectures: fetching the required data to the place where the computation occurs.
&lt;br&gt;
But it goes further than that.
&lt;br&gt;
Most of the time we end up distributing different types or categories of data. Every time a specific business process needs to compute something out of a specific piece of all this data, it&apos;s crucial to ensure the processing will happen on the very nodes where this specific piece of data is located. This is called &lt;b&gt;co-local processing&lt;/b&gt; or &lt;i&gt;data locality optimization&lt;/i&gt;.
&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;
As a summary, the web giants have designed new architectures and programming paradigms where distributing the data and the processing (ideally in a co-local way) on a cluster of nodes was the most fundamental principle.
&lt;/p&gt;


&lt;a name=&quot;sec3&quot;&gt;&lt;/a&gt;
&lt;h2&gt;3. The CAP Theorem&lt;/h2&gt;

&lt;p&gt;
But moving from a mainframe world - where everything is on the same computer and the data to compute always fits in the memory of that computer - to a distributed system world most definitely has benefits, but it also has some consequences. And that&apos;s the topic of this chapter.
&lt;/p&gt;


&lt;a name=&quot;sec31&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.1 The origins of NoSQL&lt;/h3&gt;

&lt;p&gt;
Let&apos;s start with a bit of history.
&lt;/p&gt;

&lt;a name=&quot;sec311&quot;&gt;&lt;/a&gt;
&lt;h4&gt;3.1.1 Flat files as data store&lt;/h4&gt;

&lt;p&gt;
In the early days of digital data, before 1960, the data within a Computer Information System was mostly stored in rather flat files (sometimes indexed) manipulated by top-level software systems.
&lt;br&gt;
The primitives provided by the operating system were really very low level, basically just the possibility to read or write file or file increments.
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a8eb454f-c28a-4cb9-a21b-c148ab9b1fac&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 350px;&quot; alt=&quot;An indexed flat file example&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a8eb454f-c28a-4cb9-a21b-c148ab9b1fac&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Indexed flat file&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Directly using flat files was cumbersome and painful. Different uncovered needs emerged at the time:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data isolation&lt;/li&gt;
&lt;li&gt;Access efficiency&lt;/li&gt;
&lt;li&gt;Data integrity&lt;/li&gt;
&lt;li&gt;Reducing the time required to develop brand new applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Addressing such needs by relying on indexed flat files required solutions to be implemented artificially by the applications using such files. 
&lt;br&gt;
It was highly difficult, inefficient, time consuming, etc. And the wheel had to be re-invented all the time all over again.
&lt;br&gt;
So something else was required.
&lt;/p&gt;

&lt;a name=&quot;sec312&quot;&gt;&lt;/a&gt;
&lt;h4&gt;3.1.2 RDBMS and the relational model&lt;/h4&gt;

&lt;p&gt;
So in 1969, Edgar F. Cood, a British engineer, invented the relational model. In the relational model, business entities are modeled as &lt;i&gt;Tables&lt;/i&gt; and &lt;i&gt;Associations&lt;/i&gt; (relations).
&lt;br&gt;
The relational model is at the root of &lt;b&gt;RDBMS&lt;/b&gt; - Relational DataBase Management Systems - that ruled the Data Storage world for 30 years.
&lt;/p&gt;

&lt;p&gt;
The relational model is conceived to reduce redundancy in order to optimize disk space usage. At the time of its creation Disk storage was very expensive and limited. And the volume of data in  Information Systems was rather small.
&lt;br&gt;
The relational model avoids redundancy to optimize disk space usage by guaranteeing:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Structure:&lt;/b&gt; using normal design forms and modeling techniques&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Coherence:&lt;/b&gt;  using transaction principles and mechanisms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
An example relational model would be as follows, illustrating an Exam Grade Management application
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/288402d5-a103-4e0b-8c67-a211087c93bc&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 350px;&quot; alt=&quot;a relational model example&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/288402d5-a103-4e0b-8c67-a211087c93bc&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Relational Model Example&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
In this example, if we want to know the subject assigned to a student on his profile screen, we would need to 
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extract the personal data from the &quot;student&quot; table&lt;/li&gt;
&lt;li&gt;Fetch its subject if from the &quot;relation&quot; table&lt;/li&gt;
&lt;li&gt;Read the subject title from the &quot;subject&quot; table.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
&lt;span style=&quot;color: red;&quot;&gt;
Why, oh why, separate all this information in different tables when in practice 99% of the time we want to fetch all of this together ?
&lt;/span&gt;
&lt;/p&gt;


&lt;a name=&quot;sec313&quot;&gt;&lt;/a&gt;
&lt;h4&gt;3.1.3 criticism of the relational model&lt;/h4&gt;

&lt;p&gt;
The relational model comes from a time where storage was expensive. The fundamental idea behind its design is rationalizing storage space by ensuring every piece of information is stored only once.
&lt;br&gt;
But nowadays long-term storage space is not expensive at all anymore. A Terabyte of SSD storage is not more that a few dozens of dollars. Optimizing the storage space at all cost makes little sense today.
&lt;br&gt;
In addition, the relational model is not the best way to represent some information. Let&apos;s see some examples
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/111e754b-ac70-44fd-a4ea-260d6c76c68c&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px;&quot; alt=&quot;other models&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/111e754b-ac70-44fd-a4ea-260d6c76c68c&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Other models&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;ul&gt;
&lt;li&gt;Tabular information fits naturally well in the relational model but not only. Every time we can naturally divide a business problem into well-defined and predefined entities and relations among them, the relational model is usually a good fit.&lt;/li&gt;
&lt;li&gt;But then think of other type of information, such as registration forms, product descriptions, etc. Such types of semi-structured data fit very poorly in the relational model.&lt;/li&gt;
&lt;li&gt;Also molecular data or graph data would be way better stored in very different types of databases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The web giants had to get away from the mainframe pattern, and if you challenge that, the very fundamental architecture pattern on which all information systems were built, why wouldn&apos;t you challenge all the rest, including the relational model ?
&lt;br&gt;
We&apos;ll get back to this.
&lt;/p&gt;


&lt;a name=&quot;sec32&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.2 Horizontal scalability&lt;/h3&gt;

&lt;p&gt;
The mid and late 2000’s were times of major changes in the IT landscape. Hardware capabilities significantly increased and eCommerce and internet trade, in general, exploded.
&lt;br&gt;
Some internet companies- the &quot;Web giants&quot; (Yahoo!, Facebook, Google, Amazon, Ebay, Twitter, ...), pushed traditional databases to their limits. Those databases are by design hard to scale.
&lt;br&gt;
Traditional RDBMS and traditional architecture can only &lt;b&gt;scale up&lt;/b&gt;. And scaling up is tricky.
&lt;/p&gt;


&lt;a name=&quot;sec321&quot;&gt;&lt;/a&gt;
&lt;h4&gt;3.2.1 Scaling up&lt;/h4&gt;

&lt;p&gt;
With relational RDBMSes, the only way to improve performance is by scaling up, i.e. getting bigger servers (more CPU, more RAM, more disk, etc.). There&apos;s simply nothing else that can be done.
&lt;br&gt;
But one eventually hits a hard limit imposed by the current technology. 
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/5a4c7dd0-9d31-48f5-9960-d1513616ea7d&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px;&quot; alt=&quot;scaling up&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/5a4c7dd0-9d31-48f5-9960-d1513616ea7d&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
With traditional architectures and RDMBS, all the workload happens on one single machine. And while running a few thousands operations or transactions on one single machine is perhaps possible, going much beyond it just doesn&apos;t work. The programming paradigm we use - mostly around thread synchronizations and context switches - make it impossible to run effectively a million threads on one single machine for instance.
&lt;/p&gt;

&lt;p&gt;
But there&apos;s worst than that.
&lt;br&gt;
Imagine that a machine A with 4 CPUs, 64 GB RAM and 1 TB hard drive costs 10&apos;000 USD.
&lt;br&gt;
Do you think that a machine B with twice the power so 8 CPUs, 128 GB RAM and a 2 TB hard drive would cost the double, hence 20&apos;000 USD ?
&lt;br&gt;
&lt;b&gt;No!&lt;/b&gt; It would be much more than that, perhaps four or five times the price, so more than 40k USD.
&lt;/p&gt;

&lt;p&gt;
The price of individual machines doesn&apos;t scale linearly with the processing power of the machine, it&apos;s exponential !
&lt;/p&gt;


&lt;a name=&quot;sec322&quot;&gt;&lt;/a&gt;
&lt;h4&gt;3.2.2 Scaling out&lt;/h4&gt;

&lt;p&gt;
By rethinking the architecture of databases, the web giants have been able to make them scale at will, by adding more servers to clusters instead of upgrading the servers.
&lt;br&gt;
When scaling out, instead of buying bigger machines, one buys more machines and add them in a processing cluster, working together on distributed data and processing.
&lt;br&gt;
The servers are not made of expensive, high-end hardware; they are qualified as &lt;i&gt;commodity hardware&lt;/i&gt; (or commodity servers).
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/9f763a29-a1f7-40cf-b6f6-c47e039eb5a0&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px;&quot; alt=&quot;scaling out&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/9f763a29-a1f7-40cf-b6f6-c47e039eb5a0&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
When scaling out, the limits vanish, one can add as many nodes as one wants in a processing cluster.
&lt;br&gt;
And there&apos;s a cherry on the cake, recall the example of machine A above, buying 10 machine A is not even 10 times the price of a single machine A, since one can get discounts from the number being bought.
&lt;/p&gt;

&lt;p&gt;
The only drawback is that the application leveraging on scaling out, or the information system as a whole, needs to be designed from the grounds up for distribution. And there are constraints for this, we&apos;ll see that further in this article.
&lt;/p&gt;

&lt;p&gt;
Scaling out is also called Horizontal scalability while scaling up is called vertical scalability.
&lt;/pa&gt;


&lt;a name=&quot;sec33&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.3 Data Distribution&lt;/h3&gt;

&lt;p&gt;
With most NoSQL databases, the data is not stored in one place (i.e. on one server). It is distributed among the nodes of the cluster. When created, an object is split in a number of shards, for instance 4 shards, A, B, C, D and these shards are assigned to a node in the cluster. 
&lt;br&gt;
This is called &lt;b&gt;sharding&lt;/b&gt; - or &lt;b&gt;partitioning&lt;/b&gt; - the portion of data assigned to a node is called a shard - or a partition.
&lt;/p&gt;

&lt;p&gt;
Having more cluster nodes implies a higher risk of having some nodes crash, or a network outage splitting the cluster in two. For this reason, and to avoid data loss, objects are also replicated across the clusters. The number of copies, called replicas, can be tuned. 3 replicas is a common figure.
&lt;br&gt;
Imaging that the specifications of a given computer indicates that there is a 10% chance for the computer to experience any kind of hardware failure in its first year of exploitation. Then imagine you have 10 nodes like that one in a cluster, what is the probability that at least one of these nodes experiences an hardware failure ? Yes, you can be nearly sure at least one of them will fail.
&lt;p&gt;

&lt;p&gt;
For this reason, when we start to distribute data on a cluster of multiple machines, we have to design for failures.
&lt;br&gt;
In data management, this means creating multiple copies of every shard in such a way that we maximize the chances of one of them always being available.
&lt;br&gt;
This is called &lt;B&gt;replication&lt;/b&gt;.
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1d8730dc-6e30-48ad-a7fd-73a8d718f92a&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 250px;&quot; alt=&quot;data distribution&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1d8730dc-6e30-48ad-a7fd-73a8d718f92a&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;
We can see here that the objects has been split in 4 shards A, B, C, D and that every shard has three replicas.
&lt;/p&gt;

&lt;p&gt;
The objects may move, as nodes crash or new nodes join the cluster, ready to take charge of some of the objects. Such events are usually handled automatically by the cluster; the operation of shuffling objects around to keep a fair repartition of data is called &lt;b&gt;rebalancing&lt;/b&gt;.
&lt;/p&gt;


&lt;a name=&quot;sec34&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.4 Properties of a distributed system&lt;/h3&gt;

&lt;p&gt;
In RDBMSes, we expect DB transactions to respect some fundamental properties, identified by &lt;b&gt;ACID&lt;/b&gt;: &lt;i&gt;Atomicity, Consistency, Isolation and Durability&lt;/i&gt;.
&lt;br&gt;
In distributed systems, we consider things a little differently and consider the following properties:
&lt;/o&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;Availability&lt;/b&gt;
&lt;br&gt;
Availability (or lack thereof) is a property of the database cluster. The cluster is available if a request made by a client is always acknowledged by the system, i.e. it is guaranteed to be taken into account.
&lt;br&gt;
That doesn’t mean that the request is processed immediately. It may be put on hold. But an &lt;i&gt;available&lt;/i&gt; system should at a minimum always acknowledge it immediately.
&lt;br&gt;
Practically speaking, availability is usually measured in percents. For instance, 99.99% availability means that the system is unavailable at most 0.01% of the time, that is, at most 53 min per year.
&lt;br&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;b&gt;Partition tolerance&lt;/b&gt;
&lt;br&gt;
Partition Tolerance is verified if a system made of several interconnected nodes can stand a partition of the cluster; if it continues to operate when one or several nodes disappear. This happens when nodes crash or when a network equipment is shut down, taking a whole portion of the cluster away.
&lt;br&gt;
Partition tolerance is related to availability and consistency, but it is still different. It states that the system continues to function internally (e.g. ensuring data distribution and replication), whatever its interactions with a client.
&lt;/li&gt;

&lt;li&gt;
&lt;b&gt;Consistency&lt;/b&gt;
&lt;br&gt;
When talking about distributed databases, like NoSQL, consistency has a meaning that is somewhat different than in the relational context.
&lt;br&gt;
It refers to the fact that all replicas of an entity, identified by a key in the database, have the same value whatever the node being queried.
&lt;br&gt;
With many NoSQL databases, updates take a little time to propagate across the cluster. When an entity’s value has just been created or modified, there is a short time span during which the entity is not consistent. However the cluster guarantees that it will eventually be, when replication has occurred. This is called eventual consistency
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;
These 3 properties, Consistency, Availability and Partition tolerance, are not independent. 
&lt;br&gt;
The CAP theorem - or Brewer’s theorem -  states that &lt;b&gt;a distributed system cannot guarantee all 3 properties at the same time&lt;/b&gt;.
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/7e1bf188-d074-409d-a70e-26fff0d5e80c&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;The CAP theorem&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/7e1bf188-d074-409d-a70e-26fff0d5e80c&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
This is a theorem. That means it is formally true, but in practice it is less severe than it seems.
&lt;br&gt;
The system or a client can often choose CA, AP or CP according to the context, and &quot;walk&quot; along the chosen edge by appropriate tuning.
&lt;br&gt;
Partition splits happen, but they are rare events (hopefully).
&lt;/p&gt;

&lt;p&gt;
Traditional Relational DBMSes would be seen as CA - consistency is a must
&lt;br&gt;
Many NoSQL DBMSes are AP - availability is a must. Big clusters failures happen all the time so they better live with it. Consistency is only eventual.
&lt;/p&gt;


&lt;a name=&quot;sec341&quot;&gt;&lt;/a&gt;
&lt;h4&gt;3.4.1 Eventual consistency&lt;/h4&gt;

&lt;p&gt;
Consistency refers to the fact that all replicas of an entity, identified by a key in the database, have the same value at any give time whatever the node being queried.
&lt;/p&gt;

&lt;p&gt;
With many NoSQL databases, the preferred working mode is AP and &lt;i&gt;all-the-time consistency&lt;/i&gt; is sacrificed. 
&lt;br&gt;
Favoring performance, updates take a little time to propagate across the cluster. When an entity’s value has just been created or modified, there is a short time span during which the entity is not consistent. One node being queried at that moment could show the previous value while another node at the same time would already show the new value.
&lt;br&gt;
However the cluster guarantees that it will eventually be, when replication has occurred. This is called &lt;b&gt;eventual consistency&lt;/b&gt; and this is an essential notion.
&lt;/p&gt;

&lt;p&gt;
While all-the-time consistency is sacrificed, &lt;b&gt;eventual consistency is a must and is guaranteed by most-if-not-all NoSQL Database&lt;/b&gt;.
&lt;/p&gt;


&lt;a name=&quot;sec4&quot;&gt;&lt;/a&gt;
&lt;h2&gt;4. NoSQL / NewSQL&lt;/h2&gt;

&lt;p&gt;
NoSQL databases are a new type of databases emerging from the web giants technologies mostly, scaling out natively and renouncing to the usual behaviours and features of RDBMS - Relational Database Management Systems.
&lt;/p&gt;


&lt;a name=&quot;sec41&quot;&gt;&lt;/a&gt;
&lt;h3&gt;4.1 NoSQL&lt;/h3&gt;

&lt;p&gt;
A NoSQL - originally referring to &quot;&lt;b&gt;not-SQL&lt;/b&gt;&quot; for &quot;non-relational&quot; - database provides a mechanism for storage and retrieval of data that is modeled in &lt;b&gt;means other than the tabular relations&lt;/b&gt; used in relational databases. 
&lt;br&gt;
Such databases have existed since the late 1960s, but the name &quot;NoSQL&quot; was only coined in the early 21st century, triggered by the needs of Web 2.0 companies.
&lt;br&gt;
NoSQL databases are increasingly used in Big Data and Real-Time Web applications.
&lt;br&gt;
NoSQL systems are also sometimes called &quot;Not only SQL&quot; to emphasize that they may support SQL-like query languages or sit alongside SQL databases in polyglot-persistent architectures.
&lt;br&gt;
(Wikipedia - &lt;a href=&quot;https://en.wikipedia.org/wiki/NoSQL&quot;&gt;https://en.wikipedia.org/wiki/NoSQL&lt;/a&gt;)
&lt;/p&gt;

&lt;p&gt;
The fundamental idea behind NoSQL is as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Because of the need to distribute data (Big Data), the Web giants have abandoned the whole idea of ACID transactions (only eventual consistency is possible).&lt;/li&gt;
&lt;li&gt;So if we drop ACID Transactions - which we always deemed to be so fundamental - why wouldn&apos;t we challenge all the rest - the relational model and table structure?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
There are 4 common types of NoSQL databases:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Document-oriented &lt;/b&gt;, e.g. MongoDB, ElasticSearch
&lt;li&gt;&lt;b&gt;Column-family&lt;/b&gt; (aka BigTable), e.g. Cassandra
&lt;li&gt;&lt;b&gt;Key/Value pairs&lt;/b&gt;, e.g. Redis
&lt;li&gt;&lt;b&gt;Graph&lt;/b&gt;, e.g. Neo4J
&lt;/ul&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/c5f80a99-798d-4be2-969a-67f55d95700f&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Types of NoSQL database&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/c5f80a99-798d-4be2-969a-67f55d95700f&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Document-oriented databases are really the most wide spread with market leaders such as MongoDB, ElasticSearch, CouchDB, etc.
&lt;br&gt;
Column-oriented databases are also wide spread with multiple good open source solutions.
&lt;br&gt;
Key/Value pairs databases are really &lt;b&gt;distributed caching&lt;/b&gt; products in in the end. Multiple good solutions are available on the market but most of them are proprietary software with sometimes a limited open-source version (unfortunately).
&lt;br&gt;
In terms of graph oriented databases, the lead player is Neo4J.
&lt;/p&gt;

&lt;p&gt;
The following schema provides an illustration of the way data is structured and stored in these Databases:
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/81727cc6-f37c-4295-b54d-d3adccb4a673&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;NoSQL data storage examples&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/81727cc6-f37c-4295-b54d-d3adccb4a673&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
The NoSQL landscape is y very rich ecosystems with hundreds of different products and solution and growing continuously, with nearly every week a new product appearing.
&lt;/p&gt;


&lt;a name=&quot;sec42&quot;&gt;&lt;/a&gt;
&lt;h3&gt;4.2 NewSQL&lt;/h3&gt;

&lt;p&gt;
What is NewSQL ?
&lt;/p&gt;

&lt;p&gt;
NewSQL refers to relational databases that have adopted upon some of the NoSQL genes, thus exposing a relational data model and SQL interfaces to distributed, high volume databases.
&lt;/p&gt;

&lt;p&gt;
NewSQL, contrary to NoSQL, enables an application to keep 
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The relational view on the data&lt;/li&gt;
&lt;li&gt;The SQL query language&lt;/li&gt;
&lt;li&gt;Response times suited to transactional processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Some were built from scratch (e.g. VoltDB), others are built on top of a NoSQL data store (e.g. SQLFire, backed by GemFire, a key/value store)
&lt;/p&gt;

&lt;p&gt;
The current trend is for some proven NoSQL databases, like Cassandra, to offer a thin SQL interface, achieving the same purpose
&lt;br&gt;
Generally speaking, the frontier between NoSQL and NewSQL is a bit blurry… SQL compliance is often sought for, as the key to integrating legacy SQL software (ETL, reporting) with modern No/NewSQL databases
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/d1973df4-a625-4bdd-a98b-e17c7348172e&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;NewSQL examples&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/d1973df4-a625-4bdd-a98b-e17c7348172e&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;a name=&quot;sec5&quot;&gt;&lt;/a&gt;
&lt;h2&gt;5. Hadoop and Data Lakes&lt;/h2&gt;

&lt;p&gt;
Around 2006, Google published two papers, &quot;GFS - The Google FileSystem&quot; where they explained how they designed an implemented a distributed filesystem and &quot;Map Reduce&quot; where they presented the distributed programming paradigm they used to process data stored on GFS.
&lt;br&gt;
A few years after, google published &quot;Big Table&quot;, a paper presenting how they designed and implemented a &lt;i&gt;Column-oriented database&lt;/i&gt; on top of HDFS and MapReduce.
&lt;/p&gt;

&lt;p&gt;
Doug Cutting, the leader of the Apache Lucene Project at the time discovered these papers and decided to work on an Open-Source implementation of these concepts.
&lt;br&gt;
Hadoop was born.
&lt;/p&gt;


&lt;a name=&quot;sec51&quot;&gt;&lt;/a&gt;
&lt;h3&gt;5.1 What is Hadoop ?&lt;/h3&gt;

&lt;p&gt;
Hadoop is an &lt;b&gt;Open Source Platform&lt;/b&gt; providing:

&lt;ul&gt;
&lt;li&gt;A distributed, scalable and fault tolerant storage system as a grid&lt;/li&gt;
&lt;li&gt;Initially, a single parallelism paradigm : MapReduce to reuse the storage nodes as processing nodes&lt;/li&gt;
&lt;li&gt;Since Hadoop V2 and YARN, other parallelization paradigms can be implemented on Hadoop&lt;/li&gt;
&lt;li&gt;Schemaless and optimized sequential write once and read many times&lt;/li&gt;
&lt;li&gt;Querying and processing DSL (Hive, Pig)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Hadoop was initially primarily intended for Big Data Analytics. It is the middleware under the Data Lake Architecture pattern and intents to revolution the architecture of analytical information systems / decision support systems.
&lt;br&gt;
Nowadays Hadoop can be an infrastructure for much more, such as Micro-services architecture (Hadoop V3) or Real-time Architectures.
&lt;/p&gt;

&lt;p&gt;
Hadoop is declined in different distributions: Fundation Apache, Cloudera, HortonWorks, MapR, IBM, etc.
&lt;/p&gt;


&lt;a name=&quot;sec52&quot;&gt;&lt;/a&gt;
&lt;h3&gt;5.2 Hadoop Overview&lt;/h3&gt;

&lt;p&gt;
Hadoop is designed as a layered software where technologies in every layer can be interchanged at will:
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/690fe110-474d-411b-96a5-2757af8b3906&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Hadoop Overview&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/690fe110-474d-411b-96a5-2757af8b3906&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;Distributed storage&lt;/b&gt;: Hadoop packages HDFS as the default underlying distributed filesystem. But for instance the MapR Hadoop distribution uses the MAPR filesystem instead.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Parallel Computing Framework / MapReduce Processing Engine&lt;/b&gt;: In Hadoop V1, MapReduce was the only parallel computing paradigm available on top of Hadoop, taking care of the processing distribution as well as the resources negotiation on the Hadoop cluster. 
&lt;br&gt;
With Hadoop 2.0, The MapReduce paradigm has been split from the Resource negotiation which became YARN - Yet Another Resource Negotiator. With this split, it has become possible to use Hadoop with different parallel processing constructs and paradigms, MapReduce becoming just one possibility among others.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Machine Learning / Processing&lt;/b&gt;: This is in the end the most essential layer on top of Hadoop core. Hadoop is designed first and foremost for Big Data Analytics. There are numerous solutions that were initially either implemented on top of MapReduce or ported to MapReduce. 
&lt;br&gt;
Nowadays, with YARN, software doesn&apos;t need anymore to be ported to MapReduce to run on Hadoop, it just needs to integrate with YARN.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Orchestration&lt;/b&gt;: Numerous different solution can be used to operate Hadoop and orchestrate processes.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Querying&lt;/b&gt;: A lot of NoSQL / NewSQL databases have been implemented as an Hadoop querying framework, such as HBase or Hive. Some more advanced tools goes beyond querying with as Pig.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Reporting&lt;/b&gt;: User have multiple choices of software specialized in building reports on the data in Hadoop. 
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;IS Integration&lt;/b&gt;: Integrating Hadoop in the Information System, specifically building data import / Export between Hadoop and the operational information system components is a key concern. Numerous different solutions have been developed for this and are packaged with most Hadoop distributions.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Supervision and Management&lt;/b&gt;: Most Hadoop distributions provide their own management tool. Some tools are available as Apache projects.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Hadoop is a very large ecosystems of hundreds of different software in all these different layers.
&lt;br&gt;
The most common ones would be as follows:
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/29b960d3-03ef-4d5f-bce2-bb677989dc27&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Hadoop Components&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/29b960d3-03ef-4d5f-bce2-bb677989dc27&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
But then again there are really many more components than that in a typical Hadoop distribution.
&lt;br&gt;
Most Hadoop distributions are quite behemoth software stacks that would be very difficult to integrate and configure manually, which is the very reason behind the success of these distributions.
&lt;br&gt;
Hadoop core on its own is fairly complex to install, configure and fine tune so whenever one needs Hadoop core only for his specific software (e.g to run spark), it&apos;s sometimes a more appropriate approach to search for a lighter cluster management system such as &lt;i&gt;Apache Mesos&lt;/i&gt; for instance; more on that later in this article.
&lt;/o&gt;


&lt;a name=&quot;sec53&quot;&gt;&lt;/a&gt;
&lt;h3&gt;5.3 Hadoop Architecture&lt;/h3&gt;

&lt;p&gt;
A simplified view of Hadoop core components deployment architecture would be as follows:
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/217b1b5e-1555-46e2-8033-7e86f8de2f2a&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Hadoop Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/217b1b5e-1555-46e2-8033-7e86f8de2f2a&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Hadoop Architecture&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Since Hadoop 2, having two master nodes for high-availability and avoiding &lt;i&gt;single points of failure&lt;/i&gt; on the master components is highly advised.
&lt;br&gt;
The components from Hadoop core are deployed as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
The &lt;b&gt;HDFS Name node&lt;/b&gt; (and secondary name node) is the center piece of the HDFS File System. It acts as the HDFS Master and keeps the directory tree and tracks where on the cluster the file data is kept. The &lt;b&gt;HDFS Data Nodes&lt;/b&gt; acts as slave processes, run on individual cluster nodes and take care of data storage.
&lt;/li&gt;
&lt;li&gt;
The &lt;b&gt;YARN Resource Manager&lt;/b&gt; (and secondary resource manager) is the master that arbitrates all the available cluster resources and thus helps manage the distributed applications running on the YARN system. It works together with the per-node &lt;b&gt;NodeManagers&lt;/b&gt; and the per-application &lt;b&gt;ApplicationMaster&lt;/b&gt;.
&lt;/li&gt;
&lt;li&gt;
The &lt;b&gt;MapReduce JobTracker&lt;/b&gt; is the service within Hadoop that farms out MapReduce tasks to specific nodes in the cluster, ideally the nodes that have the data for &lt;b&gt;co-local processing optimization&lt;/b&gt;, or at least are in the same rack. Client applications submit jobs to the Job tracker. &lt;b&gt;MapReduce TaskTrackers&lt;/b&gt; run on individual cluster nodes, execute the tasks and report the status of tasks to the JobTracker.
&lt;/li&gt;
&lt;/ul&gt;


&lt;a name=&quot;sec54&quot;&gt;&lt;/a&gt;
&lt;h3&gt;5.4 The DataLake Architecture pattern&lt;/h3&gt;

&lt;p&gt;
From &lt;a href=&quot;https://en.wikipedia.org/wiki/Data_lake &quot;&gt;Wikipedia&lt;/a&gt;:
&lt;br&gt;
A data lake is a system or repository of data stored in its natural/raw format.
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
It&apos;s is usually a single store of data including raw copies of source system data, sensor data, social data etc. and transformed data used for tasks such as reporting, visualization, advanced analytics and machine learning. 
&lt;/li&gt;
&lt;li&gt;
It can include structured data from relational databases, semi-structured data (CSV, logs, XML, JSON), unstructured data (emails, documents, PDFs) and binary data (images, audio, video).
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
With the continued growth in scope and scale of analytics applications using Hadoop and other data sources, then the vision of an enterprise data lake can become a reality.
&lt;br&gt;
In a practical sense, a data lake is characterized by three key attributes:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;Collect everything&lt;/b&gt;. A data lake contains all data, both raw sources over extended periods of time as well as any processed data.
&lt;br&gt;
A data lake is characterized by a &lt;b&gt;Big Volume&lt;/b&gt; of data.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Dive in anywhere&lt;/b&gt;. A data lake enables users across multiple business units to refine, explore and enrich data on their terms.
&lt;br&gt;
In a Data Lake, one doesn&apos;t know &lt;i&gt;a priori&lt;/i&gt; the analytical structures.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Flexible access&lt;/b&gt;. A data lake enables multiple data access patterns across a shared infrastructure: batch, interactive, online, search, in-memory and other processing engines.
&lt;br&gt;
As a result, a data lake delivers maximum scale and insight with the lowest possible friction and cost.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The fundamental approach of Data Lakes is to &lt;b&gt;pull&lt;/b&gt; the required data from the raw data storage, transforming it and processing it dynamically, as required per the use case being executed. It&apos;s entirely dynamic, queries and processes are designed on the fly. 
&lt;br&gt;
The storage principle is to store everything, all the raw data from the operational Information System as well as all the data produced by the IS, log files, usage metrics, etc. (Collect everything pattern).
&lt;br&gt;
Hadoop is kind of the &lt;i&gt;Operating System&lt;/i&gt; underneath the Data Lake pattern and with Hadoop&apos;s power, there is nearly no analytics use case that can&apos;t be implemented in a dynamic fashion, requiring at worst a few hours of runtime processing before providing the expected results
&lt;/p&gt;

&lt;p&gt;
This is in complete opposition with the Data Warehouse pattern where the data was &lt;b&gt;pushed&lt;/b&gt; in statically predefined transformation pipelines. The most critical drawback of this approach is the impossibility to come up with a new use case in a quick time. Most of the time, when a corporation requires a new KPI to be computed by the analytical system, if the required data was not already collected for another use case, it was impossible to provide quickly, requiring for instance to wait 6 months before providing the KPI on a 6 months period.
&lt;br&gt;
Hadoop finally made it possible at a cheap cost to get away fro this &lt;i&gt;push&lt;/i&gt; pattern. 
&lt;/p&gt;
&lt;br&gt;


&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/eb3fe0db-418c-48df-a404-146963fb779e&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;DataLake Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/eb3fe0db-418c-48df-a404-146963fb779e&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;DataLake Architecture&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
The &lt;i&gt;Data Lake&lt;/i&gt; architecture pattern and its hadoop engine form a tremendous opportunity to finally get away from the &lt;i&gt;Data Warehouse pattern&lt;/i&gt;.
&lt;br&gt;
But there are pitfalls of course and many corporations experienced it the hard way.
&lt;br&gt;
It has been stated to much everywhere that data can be incorporated &quot;as is&quot; in data lakes that way too many corporations took it too literaly, forgetting about one essential aspect, even in Data Lakes.
&lt;br&gt;
A minimum of data cleaning, cleansing and preparation is always required. The most crucial aspect than can nevfer be neglected is the need to alway have proper &lt;b&gt;correlation ID&lt;/b&gt;s in every single piece of data that is being ingested in a data lake. 
&lt;br&gt;
Without correlation IDs, data is unusable. And your Data Lake turns into a &lt;i&gt;Data Swamp&lt;/i&gt;.
&lt;/p&gt;


&lt;a name=&quot;sec6&quot;&gt;&lt;/a&gt;
&lt;h2&gt;6. Streaming Architectures&lt;/h2&gt;

&lt;p&gt;
Streaming data refers to data that is continuously generated, usually in high volumes and at high velocity. A streaming data source would typically consist of a stream of logs that record events as they happen - such as a user clicking on a link in a web page, or a sensor reporting the current temperature.
&lt;/p&gt;

&lt;p&gt;
A &lt;b&gt;streaming data architecture&lt;/b&gt; is a framework of software components built to ingest and process large volumes of streaming data from multiple sources. While traditional data solutions focused on writing and reading data in batches, a streaming data architecture consumes data immediately as it is generated, persists it to storage, and may include various additional components per use case - such as tools for real-time processing, data manipulation and analytics.
&lt;br&gt;
A &lt;b&gt;real-time&lt;/b&gt; system is an event-driven system that is available, scalable and stable, able to take decisions (actions) with a latency defined as &lt;i&gt;below the frequency of events&lt;/i&gt;.
&lt;/p&gt;

&lt;p&gt;
Streaming Architectures are not strictly related to the web giants and the Big Data revolution and CEP - Complex Events Processing - Engines exists since the early 2000s.
&lt;br&gt;
However, streaming architectures evolved significantly with products emerging from the needs of the web giants in Lambda Architecture first and then Kappa Architecture.
&lt;/p&gt;

&lt;!--
6.1 CEP RT architectures
6.2 Lambda Architecture
6.3 Kappa architecture
--&gt;

&lt;a name=&quot;sec61&quot;&gt;&lt;/a&gt;
&lt;h3&gt;6.1 Complex Event Processing&lt;/h3&gt;

&lt;p&gt;
From &lt;a href=&quot;https://en.wikipedia.org/wiki/Complex_event_processing&quot;&gt;Wikipedia&lt;/a&gt;
&lt;br&gt;
Complex event processing, or CEP, consists of a set of concepts and techniques developed in the early 1990s for processing real-time events and extracting information from event streams as they arrive. The goal of complex event processing is to identify meaningful events (such as opportunities or threats) in real-time situations and respond to them as quickly as possible.
&lt;/p&gt;

&lt;p&gt;
In a &lt;i&gt;Complex Event Processing Architecture&lt;/i&gt; :
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Historical data is regularly and consistently updated with live data.&lt;/li&gt;
&lt;/li&gt;Live data is available to the end user &lt;/li&gt;
&lt;li&gt;
Both types or data (historical and live) are not necessarily presented consistently to the end user.
&lt;ul&gt;
&lt;li&gt;Both sets of data can have their own screens or even application&lt;/li&gt;
&lt;li&gt;&lt;i&gt;A consistent view on both sets of data would be proposed by Lambda Architecture (next topic in this presentation)&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/3f822b48-b325-4d2b-a36e-7245dceb80f2&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Complex Event Processing&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/3f822b48-b325-4d2b-a36e-7245dceb80f2&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Complex Event Processing&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
A few notes on typical CEP deployments, in a raw fashion:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;The rules GUI&lt;/b&gt; is often a user friendly editor supporting &lt;i&gt;hot&lt;/i&gt; updates of rules and made available to business users.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;The capture middleware&lt;/b&gt; should support very high throughput of thousands of events per second, just as the whole processing line and negligible latency.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;The CEP engine&lt;/b&gt; needs to support very high throughput as well and usually a maximum latency of a few dozen milliseconds to hundreds milliseconds. Fault tolerance and state coherence are common concerns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Complex Event Processing engines and architecture are heavily used in the industry in the world of real-time computing systems, such as trading systems, payment monitoring systems, etc.
&lt;br&gt;
Such engines form however a quite legacy technology and have limits in terms of analytics. Most if not all CEP engines on the market even nowadays are really some sort of evolved &lt;i&gt;rules-engines&lt;/i&gt;.
&lt;br&gt;
And that would be the most common limit of CEP engines, the fact that its really only about rules. Machine learning and AI use cases are limited on CEP engines by the difficulty of these systems to derive features requiring correlation with large historical datasets. 
&lt;/p&gt;

&lt;p&gt;
The rise of Big Data analytics technologies have opened the door for much more advanced analytics use cases in real-time. Lambda Architecture and Kappa Architectures are much more recent approaches to real-time analytics.
&lt;/p&gt;


&lt;a name=&quot;sec62&quot;&gt;&lt;/a&gt;
&lt;h3&gt;6.2 Lambda Architecture&lt;/h3&gt;

&lt;p&gt;
The Lambda Architecture, first proposed by Nathan Marz, attempts to provide a combination of technologies that together provide the characteristics of a web-scale system that satisfies requirements for availability, maintainability, fault-tolerance and low-latency.
&lt;/p&gt;

&lt;p&gt;
Quoting &lt;a href=&quot;https://en.wikipedia.org/wiki/Lambda_architecture&quot;&gt;Wikipedia&lt;/a&gt;: &quot;&lt;i&gt;Lambda architecture is a data-processing architecture designed to handle massive quantities of data by taking advantage of both batch- and stream-processing methods. 
&lt;br&gt;
This approach to architecture attempts to balance latency, throughput, and fault-tolerance by using batch processing to provide comprehensive and accurate views of batch data, while simultaneously using real-time stream processing to provide views of online data. The two view outputs may be joined before presentation. 
&lt;br&gt;
The rise of lambda architecture is correlated with the growth of big data, real-time analytics, and the drive to mitigate the latencies of map-reduce.&lt;/i&gt;&quot;
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 50px; &quot; alt=&quot;Lambda Symbol&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
At a high level, the Lambda Architecture is designed to handle both real-time and historically aggregated batched data in an integrated fashion. It separates the duties of real-time and batch processing so purpose-built engines, processes, and storage can be used for each, while serving and query layers present a unified view of all of the data. 
&lt;br&gt;
The efficiency of this architecture becomes evident in the form of increased throughput, reduced latency and negligible errors. While we mention data processing we basically use this term to represent high throughput, low latency and aiming for near-real-time applications.
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/0b993a55-6c71-4eab-811d-426e084385b6&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Lambda Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/0b993a55-6c71-4eab-811d-426e084385b6&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
As new data is introduced to the system, it is processed simultaneously by both the batch layer, and the speed layer. The batch layer is an append-only repository containing unprocessed raw data. The batch layer periodically or continuously runs jobs that create views of the batch data-aggregations or representations of the most up-to-date versions. These batch views are sent to the serving layer, where they are available for analytic queries.
&lt;br&gt;
At the same time that data is being appended to the batch layer, it is simultaneously streaming into the speed layer. The speed layer is designed to allow queries to reflect the most up-to-date information-necessary because the serving layer&apos;s views can only be created by relatively long-running batch jobs. The speed layer computes only the data needed to bring the serving layer&apos;s views to real time-for instance, calculating totals for the past few minutes that are missing in the serving layer&apos;s view.
&lt;br&gt;
By merging data from the speed and serving layers, low latency queries can include data that is based on computationally expensive batch processing, and yet include real-time data. In the Lambda Architecture, the raw source data is always available, so redefinition and re-computation of the batch and speed views can be performed on demand. The batch layer provides a big data repository for machine learning and advanced analytics, while the speed and serving layers provide a platform for real-time analytics.
&lt;br&gt;
The Lambda Architecture provides a useful pattern for combining multiple big data technologies to achieve multiple enterprise objectives.
&lt;/p&gt;

&lt;p&gt;
There are numerous solutions nowadays to build every layer of a Lambda Architecture:
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/56ffadc9-952a-4e2c-9867-6e8799ffcc26&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Lambda Architecture components&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/56ffadc9-952a-4e2c-9867-6e8799ffcc26&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
The takeaway here is that we have gone a long way since &lt;i&gt;Complex Event Processing&lt;/i&gt; architectures and we have now numerous solutions to build new generations of streaming architectures able to extend real-time streaming to much more advanced analytics use cases, embracing &lt;i&gt;Real-time Artificial Intelligence&lt;/i&gt; use cases.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Pros and Cons of Lambda Architecture.&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Pros&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Batch layer of Lambda architecture manages historical data with the fault tolerant distributed storage which ensures low possibility of errors even if the system crashes.&lt;/li&gt;
&lt;li&gt;It is a good balance of speed and reliability.&lt;/li&gt;
&lt;li&gt;Fault tolerant and scalable architecture for data processing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Cons&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;It can result in coding overhead due to the need to implement the same analytics logic twice:&lt;/b&gt; one time in the speed layer and one time all over again in the batch layer.&lt;/li&gt;
&lt;li&gt;Re-processes every batch cycle which is not beneficial in certain scenarios.&lt;/li&gt;
&lt;li&gt;A data modeled with Lambda architecture is difficult to migrate or reorganize.&lt;/li&gt;
&lt;/ul&gt;


&lt;a name=&quot;sec63&quot;&gt;&lt;/a&gt;
&lt;h3&gt;6.3 Kappa Architecture&lt;/h3&gt;


&lt;p&gt;
In 2014 Jay Kreps started a discussion where he pointed out some discrepancies of Lambda architecture that further led the big data world to another alternate architecture that used less code resource and was capable of performing well in certain enterprise scenarios where using multi layered Lambda architecture seemed like extravagance.
&lt;br&gt;
Kappa Architecture cannot be taken as a substitute of Lambda architecture on the contrary it should be seen as an alternative to be used in those circumstances where active performance of batch layer is not necessary for meeting the standard quality of service.
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/fd9e852b-718f-48b3-8c89-c0ab9c596488&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 250px; &quot; alt=&quot;Lambda vs Kappa Symbol&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/fd9e852b-718f-48b3-8c89-c0ab9c596488&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Kappa architecture is a streaming-first architecture deployment pattern. With most recent Stream Processing technologies (Kafka Streams, Flink, etc.) the interest and relevance of the batch layer tend to diminish. The streaming layer matches computation abilities of the batch layer (ML, statistics, etc.) and stored data as it processes it. 
&lt;br&gt;
A batch layer would only be needed to kick-start the system on historical data but then Apache Flink can very well do that
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1ad9d53b-e708-4f20-8fab-2f8b3988f0af&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Lambda Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/1ad9d53b-e708-4f20-8fab-2f8b3988f0af&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Kappa architecture can be deployed for those data processing enterprise models where:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple data events or queries are logged in a queue to be catered against a distributed file system storage or history.&lt;/li&gt;
&lt;li&gt;The order of the events and queries is not predetermined. Stream processing platforms can interact with database at any time.&lt;/li&gt;
&lt;li&gt;It is resilient and highly available as handling Terabytes of storage is required for each node of the system to support replication.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Pros and Cons of Kappa architecture&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Pros&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kappa architecture can be used to develop data systems that are online learners and therefore don’t need the batch layer.&lt;/li&gt;
&lt;li&gt;Re-processing is required only when the code changes.&lt;/li&gt;
&lt;li&gt;It can be deployed with fixed memory.&lt;/li&gt;
&lt;li&gt;It can be used for horizontally scalable systems.&lt;/li&gt;
&lt;li&gt;Fewer resources are required as the machine learning is being done on the real time basis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Cons&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Absence of batch layer might result in errors during data processing or while updating the database that requires having an exception manager to reprocess the data or reconciliation.&lt;/li&gt;
&lt;/ul&gt;


&lt;a name=&quot;sec7&quot;&gt;&lt;/a&gt;
&lt;h2&gt;7. Big Data 2.0&lt;/h2&gt;


&lt;p&gt;
When google published their papers in the early 2000s, it was quite a tsunami in the Computer Engineering World. Doug Cutting and the guys behind Hadoop started working on Hadoop but a lot of other initiatives kicked off as well.
&lt;br&gt;
With their approach - scaling information systems on commodity hardware, it turned out that massive computational systems suddenly became affordable and it gave a whole new level of interest in distributed systems and distributed computing.
&lt;br&gt;


&lt;p&gt;
There are now an entire range of engines that transcend the Hadoop framework and are dedicated to specific verticals (e.g. structured data, graph data, streaming data, etc.)
&lt;br&gt;
Nowadays, The NoSQL ecosystem provides incredibly efficient alternatives to HDFS storage in the storage layer. In the processing layer, there is a plethora of solutions available from Kafka Streams to Apache Flink through Spark, etc.
&lt;br&gt;
On the resource negotiation side as well, multiple initiatives provide lightweight and interesting alternatives to Hadoop&apos;s YARN.
&lt;/p&gt;


&lt;a name=&quot;sec71&quot;&gt;&lt;/a&gt;
&lt;h3&gt;7.1 Alternatives to Hadoop &lt;/h3&gt;


&lt;p&gt;
A specific project kicked off by the University of California retained quite a bit of attention at the time, the &lt;i&gt;Nexus&lt;/i&gt; project renamed later &lt;i&gt;Mesos&lt;/i&gt; and given to the Apache Software Foundation.
&lt;/p&gt;
&lt;p&gt;
Apache Mesos intended to be kind of the &lt;i&gt;Operating System&lt;/i&gt; of a computer cluster, somehow in the same way the &lt;i&gt;Linux Kernel&lt;/i&gt; for instance is operating a single machine. Mesos intended to provide the same kind of primitives for resources management at the scale of a whole cluster.
&lt;br&gt;
Pretty early in the Mesos development story, support of docker containers has been added to enable users to deploy and scale applications in the form of docker containers.
&lt;/p&gt;

&lt;p&gt;
A few years Later, some folks inspired from &lt;i&gt;Google Borg&lt;/i&gt; and created in their turn a &lt;i&gt;cloud container orchestration system&lt;/i&gt; for automating computer application deployment, scaling, and management. They named it Kubernetes.
&lt;br&gt;
With Mesos and Kubernetes gaining a lot of traction since scaling applications in the form of docker containers is extremely convenient, the folks at Hadoop added support to deploying applications in the form of docker containers as well in YARN in Hadoop 3.0.
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/3cb0a91f-9959-4f4f-b55b-79b4c2d1c57a&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 650px;&quot; alt=&quot;Big Data 2.0&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/3cb0a91f-9959-4f4f-b55b-79b4c2d1c57a&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;
Nowadays in 2021, with Hadoop 3, these 3 technologies converge tend to converge to the same possibilities. Hadoop 3 supports deploying jobs as docker containers just as Mesos and Kubernetes.
&lt;br&gt;
Mesos and Kubernetes can use alternatives to HDFS such as Ceph, GlusterFS, Minio, (of course Amazon, Azure, ...) etc.
&lt;/p&gt;

&lt;p&gt;
So while Kubernetes was really oriented to scale application in the &lt;b&gt;Operational Information System&lt;/b&gt; space initially, it tends now to overflow to analytics use case as well.
&lt;br&gt;
And the other way around, while Hadoop is still first and foremost oriented to deploy applications in the &lt;b&gt;Analytical Information System&lt;/b&gt; space, Hadoop 3 tends to be deployed increasingly in the operational space as well.
&lt;br&gt;
Apache Mesos can well be used on both sides and was forming an interesting alternatives to Hadoop YARN in both worlds for quite some time. Today, Apache Mesos, even though from my perspective an amazing software, is not heavily maintained anymore and support for Mesos tends to vanish in latest versions of software stacks.
&lt;/p&gt;

&lt;p&gt;
Kubernetes (and/or technologies based on Kubernetes) is today a market standard for the Operational IS just as Hadoop remains a market standard for the Analytical IS.
&lt;/p&gt;


&lt;a name=&quot;sec72&quot;&gt;&lt;/a&gt;
&lt;h3&gt;7.2 Kubernetes&lt;/h3&gt;

&lt;p&gt;
Kubernetes is an Open Source Platform providing:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated software applications deployment, scaling, failover and management across cluster of nodes.&lt;/li&gt;
&lt;li&gt;Management of application runtime components as Docker containers and application units as Pods.&lt;/li&gt;
&lt;li&gt;Multiple common services required for service location, distributed volume management, etc. (pretty much everything one requires to deploy application on a Big Data cluster).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Kubernetes is originally largely inspired and even based on Google Borg, (one of) Google’s initial cluster management system(s). It has been released  as Open-Source component in Google in 2014 and the 
first official release was in 2015.
&lt;/p&gt;

&lt;p&gt;
Kubernetes is emerging as a standard as a  &lt;b&gt;Cloud Operating System&lt;/b&gt;.
&lt;br&gt;
In comes in the flavour of many distributions. The mains ones are:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PKS (Pivotal Container Service)/li&gt;
&lt;li&gt;Red-Hat OpenShift/li&gt;
&lt;li&gt;Canonical Kubernetes/li&gt;
&lt;li&gt;Google / AWS / Azure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Kubernetes deployment architecture would be as follows:
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/5593b148-4030-42a8-a170-314f8f5492ca&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Kubernetes Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/5593b148-4030-42a8-a170-314f8f5492ca&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Kubernetes Architecture&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
With the ever-growing popularity of containerized cloud-native applications, Kubernetes has become the leading orchestration platform to manage any containerized application.
&lt;br&gt;
Again, nowadays &lt;b&gt;Kubernetes&lt;/b&gt; is emerging as a market standard to scale the &lt;b&gt;Operational Information System&lt;/b&gt;, while &lt;b&gt;Hadoop&lt;/b&gt; largely remains a market standard to scale the &lt;b&gt;Analytical Information System&lt;/b&gt;.
&lt;/p&gt;



&lt;a name=&quot;sec8&quot;&gt;&lt;/a&gt;
&lt;h2&gt;8. Micro-services&lt;/h2&gt;

&lt;p&gt;
From &lt;a href=&quot;https://en.wikipedia.org/wiki/Microservices&quot;&gt;Wikipedia&lt;/a&gt;:
&lt;br&gt;
&lt;b&gt;Microservice architecture&lt;/b&gt; - a variant of the &lt;b&gt;Service-Oriented Architecture (SOA)&lt;/b&gt; structural style - arranges an application as a collection of loosely-coupled services. In a microservices architecture, services are fine-grained and the protocols are lightweight. Its characteristics are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Services in a microservices architecture (MSA) are small in size, messaging-enabled, bounded by contexts, autonomously developed, independently deployable, decentralized and built and released with automated processes.&lt;/li&gt;
&lt;li&gt;Services are often processes that communicate over a network to fulfill a goal using technology-agnostic protocols such as HTTP.&lt;/li&gt;
&lt;li&gt;Services are organized around business capabilities.&lt;/li&gt;
&lt;li&gt;Services can be implemented using different programming languages, databases, hardware and software environment, depending on what fits best (Note JKE : this is not a strict requirement, e.g. Spring boot)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
From &lt;i&gt;Martin Fowler&lt;/i&gt;:
&lt;br&gt;
A Microservices-based architecture has the following properties:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Independent services lifecycles leads to a continuous delivery software development process. A change to a small part of the application only requires rebuilding and redeploying only one or a small number of services.&lt;/li&gt;
&lt;li&gt;Adheres to principles such as fine-grained interfaces to independently deployable services, business-driven development (e.g. domain-driven design).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
As early as 2005, Peter Rodgers introduced the term &quot;Micro-Web-Services&quot; during a presentation at the Web Services Edge conference. The architectural style name was really adopted in 2012.
&lt;br&gt;
Kubernetes democratized the architectural approach. The two big players in this field are Spring Cloud and Kubernetes
&lt;/p&gt;

&lt;p&gt;
A typical micro-services infrastructure architecture would be as follows:
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/9ef528e8-40a3-42a8-8d73-db7ea47ff4d6&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 850px;&quot; alt=&quot;Micro-services infrastructure Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/9ef528e8-40a3-42a8-8d73-db7ea47ff4d6&quot; /&gt;
&lt;/a&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;Micro-services Architecture&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;a name=&quot;sec81&quot;&gt;&lt;/a&gt;
&lt;h3&gt;8.1. Micro-services discussion&lt;/h3&gt;

&lt;p&gt;
Ask yourself : do you need microservices ?
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Microservices are NOT Big Data !&lt;/b&gt;. In Big Data Analytics, one needs to scale the processing linearly with the storage. Hadoop and for instance Spark with Mesos on ElasticSearch are designed for that very key aspect to be respected: co-local processing optimization. Micro-services are not designed for this. The scaling approach in micro-services is at the component / service level. Heavy resources consuming services are scaled widely while light services run typically on a few nodes mostly for high-availability concerns. &lt;/li&gt;
&lt;li&gt;&lt;b&gt;You don’t need microservices or Kubernetes to benefit from Docker&lt;/b&gt;. Docker is a tremendous way to package and deploy applications as a whole or individual application components. Unless you need horizontal scalability and high-availability, you might not need Kubernetes or a micro-services infrastructure.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;You’re not scaling anything with synchronous calls.&lt;/b&gt; This is essential. A fundamental element in the design of a micro-services architecture resides in the usage of asynchronous calls as the communication paradigm. Think of it. If services call each others using synchronous calls, then scaling them is useless since they will all synchronize with the slowest of them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
As a consequence, don’t do microservices unless:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You &lt;b&gt;need&lt;/b&gt; independent service-level scalability (vs. storage / processing scalability - Big Data).&lt;/li&gt;
&lt;li&gt;You &lt;b&gt;need&lt;/b&gt; a strong SOA - Service-Oriented Architecture.&lt;/li&gt;
&lt;li&gt;You &lt;b&gt;need&lt;/b&gt; independent services lifecycle management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
There are various challenges to be accounted when implementing micro-services:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Distributed caching vs reloading the world all over again.&lt;/b&gt; If every service is a fully independent application, then all the reference and master data need to be reloaded all over again by all services. This needs to be accounted and distributed caching needs to be considered.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Not all applications are fit for asynchronous communications.&lt;/b&gt; Some applications require fundamentally synchronous calls.&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Identifying the proper granularity for services.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;Enterprise architecture view is too big&lt;/li&gt;
&lt;li&gt;Application architecture view is too fine&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Data consistency without distributed transactions&lt;/b&gt;. Applications need to be designed with this in mind.&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Weighting the overall memory and performance waste.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;A Spring boot stack + JVM + Linux Docker base for every single service ?&lt;/li&gt;
&lt;li&gt;HTTP calls in between layers ?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;a name=&quot;sec9&quot;&gt;&lt;/a&gt;
&lt;h2&gt;9. Conclusion&lt;/h2&gt;

&lt;p&gt;
We went a long way in this article, from the web giants and their needs to scale their information systems horizontally, the reasons behind it and the challenges this implies, down to Micro-services and the scaling of individual Information Systems components.
&lt;br&gt;
The Web giants needs were really related initially to their massive amount of data to be manipulated and the need to scale the processing linearly with the storage distribution. Nowadays, cloud computing and SaaS - Software As A Service  on the cloud form somehow a different needs.
&lt;br&gt;
Initial Big Data technologies were really oriented towards Data Analytics use cases and the Analytical Information System space. Later technologies, namely NoSQL / NewSQL and now Kubernetes and micro-services are much more oriented towards scaling or deploying on the cloud Operational Information System components
&lt;/p&gt;

&lt;p&gt;
The Strong frontier between Operational IS and Analytical IS will tend to vanish in the future.
&lt;/p&gt;
&lt;br&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/e177c115-cc09-4659-ae72-dfa906030a62&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 500px;&quot; alt=&quot;Operational / Analytical Frontier&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/e177c115-cc09-4659-ae72-dfa906030a62&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Increasingly, in Hadoop 3 with YARN able to manage and deploy docker containers, Hadoop is not so strictly limited to the Analytical IS. 
&lt;br&gt;
On the other side, Kubernetes make it increasingly feasible to scale heavy data analytics applications as well.
&lt;br&gt;
Even today NoSQL, Streaming, Lambda and Kappa architectures are increasingly overflowing to the Operational IS and as such provide a common ground for operational processes and analytical processes.
&lt;/p&gt;

</description>          </item>
    <item>
    <guid isPermaLink="true">https://www.niceideas.ch/roller2/badtrash/entry/powerful-big-data-analytics-platform</guid>
    <title>Powerful Big Data analytics platform fights financial crime in real time</title>
    <dc:creator>Jerome Kehrli</dc:creator>
    <link>https://www.niceideas.ch/roller2/badtrash/entry/powerful-big-data-analytics-platform</link>
        <pubDate>Fri, 3 Sep 2021 05:17:04 -0400</pubDate>
    <category>Big Data</category>
    <category>architecture</category>
    <category>bank</category>
    <category>banking</category>
    <category>banking-fraud</category>
    <category>big-data</category>
    <category>netguardians</category>
    <atom:summary type="html">&lt;p&gt;
&lt;i&gt;(Article initially published on &lt;a href=&quot;https://blog.netguardians.ch/powerful-big-data-analytics-platform-fights-financial-crime-in-real-time&quot;&gt;NetGuardians&apos; blog&lt;/a&gt;)&lt;/i&gt;
&lt;/p&gt;

&lt;p&gt;
NetGuardians overcomes the problems of analyzing billions of pieces of data in real time with a unique combination of technologies to offer unbeatable fraud detection and efficient transaction monitoring without undermining the customer experience or the operational efficiency and security in an enterprise-ready solution.
&lt;/p&gt;

&lt;p&gt;
When it comes to data analytics, the more data the better, right? Not so fast. That’s only true if you can crunch that data in a timely and cost-effective way.
&lt;/p&gt;

&lt;p&gt;
This is the problem facing banks looking to Big Data technology to help them spot and stop fraudulent and/or non-compliant transactions. With a window of no more than a hundredth of a millisecond to assess a transaction and assign a risk score, banks need accurate and robust real-time analytics delivered at an affordable price. Furthermore, they need a scalable system that can score not one but many thousands of transactions within a few seconds and grow with the bank as the industry moves to real-time processing.
&lt;/p&gt;

&lt;p&gt;
AML transaction monitoring might be simple on paper but making it effective and ensuring it doesn’t become a drag on operations has been a big ask. Using artificial intelligence to post-process and analyze alerts as they are thrown up is a game-changing paradigm, delivering a significant reduction in the operational cost of analyzing those alerts. But accurate fraud risk scoring is a much harder game. Some fraud mitigation solutions based on rules engines focus on what the fraudsters do, which entails an endless game of cat and mouse, staying up to date with their latest scams. By definition, this leaves the bank at least one step behind.
&lt;/p&gt;

&lt;p&gt;
At NetGuardians, rather than try to keep up with the fraudsters, we focus on what we know and what changes very little – customers’ behavior and that of bank staff. By learning “normal” behavior, such as typical time of transaction, size, beneficiary, location, device, trades, etc., for each customer and internal user, and comparing each new transaction or activity against those of the past, we can give every transaction a risk score.
&lt;/p&gt;
 
</atom:summary>        <description>&lt;p&gt;
&lt;i&gt;(Article initially published on &lt;a href=&quot;https://blog.netguardians.ch/powerful-big-data-analytics-platform-fights-financial-crime-in-real-time&quot;&gt;NetGuardians&apos; blog&lt;/a&gt;)&lt;/i&gt;
&lt;/p&gt;

&lt;p&gt;
NetGuardians overcomes the problems of analyzing billions of pieces of data in real time with a unique combination of technologies to offer unbeatable fraud detection and efficient transaction monitoring without undermining the customer experience or the operational efficiency and security in an enterprise-ready solution.
&lt;/p&gt;

&lt;p&gt;
When it comes to data analytics, the more data the better, right? Not so fast. That’s only true if you can crunch that data in a timely and cost-effective way.
&lt;/p&gt;

&lt;p&gt;
This is the problem facing banks looking to Big Data technology to help them spot and stop fraudulent and/or non-compliant transactions. With a window of no more than a hundredth of a millisecond to assess a transaction and assign a risk score, banks need accurate and robust real-time analytics delivered at an affordable price. Furthermore, they need a scalable system that can score not one but many thousands of transactions within a few seconds and grow with the bank as the industry moves to real-time processing.
&lt;/p&gt;

&lt;p&gt;
AML transaction monitoring might be simple on paper but making it effective and ensuring it doesn’t become a drag on operations has been a big ask. Using artificial intelligence to post-process and analyze alerts as they are thrown up is a game-changing paradigm, delivering a significant reduction in the operational cost of analyzing those alerts. But accurate fraud risk scoring is a much harder game. Some fraud mitigation solutions based on rules engines focus on what the fraudsters do, which entails an endless game of cat and mouse, staying up to date with their latest scams. By definition, this leaves the bank at least one step behind.
&lt;/p&gt;

&lt;p&gt;
At NetGuardians, rather than try to keep up with the fraudsters, we focus on what we know and what changes very little – customers’ behavior and that of bank staff. By learning “normal” behavior, such as typical time of transaction, size, beneficiary, location, device, trades, etc., for each customer and internal user, and comparing each new transaction or activity against those of the past, we can give every transaction a risk score.
&lt;/p&gt;
 

&lt;h2&gt;Billions of pieces of data&lt;/h2&gt;

&lt;p&gt;
To do this effectively means taking into account thousands of pieces of information every time a customer makes a transaction. Multiply that by the number of customers a bank has on its books, and it quickly gets to billions.
&lt;/p&gt;

&lt;p&gt;
Such high volumes would overwhelm most platforms, slowing the analytics to an unacceptable speed for the demands of real-time banking. At NetGuardians, we have solved this by using a combination of technologies that allows us to regularly batch process all the data for super-accurate models and supplement these batch models in real time by checking and adding smaller data sets as they arrive. This allows our software to accurately assess huge volumes of transactions in real-time.
&lt;/p&gt;

&lt;p&gt;
The technologies we use are:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apache Kafka&lt;/li&gt;
&lt;li&gt;Elasticsearch&lt;/li&gt;
&lt;li&gt;Apache Mesos&lt;/li&gt;
&lt;li&gt;Apache Spark&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
All are open-source and run on our proprietary &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/lambda-architecture-with-kafka-elasticsearch&quot;&gt;Lambda architecture&lt;/a&gt;-driven platform. Together, they make up a powerful and affordable solution for analyzing every transaction accurately in real time. In fact, our platform catches up to 99% of fraud, with 85 percent fewer false alerts, cutting investigation time by 95 percent compared with alternative rule-based solutions.
&lt;/p&gt;

&lt;p&gt;
While this is key, it’s not the best bit.
&lt;/p&gt;

&lt;p&gt;
At NetGuardians, we help our customers reap the benefits of cutting-edge and state-of-the-art open-source technologies without them suffering any of the drawbacks. We integrate these technologies, fine-tune and secure them and, critically, we implement enterprise-grade requirements on top. This means banks can use our solution out of the box.
&lt;/p&gt;
 

&lt;h2&gt;Enterprise-Ready Big Data Platform&lt;/h2&gt;

&lt;p&gt;
NetGuardians combines all the appropriate technologies in a way to make them work together 100 percent of the time, perfectly fine-tuned and secure, providing a bank everything it requires for an enterprise environment. This includes high availability, data and communication encryption, disaster recovery processes, state-of-the-art authorization, identification and authentication frameworks, single sign on, backup and restore procedures and much more. In this way, banks using our software enjoy the benefits of open source – easy integration and further development/fine-tuning – with the security and resilience of proprietary software.
&lt;/p&gt;

&lt;p&gt;
With NetGuardians, banking institutions get the best of both worlds. But the cherry on the cake is that our banks don’t have to do anything. The NetGuardians platform takes care of everything and operates itself automatically, benefitting from strong NoSQL and DevOps genes. And that is unique to us.
&lt;/p&gt;

&lt;p&gt;
Should it want to, though, a bank can create its own analytics on top of the open-source components on which the NetGuardians’ platform is built for its own use cases. A bank may want to use our version of Kafka for its own data-streaming use cases, for example, or it can open our 360 vision of the customer and user activities in ElasticSearch and expose that data through a secured API to in-house, third party software. This allows it to use the data for whatever it wants or needs to do - perhaps AML use cases or enriching the CRM application with NetGuardians’ data about customers.
&lt;/p&gt;
 

&lt;h2&gt;The future of finance is real-time payments&lt;/h2&gt;

&lt;p&gt;
Typically, many banks access the anonymized data we collect and store on our platform as a financial crime data lake to enrich their own customer 360 views in front office applications with risk indicators and a consolidated view of customers’ activities on their account. This is important because real time payments are growing fast. In 2020, 54 percent of consumers had used real-time payment app PayPal https://www.paymentsjournal.com/real-time-payments-everything-you-need-to-know/. Similar apps such as Venmo and Zelle are also growing fast – with the latter claiming 13 percent of consumers using its app in 2020, up from 1 percent in 2017.
&lt;/p&gt;

&lt;p&gt;
While retail payments are important, it’s in business that the big volumes lie and in one survey 80 percent of businesses said they wanted real time banking. Already this is translating into action - in the US, 2020 saw a fivefold increase year on year in financial institutions implementing real-time payments.
&lt;/p&gt;

&lt;p&gt;
Such huge growth means banks, big and small, will need affordable fraud detection in real time that can cope with these volumes. For the big banks, the solution will need to scale fast; for the smaller ones, they need a platform that can deliver accurate real-time risk scoring with smaller data sets. NetGuardians, with its unique combination of proprietary and open-source technologies, satisfies both. That is why banks worldwide – from Tier 1 to credit unions and co-ops – are turning to NetGuardians fraud-mitigation software to keep their customers’ cash safe.
&lt;/p&gt;

&lt;p&gt;
&lt;i&gt;(Article initially published on &lt;a href=&quot;https://blog.netguardians.ch/powerful-big-data-analytics-platform-fights-financial-crime-in-real-time&quot;&gt;NetGuardians&apos; blog&lt;/a&gt;)&lt;/i&gt;
&lt;/p&gt;
</description>          </item>
    <item>
    <guid isPermaLink="true">https://www.niceideas.ch/roller2/badtrash/entry/lambda-architecture-with-kafka-elasticsearch</guid>
    <title>Lambda Architecture with Kafka, ElasticSearch and Spark (Streaming)</title>
    <dc:creator>Jerome Kehrli</dc:creator>
    <link>https://www.niceideas.ch/roller2/badtrash/entry/lambda-architecture-with-kafka-elasticsearch</link>
        <pubDate>Fri, 4 May 2018 06:32:20 -0400</pubDate>
    <category>Big Data</category>
    <category>architecture</category>
    <category>big-data</category>
    <category>elasticsearch</category>
    <category>kafka</category>
    <category>lambda-architecture</category>
    <category>mesos</category>
    <category>spark</category>
    <atom:summary type="html">&lt;!-- Lambda Architecture with Kafka, ElasticSearch and Spark (Streaming)--&gt;

&lt;p&gt;
The Lambda Architecture, first proposed by Nathan Marz, attempts to provide a combination of technologies that together provide the characteristics of a web-scale system that satisfies requirements for availability, maintainability, fault-tolerance and low-latency.
&lt;/p&gt;

&lt;p&gt;
Quoting &lt;a href=&quot;https://en.wikipedia.org/wiki/Lambda_architecture&quot;&gt;Wikipedia&lt;/a&gt;: &quot;&lt;i&gt;Lambda architecture is a data-processing architecture designed to handle massive quantities of data by taking advantage of both batch- and stream-processing methods. 
&lt;br&gt;
This approach to architecture attempts to balance latency, throughput, and fault-tolerance by using batch processing to provide comprehensive and accurate views of batch data, while simultaneously using real-time stream processing to provide views of online data. The two view outputs may be joined before presentation. 
&lt;br&gt;
The rise of lambda architecture is correlated with the growth of big data, real-time analytics, and the drive to mitigate the latencies of map-reduce.&lt;/i&gt;&quot;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 60px; &quot; alt=&quot;Lambda Symbol&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
 
In my current company - NetGuardians - we detect banking fraud using several techniques, among which real-time scoring of transactions to compute a risk score.
&lt;br /&gt;
The deployment of Lambda Architecture has been a key evolution to help us evolve towards real-time scoring on the large scale. 
&lt;/p&gt;

&lt;p&gt;
In this article, I intend to present how we do Lambda Architecture in my company using Apache Kafka, ElasticSearch and Apache Spark with its extension Spark-Streaming, and what it brings to us.
&lt;/p&gt;
</atom:summary>        <description>&lt;!-- Lambda Architecture with Kafka, ElasticSearch and Spark (Streaming)--&gt;

&lt;p&gt;
The Lambda Architecture, first proposed by Nathan Marz, attempts to provide a combination of technologies that together provide the characteristics of a web-scale system that satisfies requirements for availability, maintainability, fault-tolerance and low-latency.
&lt;/p&gt;

&lt;p&gt;
Quoting &lt;a href=&quot;https://en.wikipedia.org/wiki/Lambda_architecture&quot;&gt;Wikipedia&lt;/a&gt;: &quot;&lt;i&gt;Lambda architecture is a data-processing architecture designed to handle massive quantities of data by taking advantage of both batch- and stream-processing methods. 
&lt;br&gt;
This approach to architecture attempts to balance latency, throughput, and fault-tolerance by using batch processing to provide comprehensive and accurate views of batch data, while simultaneously using real-time stream processing to provide views of online data. The two view outputs may be joined before presentation. 
&lt;br&gt;
The rise of lambda architecture is correlated with the growth of big data, real-time analytics, and the drive to mitigate the latencies of map-reduce.&lt;/i&gt;&quot;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 60px; &quot; alt=&quot;Lambda Symbol&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
 
In my current company - NetGuardians - we detect banking fraud using several techniques, among which real-time scoring of transactions to compute a risk score.
&lt;br /&gt;
The deployment of Lambda Architecture has been a key evolution to help us evolve towards real-time scoring on the large scale. 
&lt;/p&gt;

&lt;p&gt;
In this article, I intend to present how we do Lambda Architecture in my company using Apache Kafka, ElasticSearch and Apache Spark with its extension Spark-Streaming, and what it brings to us.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Summary&lt;/b&gt;
&lt;/p&gt;


&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec1&quot;&gt;1. Introduction&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec11&quot;&gt;1.1 NetGuardians&apos; key big data software components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec12&quot;&gt;1.2 One ring to rule them all&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec13&quot;&gt;1.3 Real-time readiness&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec2&quot;&gt;2. Lambda Architecture&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec21&quot;&gt;2.1 Lambda Architecture principles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec22&quot;&gt;2.2 Lambda Architecture with Kafka, ElasticSearch and Spark (Streaming)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec23&quot;&gt;2.3 Drawbacks and difficulties of Lambda Architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec3&quot;&gt;3. Real-time computation with Lambda Architecture&lt;/a&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec4&quot;&gt;4. Conclusion&lt;/a&gt;
&lt;/li&gt;

&lt;/ul&gt;


&lt;a name=&quot;sec1&quot;&gt;&lt;/a&gt;
&lt;h2&gt;1. Introduction&lt;/h2&gt;


&lt;a name=&quot;sec11&quot;&gt;&lt;/a&gt;
&lt;h3&gt;1.1 NetGuardians&apos; key big data software components&lt;/h3&gt;

&lt;p&gt;
NG|Screener, NetGuardians&apos; flasgship product, is a Big Data Analytics Platform aimed at preventing fraud on the large scale within Financial Institutions. 
&lt;br&gt;
Our platform manages and operates Big Data Analytics Use Cases detecting fraud attempts by analyzing user behaviours and financial transactions. Working in real-time, it can block suspicious business events, e.g financial transactions to prevent fraud effectively.
&lt;/p&gt;

&lt;p&gt;
Our platform is built internally on four key Big Data Open Source Software components:
&lt;/p&gt;


&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;Kafka Logo&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/203ed798-13b0-4d43-9f3b-4d6047ecd959&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
&lt;b&gt;Apache Kafka&lt;/b&gt;: Kafka is an open-source stream processing software aimed at providing a unified, high-throughput, low-latency platform for handling real-time data feeds.
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;ElasticSearch Logo&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/26059d4e-069e-49d1-857d-50c428591557&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
&lt;b&gt;ElasticSearch&lt;/b&gt;: ElasticSearch is a distributed, real-time, RESTful search and analytics document-oriented storage engine. It lets one perform and combine many types of searches - structured, unstructured, geo, metric - in real time.
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;Mesos Logo&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/b38d48c0-7b52-40cd-ad86-203ae0735d6d&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
&lt;b&gt;Apache Mesos&lt;/b&gt;: Mesos is a distributed systems kernel that runs on every machine and provides applications with API&apos;s for resource management and scheduling across entire datacenter and cloud environments.
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;Spark Logo&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/4c1d16c3-c660-42a3-9440-067587918a63&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
&lt;b&gt;Apache Spark&lt;/b&gt;: Spark is a fast and general engine for large-scale data processing. It provides programmers with an API functioning as a working set for distributed programs that offers a versatile form of distributed shared memory.
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;a name=&quot;sec12&quot;&gt;&lt;/a&gt;
&lt;h3&gt;1.2 One ring to rule them all&lt;/h3&gt;

&lt;p&gt;
The choice of these specific components under the hood is not anecdotal. Running Apache Spark on Apache Mesos is really still cutting edge nowadays and the choice of Apache Kafka and ElasticSearch, in addition to the good fit with our use case, answers a very important need we have.
&lt;/p&gt;

&lt;p&gt;
We deploy our platform as much in tier 1 banks and big financial services providers than small private banks in Switzerland or even small Credit Institutions in Africa. Some of our customers have a few thousands of transactions daily while some others have dozens of millions of transactions per day. 
&lt;br&gt;
Considering that some of our Analytics use cases require depth of analysis of several years, when we have billions of events to consider, we deploy our analytics platform on multiple-nodes clusters, sometimes up to a few dozen computation and storage nodes within the cluster. On the other hand, when we we work for small institutions with very low data volumes, we deploy it on a single small machine.
&lt;br&gt;
This need is at the very root of our technology choice, we needed technologies able to run efficiently on single small machines while still being able to scale our on hundreds of nodes should we require that.
&lt;/p&gt;

&lt;p&gt;
ElasticSearch, Apache Spark, Apache Mesos and Apache Kaflka have been designed from the grounds up with this horizontal scalability in mind. But they have been implemented in such a way that they run also very well on a single little machine. 
&lt;br&gt;
This is pretty uncommon in the Big Data Technology / NoSQL family of products. For instance, Apache Hadoop performs most of the time very poorly on single machines.
&lt;/p&gt;

&lt;p&gt;
These products under the hood are key to sustain our &quot;&lt;i&gt;one ring to rule them all&lt;/i&gt;&quot; approach. We develop one single platform that we can deploy everywhere, regardless of the volume of data of our customers.
&lt;/p&gt;

&lt;a name=&quot;sec13&quot;&gt;&lt;/a&gt;
&lt;h3&gt;1.3 Real-time readiness&lt;/h3&gt;

&lt;p&gt;
In addition to their unique genes regarding vertical scalability described above, ElasticSearch, Apache Kafka and Apache Spark are providing our platform with another key feature.
&lt;/p&gt;

&lt;p&gt;
With ElasticSearch, real-time updating (fast indexing) is achievable through various functionalities and search / read response time can be astonishingly deterministic.
&lt;/p&gt;

&lt;p&gt;
Apache Kafka comes with the Kafka Stream extension. The Streams API, available as a Java library that is part of the official Kafka project, is the easiest way to write mission-critical real-time applications and microservices with all the benefits of Kafka&apos;s server-side cluster technology. 
&lt;br&gt;
Despite being a humble library, Kafka Streams directly addresses both hardest problems in stream processing: 
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;event-at-a-time processing with millisecond latency and &lt;/li&gt;
&lt;li&gt;stateful processing including distributed joins and aggregations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Kafka enables to implement fast processing on business events, e.g most often financial transactions in real-time and in event-at-a-time mode while dispatching micro-batches further to Spark Streaming.
The more complicated processing required by our Analytics use cases occurs then within Spark through the Spark Streaming extension.
&lt;/p&gt;

&lt;p&gt;
Spark Streaming is able to process hundreds of thousands of records per node per second. When using Kafka as a source, it is able to consume nearly half million records per node per second which is striking. It also offers near linear scaling ability, another great perk. 
&lt;br&gt;
In contrary to Kafka, Spark Streaming works using a micro-batches approach. It works as follows; received input streams and decided into small batches, which are processed by Spark engine and a processed stream of batches is return. 
&lt;br&gt;
The micro-batches can be as small as a few milliseconds batches, thus enabling sub-second latency while still ensuring a very high throughput and access to the whole Spark power and versatility to implement high level analytics use cases.
&lt;/p&gt;

&lt;p&gt;
This real-time readiness aspect of these components of our technology stack is key to deploy Lambda Architecture within the our platform.
&lt;/p&gt;

&lt;a name=&quot;sec2&quot;&gt;&lt;/a&gt;
&lt;h2&gt;2. Lambda Architecture&lt;/h2&gt;

&lt;p&gt;
When it comes to processing transactions in real-time, our platform provides a state-of-the-art implementation of a Lambda Architecture.
 &lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 60px; &quot; alt=&quot;Lambda Symbol&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Lambda architecture is a Big Data Architecture that enables us to reunite our real-time and batch analytics layers.
&lt;/p&gt;


&lt;a name=&quot;sec21&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.1 Lambda Architecture principles&lt;/h3&gt;

&lt;p&gt;
Lambda architecture is a data-processing architecture designed to handle massive quantities of data by taking advantage of both batch- and stream-processing methods. This approach to architecture attempts to balance latency, throughput, and fault-tolerance by using batch processing to provide comprehensive and accurate views of batch data, while simultaneously using real-time stream processing to provide views of online data.
&lt;/p&gt;

&lt;p&gt;
At a high level, the Lambda Architecture is designed to handle both real-time and historically aggregated batched data in an integrated fashion. It separates the duties of real-time and batch processing so purpose-built engines, processes, and storage can be used for each, while serving and query layers present a unified view of all of the data. 
&lt;br&gt;
The rise of lambda architecture is correlated with the growth of big data and real-time analytics.
&lt;/p&gt;


&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px; &quot; alt=&quot;Lambda Architecture&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/f36e9948-0053-4f07-a0ff-a1ebca0b5762&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
As new data is introduced to the system, it is processed simultaneously by both the batch layer, and the speed layer. The batch layer is an append-only repository containing unprocessed raw data. The batch layer periodically or continuously runs jobs that create views of the batch data-aggregations or representations of the most up-to-date versions. These batch views are sent to the serving layer, where they are available for analytic queries.
&lt;br&gt;
At the same time that data is being appended to the batch layer, it is simultaneously streaming into the speed layer. The speed layer is designed to allow queries to reflect the most up-to-date information-necessary because the serving layer&apos;s views can only be created by relatively long-running batch jobs. The speed layer computes only the data needed to bring the serving layer&apos;s views to real time-for instance, calculating totals for the past few minutes that are missing in the serving layer&apos;s view.
&lt;br&gt;
By merging data from the speed and serving layers, low latency queries can include data that is based on computationally expensive batch processing, and yet include real-time data.
In the Lambda Architecture, the raw source data is always available, so redefinition and re-computation of the batch and speed views can be performed on demand. The batch layer provides a big data repository for machine learning and advanced analytics, while the speed and serving layers provide a platform for real-time analytics.
&lt;br&gt;
The Lambda Architecture provides a useful pattern for combining multiple big data technologies to achieve multiple enterprise objectives.
&lt;/p&gt;

&lt;a name=&quot;sec22&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.2 Lambda Architecture with Kafka, ElasticSearch and Spark (Streaming)&lt;/h3&gt;

&lt;p&gt;
Lambda defines a big data architecture that allows pre-defined and arbitrary queries and computations on both fast-moving data and historical data.
&lt;br&gt;
Using Kafka, ElasticSearch, Spark and SparkStreaming, it is achieved using the following layout:
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/a63d7668-8d45-47ec-a2f5-57eb64eb6b00&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 800px; &quot; alt=&quot;Lambda Architecture - Software Components&quot; src=&quot;https://www.niceideas.ch/roller2/badtrash/mediaresource/45ee2683-eb9f-4698-aea4-de5c18620c40&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Lambda Architecture enables us to score transactions or other business events in real-time and still consider the most recent events as well as the whole transaction history in its scoring model.
&lt;/p&gt;

&lt;p&gt;
By using Kafka at the beginning of the pipeline to accept inputs, it can be guaranteed that messages will be delivered as long as they enter the system, regardless of hardware or network failure.
&lt;/p&gt;

&lt;p&gt;
The batch layer is largely build on the Apache Spark / Mesos coupled with ElasticSearch as large scale storing component underneath. The reasons why we are running on Spark, Mesos and ElasticSearch have been covered before in this document but interestingly, these components appear to behave extremely well together when it comes to addressing batch processing concerns, thanks to spark&apos;s ability to work largely in memory and proper optimization of data co-locality on ElasticSearch and Spark nodes.
&lt;/p&gt;

&lt;p&gt;
In the streaming layer, Kafka messages are consumed in real time using Spark Streaming. In terms of core component to support the speed layer, the usual choice is between Apache Storm or Apache Spark Streaming. 
The main selection criteria between the two depends on whether one is interested in ultra low latency (Apache Storm) or high throughput (Apache Spark Streaming). There are other factors, but these are some of the main drivers.
&lt;br&gt;
In my company, for our use cases, we can afford a little higher latency as long as we work under a second to score a business event (e.g. financial transaction). On the other hand, we face situations where burst of thousands of transactions to be scored per second are common. As such, high throughput is not optional for us, it&apos;s a key requirement and as such, the rationality behind the usage of Apache Spark Streaming.
&lt;br&gt;
Here, in the speed layer, ElasticSearch is key to reduce latency of integration concerns of the speed layers since it is a real-time querying database in addition to a very powerful database engine. 
&lt;/p&gt;

&lt;p&gt;
The Serving Layer, consolidating the batch layer and speed layer partial results, is largely home made in our case and relies on ElasticSearch&apos;s ability to fetch both partial sets in real-time.
&lt;/p&gt;

&lt;a name=&quot;sec23&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.3 Drawbacks and difficulties of Lambda Architecture&lt;/h3&gt;

&lt;p&gt;
There is a natural tendency to duplicate logic between batch layer and speed layer which needs to be addressed through strict design and re-usable logic. Using Spark in batch mode on the batch layer and Spark Streaming on the speed layer in our case really helps us reuse business logic as much as possible between both worlds.
&lt;/p&gt;
&lt;p&gt;
In addition, there is an operational complexity of the systems that are involved in implementing the lambda architecture. Thus the implementation of Lambda architecture is inherently difficult.
&lt;/p&gt;


&lt;a name=&quot;sec3&quot;&gt;&lt;/a&gt;
&lt;h2&gt;3. Real-time computation with Lambda Architecture&lt;/h2&gt;

&lt;p&gt;
The demand for real-time analytics has led to demand for workflows that can effectively balance latency, throughput, scaling and fault tolerance.
&lt;br&gt;
In order to accommodate the demand for real-time analytics, we need to design a system that can provide balance between the concept of &quot;single version of truth&quot; and &quot;real-time analytics&quot;. Lambda Architecture is one such method.
&lt;/p&gt;

&lt;p&gt;
In my company, some of our analytics use cases require to consider very extended contextual information about trade and transaction activities, for instance, to build user and customer profiles or analyze their past behaviours. 
&lt;br&gt;
Building such contextual information typical require analyzing over again and again billions of business events and peta-bytes of data. 
&lt;br&gt;
Rebuilding these profiles or re-creating the aggregated statistical metrics would require several dozens of minutes even on large cluster in a typical batch processing approach.
&lt;br&gt;
Happily, all this information supports an incremental building way and as such we can benefit from Lambda architecture to rebuild the historical part while the latest data is taken into consideration by the speed layer to provide an up-to-date (as far as real-time) view of the reality. The serving layer consolidates both results to provide always up-to-date and accurate views of these profiles or other aggregated statistical metrics.
&lt;br&gt;
These real-time metrics are thus made available to our real-time scoring and classification systems.
&lt;/p&gt;

&lt;p&gt;
The same technologies and approaches deployed in the speed layer to provide up-to-date views of the reality are used to score and classify business events, e.g. financial transactions in real-time.
&lt;br&gt;
Here as well, we have no requirements for strong real-time with millisecond-order latency. As long as we can provide a risk score or a classification for an event under a second, this is sufficient for our use cases.
&lt;br&gt;
On the other hand, it happens often that we have to compute burst of events of several hundreds of entries per second. As such, a system benefiting from an acceptable latency but a very high throughput such as Apache Spark Streaming is a key component of our processing platform.
&lt;/p&gt;

&lt;p&gt;
In addition, within NG|Screener UI we provide our customers with a full-blend data discovery application (forensic application). Lambda Architecture is key in enabling us to provide our users with real-time updates and a second close up-to-date view of the reality.
&lt;/p&gt;

&lt;a name=&quot;sec4&quot;&gt;&lt;/a&gt;
&lt;h2&gt;4. Conclusion&lt;/h2&gt;


&lt;p&gt;
Deploying Lambda architecture on our use cases has proven to be the simplest way to reach our objectives:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Up to date and second-close view of the reality in contextual information, user / customer profiles and other key periodic statistical metrics&lt;/li&gt;
&lt;li&gt;Classification and scoring of business events with an under-a-second latency and a very high throughput&lt;/li&gt;
&lt;li&gt;Resilience and fault tolerance of our business processes on large clusters, both on technical failures and human failures&lt;/li&gt;
&lt;li&gt;Simplicity and maintenance, especially in our approach since we can share significant portions of codes between the batch layer and the speed layer since both are built on Apache Spark&lt;/li&gt;
&lt;li&gt;Resolution of operational complexity of big computation on historical data by dividing the work to do in an incremental fashion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Now of course, Lambda Architecture being the simplest way for us to reach our mission-critical objectives doesn&apos;t make it simple per se, on the contrary. Lambda Architecture is inherently difficult to deploy and maintain and requires sound design and implementation. 
&lt;/p&gt;
&lt;p&gt;
At NetGuardians, we could benefit from our mastery of cutting-edge technologies as well as our in-depth experience of batch computing systems and real-time computing systems to make it an advantage of our approach.
&lt;/p&gt;


</description>          </item>
    <item>
    <guid isPermaLink="true">https://www.niceideas.ch/roller2/badtrash/entry/video-of-jerome-kehrli-presenting</guid>
    <title>Presenting NetGuardians&apos; Big Data technology (video)</title>
    <dc:creator>Jerome Kehrli</dc:creator>
    <link>https://www.niceideas.ch/roller2/badtrash/entry/video-of-jerome-kehrli-presenting</link>
        <pubDate>Fri, 5 Jan 2018 13:00:00 -0500</pubDate>
    <category>Big Data</category>
    <category>bank</category>
    <category>banking</category>
    <category>big-data</category>
    <category>netguardians</category>
    <category>video</category>
    <atom:summary type="html">&lt;p&gt;
I am presenting in this video NetGuardians&apos; Big Data approach, technologies and its advantages for the banking institutions willing to deploy big data technologies for Fraud Prevention.
&lt;/p&gt;

    &lt;!-- 1. The &lt;iframe&gt; (and video player) will replace this &lt;div&gt; tag. --&gt;
    &lt;div id=&quot;player&quot; style=&quot;max-width: 100%;&quot;&gt;&lt;/div&gt;

    &lt;script&gt;
      // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement(&apos;script&apos;);

      tag.src = &quot;https://www.youtube.com/iframe_api&quot;;
      var firstScriptTag = document.getElementsByTagName(&apos;script&apos;)[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

      // 3. This function creates an &lt;iframe&gt; (and YouTube player)
      //    after the API code downloads.
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player(&apos;player&apos;, {
          height: &apos;360&apos;,
          width: &apos;640&apos;,
          videoId: &apos;wxESC2PCwp4&apos;,
          events: {
            &apos;onReady&apos;: onPlayerReady,
            &apos;onStateChange&apos;: onPlayerStateChange
          }
        });
      }

      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        //event.target.playVideo();
      }

      // 5. The API calls this function when the player&apos;s state changes.
      //var done = false;
      function onPlayerStateChange(event) {
        /*
        if (event.data == YT.PlayerState.PLAYING &amp;&amp; !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
        */
      }
/*
      function stopVideo() {
        player.stopVideo();
      }
*/
    &lt;/script&gt;

&lt;p&gt;
The speech is reported in textual form hereafter.
&lt;/p&gt;
</atom:summary>        <description>&lt;p&gt;
I am presenting in this video NetGuardians&apos; Big Data approach, technologies and its advantages for the banking institutions willing to deploy big data technologies for Fraud Prevention.
&lt;/p&gt;

    &lt;!-- 1. The &lt;iframe&gt; (and video player) will replace this &lt;div&gt; tag. --&gt;
    &lt;div id=&quot;player_1231346&quot; style=&quot;max-width: 100%;&quot;&gt;&lt;/div&gt;

    &lt;script&gt;

        player = new YT.Player(&apos;player_1231346&apos;, {
          height: &apos;360&apos;,
          width: &apos;640&apos;,
          videoId: &apos;wxESC2PCwp4&apos;
        });

    &lt;/script&gt;

&lt;p&gt;
The speech is reported in textual form hereafter.
&lt;/p&gt;

&lt;p&gt;
It keeps puzzling me to see how deploying Big Data Technologies in banking institutions for fraud prevention and other use cases seems to be so difficult.
&lt;br&gt;
A large number of such projects have simply failed over the past.
&lt;br&gt;
By failure I mean projects that, led to poor results, or exceeded the budget significantly, or even that have been simply cancelled.
&lt;/p&gt;

&lt;p&gt;
When looking at why these projects failed, it always boils down to the two same major issues.
 &lt;/p&gt;

&lt;p&gt;
The first major issue is that extracting the required data to build the analytics use cases is a challenge on its own. 
Let&apos;s say the bank managed to extract the required data, which is only a technical problem, but cleaning, enriching, normalizing and re-modeling it for banking fraud use cases is a whole new project.
 &lt;/p&gt;

&lt;p&gt;
The second major issue is that technological mastery alone is not sufficient for Big Data projects to succeed. 
&lt;br&gt;
Implementing data analytics use cases requires a strong involvement from business experts. 
&lt;br&gt;
It always amazes me to see so many projects had the illusion that putting a dozen of gifted Data Scientists in a room for a few years would be sufficient. Without a clear business understanding, Data Scientists are blind and can go nowhere.
 &lt;/p&gt;

&lt;p&gt;
And then even with a clear understanding of these both challenges, deploying big data technologies for fraud prevention is a 10 months to 2 years project. 
At NetGuardians we typically deploy our technology at our new customers within a few weeks.
&lt;/p&gt;

&lt;p&gt;
So how do we do that ?
&lt;/p&gt;

&lt;p&gt;
First, we are using technology on the bleeding edge of the state of the art, not today&apos;s state of the art but tomorrow&apos;s, benefiting from the right data extraction approach and the right use cases.
&lt;/p&gt;

&lt;p&gt;
In terms of technology, our NG|Screener platform is using key big data components underneath: ElasticSearch, Mesos and Spark.
&lt;/p&gt;

&lt;p&gt;
Regarding the Data Ingestion System, we have developed at NetGuardians our Data Collection Framework that is simple, efficient and configurable.
&lt;br&gt;
Typical data extraction tools are either simple, or efficient or configurable. Our framework is all of that together, without any compromises.
 &lt;/p&gt;

&lt;p&gt;
Then, working with numerous financial institutions worldwide over the years made us understand the indispensable role of not only technology but also business expertise when it comes to developing Big Data analytics use cases.
 &lt;/p&gt;

&lt;p&gt;
Business experts in banking institutions are only hardly available, right ?
&lt;br&gt;
Not a problem for us, we have hired our own.
&lt;br&gt;
Today, we have our own business and risk experts with an impressive trackrecord in risk or other banking business departments.
 &lt;/p&gt;

&lt;p&gt;
At NetGuardians, we have this multi-competencies team that so many project struggle to build and together, we have designed and implemented the right use cases to make Big Data deployment projects happen smoothly at our customers, and bring them actual added value.
 &lt;/p&gt;

&lt;p&gt;
As a result, our customers are able to make sense of their available Big Data, save enormous amount of time, and implement the Big Data technology to proactively prevent growing fraud challenges.
 &lt;/p&gt;

&lt;p&gt;
From a personal perspective, I am utmost proud of what we have built, both in terms of technology and approach, as well as the privilege I have to work in a team with such brilliant minds and wonderful persons.
&lt;/p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2</guid>
    <title>ELK-MS - ElasticSearch/LogStash/Kibana - Mesos/Spark : a lightweight and efficient alternative to the Hadoop Stack - part III : so why is it cool ?</title>
    <dc:creator>Jerome Kehrli</dc:creator>
    <link>https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2</link>
        <pubDate>Wed, 30 Aug 2017 16:43:44 -0400</pubDate>
    <category>Big Data</category>
    <category>big-data</category>
    <category>elasticsearch</category>
    <category>elk</category>
    <category>elk-ms</category>
    <category>kibana</category>
    <category>logstash</category>
    <category>mesos</category>
    <category>spark</category>
    <atom:summary type="html">&lt;p&gt;
So, finally the conclusion of this serie of three articles, the big conclusion, where I intend to present why this ELK-MS, ElasticSearch/LogStash/Kibana - Mesos/Spark, stack is cool.
&lt;br&gt;
Without any more waiting, let&apos;s give the big conclusion right away, using ElasticSearch, Mesos and Spark can really distribute and scale the processing the way we want and very easily &lt;b&gt;scale the processing linearly with the amount of data to process&lt;/b&gt;.
&lt;br&gt;
And this, exactly this and nothing else, is very precisely what we want from a Big Data Processing cluster.
&lt;/p&gt;
&lt;p&gt;
At the end of the day, we want a system that books a lot of the resources of the cluster for a job that should process a lot of data and only a small subset of these resources for a job that works on a small subset of data.
&lt;br&gt;
And this is precisely what one can achieve pretty easily with the ELK-MS stack, in an almost natural and straightforward way.
&lt;br&gt;
I will present why and how in this article.
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 400px; &quot; alt=&quot;ELK-MS Data Architecture&quot; src=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana&quot;&gt;The first article - ELK-MS - part I : setup the cluster&lt;/a&gt; in this serie presents the ELK-MS stack and how to set up a test cluster using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS.tar.gz&quot;&gt;niceideas ELK-MS package&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;The second article - ELK-MS - part II : assessing behaviour&lt;/a&gt; presents a few concerns, assesses the expected behaviour using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS_TEST.tar.gz&quot;&gt;niceideas ELK-MS TEST package&lt;/a&gt; and discusses challenges and constraints in this ELK-MS environment.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2&quot;&gt;This third and last article - ELK-MS - part III : so why is it cool?&lt;/a&gt; presents, as indicated, why this ELK-MS stack is really really cool and works great.
&lt;/p&gt;
&lt;p&gt;
This article assumes a basic understanding of Big Data / NoSQL technologies in general by the reader.
&lt;/p&gt;</atom:summary>        <description>&lt;!-- ELK-MS - ElasticSearch/LogStash/Kibana - Mesos/Spark : a lightweight and efficient alternative to the Hadoop Stack - part III : so why is it cool ? --&gt;


&lt;p&gt;&lt;i&gt;
&lt;b&gt;Edited 2017-10-30&lt;/b&gt;: I was using ES 5.0.0 with Spark 2.2.0 at the time of writing the initial version of this article. 
&lt;br&gt;
With ElasticSearch 6.x, and ES-Hadoop 6.x, the game changes a little. The Spark 2.2.0 Dynamic allocation system is now perfectly compatible with the way ES-Hadoop 6.x enforces data locality optimization and everything works just as expected.
&lt;/i&gt;
&lt;/p&gt;

&lt;p&gt;
So, finally the conclusion of this serie of three articles, the big conclusion, where I intend to present why this ELK-MS, ElasticSearch/LogStash/Kibana - Mesos/Spark, stack is really really cool.
&lt;br&gt;
Without any more waiting, let&apos;s give the big conclusion right away, using ElasticSearch, Mesos and Spark can really distribute and scale the processing the way we want and out of the box /(using Dynamic Allocation) &lt;b&gt;scale the processing linearly with the amount of data to process&lt;/b&gt;.
&lt;br&gt;
And this, exactly this and nothing else, is very precisely what we want from a Big Data Processing cluster.
&lt;/p&gt;
&lt;p&gt;
At the end of the day, we want a system that books a lot of the resources of the cluster for a job that should process a lot of data and only a small subset of these resources for a job that works on a small subset of data, with a strong enforcement of data locality optimization.
&lt;br&gt;
And this is precisely what one can achieve pretty easily with the ELK-MS stack, in an almost natural and straightforward way.
&lt;br&gt;
I will present why and how in this article.
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 400px; &quot; alt=&quot;ELK-MS Data Architecture&quot; src=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana&quot;&gt;The first article - ELK-MS - part I : setup the cluster&lt;/a&gt; in this serie presents the ELK-MS stack and how to set up a test cluster using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS.tar.gz&quot;&gt;niceideas ELK-MS package&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;The second article - ELK-MS - part II : assessing behaviour&lt;/a&gt; presents a few concerns, assesses the expected behaviour using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS_TEST.tar.gz&quot;&gt;niceideas ELK-MS TEST package&lt;/a&gt; and discusses challenges and constraints in this ELK-MS environment.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2&quot;&gt;This third and last article - ELK-MS - part III : so why is it cool?&lt;/a&gt; presents, as indicated, why this ELK-MS stack is really really cool and works great.
&lt;/p&gt;
&lt;p&gt;
This article assumes a basic understanding of Big Data / NoSQL technologies in general by the reader.
&lt;/p&gt;
&lt;p&gt;


&lt;b&gt;Summary&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec1&quot;&gt;1. Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec2&quot;&gt;2. Data locality and workload distribution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec3&quot;&gt;3. Examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec4&quot;&gt;4. Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;a name=&quot;sec1&quot;&gt;&lt;/a&gt;
&lt;h2&gt;1. Introduction &lt;/h2&gt;

&lt;p&gt;
The reader might want to refer to the &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana#sec1&quot;&gt;Introduction of the first article in the serie&lt;/a&gt; as well as &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1#sec1&quot;&gt;the introduction of the second article&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Summarizing them, this series of article is about presenting and assessing the ELK-MS stack, the tests done using the test cluster and present the conclusion, in terms of constraints as well as key lessons.
&lt;br&gt;
The second article was presenting the technical constraints coming from integrating Spark with ElasticSearch through the ES-Hadoop connector when running Spark on Mesos.
&lt;br&gt;
In this second article I focused a lot on what was not working and what were the constraints. A reader might have had the impression that these constraints could prevent a wide range of use cases on the ELK-MS stack. I want to address this fear in this third article since this is all but true, Spark on Mesos using data from ElasticSearch is really a pretty versatile environment and can address most if not all data analysis requirements.
&lt;/p&gt;
&lt;p&gt;
In this last article, I will present how one can use a sound approach regarding data distribution in ElasticSearch to drive the distribution of the workload on the Spark cluster.
&lt;br&gt;
And it turns out that it&apos;s pretty straightforward to come up with a simple, efficient and natural approach to control the workload distribution using ElasticSearch, Spark and Mesos.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;ES index layout strategies&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
The parameters that architects and developers need to tune to control the data distribution on ElasticSearch, which, in turn, controls the workload distribution on spark, are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;b&gt;index splitting&lt;/b&gt; strategy&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;index sharding&lt;/b&gt; strategy&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;replication&lt;/b&gt; strategy (factor)&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;sharding key&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Spark aspects&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Then on the spark side the only important aspect is to use a proper version of ES-Hadoop supporting the Dynamic Allocation System without compromising data locality optimization (i.e ES-Hadoop &gt;= 6.x for Spark 2.2)
&lt;/p&gt;

&lt;p&gt;
But before digging into this, and if that is not already done before, I can only strongly recommend reading the &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana&quot;&gt;the first article&lt;/a&gt; in this serie, related presenting the ELK-MS stack and &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;the second article&lt;/a&gt; which presents the conclusions required to understand what will follow.
&lt;/p&gt;


&lt;a name=&quot;sec2&quot;&gt;&lt;/a&gt;
&lt;h2&gt;2. Data locality and workload distribution&lt;/h2&gt;

&lt;p&gt;
What has been presented in &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1#sec3&quot;&gt;the conclusion section of the ELK-MS part II article&lt;/a&gt; is summarized hereunder:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Fine Grained scheduling mode of spark jobs by Mesos screws performances up to an unacceptable level. ELK-MS need to stick to &lt;b&gt;Coarse-Grained&lt;/b&gt; scheduling mode.
&lt;/li&gt;
&lt;li&gt;
ES-Hadoop is able to enforce data-locality optimization under nominal situations. Under a heavily loaded cluster, data-locality optimization can be compromised for two reasons:
&lt;ul&gt;
&lt;li&gt;
If the local Mesos / Spark node to a specific ES node is not available after the configured waiting time, the processing will be moved to another free Mesos / Spark node.
&lt;/li&gt;
&lt;li&gt;
ElasticSearch can well decide to serve the request from another node should the local ES node be busy at the time it is being requested by the local spark node.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
With ES-Hadoop 5.x, Dynamic allocation was messing up data locality optimization between ES and Spark. As such only Static allocation was usable and it was required to limit artificially the amount of nodes for a given job in good correspondance to the amount of shards in ES (usage of property &lt;code&gt;spark.cores.max&lt;/code&gt; to limit the amount of spark executors and the  &lt;code&gt;search_shards&lt;/code&gt; API in ES to find out about the amount of shards to be processed)
&lt;br&gt;
&lt;b&gt;But now with ES-Hadoop 6.x, Dynamic allocation doesn&apos;t interfere with data locality optimization  and everything works well out of the box.&lt;/b&gt;
&lt;/li&gt;
&lt;li&gt;
Re-distributing the data on the cluster after the initial partitioning decision is only done by spark under specific circumstances.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;ES-Hadoop drives spark partitioning strategy&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;
So what happens with ES-Hadoop 6.x and dynamic allocation is that ElasticSearch sharding strategy drives the partitionning strategy of corresponding data frames in Spark. With Data Locality Optimization kicking in, even with Dynamic Allocation enabled, The Spark / Mesos cluster will do its best to create the Spark partitions on the nodes where the ES shards are located.
&lt;br&gt;
And this really works just out of the box.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Eventually, there will be just as many executors booked by Mesos / Spark on the cluster as is requiredto handle every ES shars in a dedicated, co-located partition within Spark.&lt;/b&gt;
&lt;/p&gt;


&lt;a name=&quot;sec3&quot;&gt;&lt;/a&gt;
&lt;h2&gt;3. Examples&lt;/h2&gt;

&lt;p&gt;
In order to illustrate why I believe that in fact the way ELK-MS behaves when it comes to distributing the workload following the distribution of the data is &lt;i&gt;efficient and natural&lt;/i&gt;, we&apos;ll use the examples below.
&lt;/p&gt;
&lt;p&gt;
Imagine the following situation: the ELK-MS test cluster contains 6 nodes with similar configurations. The dataset to be stored is called &lt;code&gt;dataset&lt;/code&gt; and contains 2 months of data.
&lt;br&gt;
In ElasticSearch the indexing settings are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
The &lt;b&gt;Index splitting strategy&lt;/b&gt; is &lt;b&gt;by month&lt;/b&gt;. This is not strictly an ElasticSearch setting, this is configured in Logstash or any other data ingestion tool.
&lt;br&gt;
As a matter of fact, whenever one wants to store temporal data in ElasticSearch (timeseries), one naturally considers splitting the index by year, month or even day depending on the size of the dataset.
&lt;/li&gt;
&lt;li&gt;
The &lt;b&gt;sharding strategy&lt;/b&gt; consists in creating 3 shards.
&lt;/li&gt;
&lt;li&gt;
The &lt;b&gt;replication strategy&lt;/b&gt; consists in creating 2 replicas (meaning 1 primary shard and 2 replicas).
&lt;/li&gt;
&lt;li&gt;
We do not care about configuring the &lt;i&gt;sharding key&lt;/i&gt; any differently than the default for now (a few words on the sharding key configuration are given in the conclusion).
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Initial situation&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
We can imagine that the above situation ends up in the following data layout on the cluster. (One should note though that this is not very realistic since ES would likely not split both month this way when it comes to storing replicas):
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data_empty.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 500px; &quot; alt=&quot;Data Architecture nominal situation&quot; src=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data_empty.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Working on a small subset of data for one month&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Now let&apos;s imagine that we write a processing script in spark that fetches a small subset of the data of one month, June 2017, so [A] here.
&lt;/p&gt;
&lt;p&gt;
In addition, imagine that the filter ends up identifying precisely the data from a single shard of the index. Spark / Mesos would create in this case a single spark partition on the node co-located to the ES shard.
&lt;/p&gt;
&lt;p&gt;
The processing happens this way in this case:
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data_subset.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 500px; &quot; alt=&quot;Data Architecture working on subset&quot; src=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data_subset.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Since only one shard needs to be read from ElasticSearch, ES-Hadoop will drive the creation of a single partition in the resulting DataFrame (or RDD), which in turn will cause Spark to request a single task in one executor, the one local to the ES shard.
&lt;/p&gt;
&lt;p&gt;
So what actually happens is that working on a single shard located on single ES node will actually drive spark in a way to make it work on one single node as well.
&lt;br&gt;
Using replicas has the benefits to give the Mesos / Spark cluster some choice in regards to which this node should be. This is especially important if the cluster is somewhat loaded.
&lt;/p&gt;
&lt;p&gt;


&lt;b&gt;Working on a single month of data&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;

In this second example, the processing script works on a single month of data, the full month of June 2017, so all shards of [A] here.
&lt;/p&gt;
&lt;p&gt;
This will drive Spark to create 3 corresponding partitions on the Mesos / Spark cluster.
&lt;br&gt;
The processing works as follows in this case:
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data_1_month.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 500px; &quot; alt=&quot;Data Architecture working on full month&quot; src=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data_1_month.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
Three shards from ES need to be fetched to Spark. ES-Hadoop will create 3 partitions which leads to 3 tasks to be dispatched on the Spark processing stage. These 3 tasks will be executed on the 3 local ES nodes owning the shards.
&lt;/p&gt;
&lt;p&gt;
Again, distributing the input data on one third of the ES cluster on one side, and limiting&apos;s Spark resources to the actual number of nodes required on the other side, leads to one third of the Spark cluster to be used for the spark processing. 
&lt;br&gt;
In this case, the ElasticSearch data distribution strategy drives the workload distribution on spark.
&lt;br&gt;
Again replication is useful to ensure a successful distribution even under a loaded cluster.
&lt;/p&gt;


&lt;p&gt;
&lt;b&gt;Working on the whole period&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
This will drive spark to create partitions on all nodes of the cluster.
&lt;br&gt;
The processing happens this way:
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 500px; &quot; alt=&quot;Data Architecture working on both months&quot; src=&quot;https://www.niceideas.ch/es_spark/images/big_archi_data.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
When working on the whole period, it happens fortunately in this case that we end up fetching shards from the whole ES cluster, in this case the whole spark cluster will be used to distribute the processing workload, since each and every local spark node will need to work on the local ES shard.
&lt;/p&gt;
&lt;p&gt;
Again, one last time, &lt;b&gt;the ElasticSearch data distribution strategy drives the workload distribution in good understanding to the data distribution, enforcing data-locality optimization.&lt;/b&gt;
&lt;/p&gt;



&lt;a name=&quot;sec4&quot;&gt;&lt;/a&gt;
&lt;h2&gt;4. Conclusion&lt;/h2&gt;

&lt;p&gt;
In conclusion, having the ElasticSearch data distribution strategy driving the processing distribution on the Mesos / Spark cluster, thanks to the ES-Hadoop connector requirements given to spark, makes a lot of sense if you think of it.
&lt;/p&gt;
&lt;p&gt;
First it&apos;s &lt;b&gt;simple and consistent&lt;/b&gt;. One can understand how the first stages of processing will occur within spark by simply looking at the data distribution using for instance Cerebro. Everything is well predictable and straightforward to assess.
&lt;/p&gt;
&lt;p&gt;
But more importantly, it&apos;s &lt;b&gt;efficient&lt;/b&gt; since, well, whenever we store data in ElasticSearch, we think of the distribution strategy, in terms of index splitting, sharding and replication precisely for the single purpose of performance. 
&lt;br&gt;
Creating too many indexes and shards, more that the amount of nodes, would be pretty stupid since having more than X shards to read per node, where X is the amount of CPUs available to ES on a node, leads to poor performances. As such, the highest limit is the amount of CPUs in the cluster. Isn&apos;t it fortunate that this is also the limits we want in such case for our spark processing cluster?
&lt;br&gt;
On the other hand, when one wants to store a tiny dataset, a single index and a single shard is sufficient. In this case, a processing on this dataset would also use a single node in the spark cluster. Again that is precisely what we want.
&lt;/p&gt;
&lt;p&gt;

In the end, one &lt;i&gt;&quot;simply&quot;&lt;/i&gt; needs to optimize his ElasticSearch cluster and the spark processing will be optimized accordingly. 
&lt;br&gt;
Eventually, the processing distribution will scale linearly with the data distribution. As such, it&apos;s &lt;b&gt;a very natural approach&lt;/b&gt; in addition to being simple and efficient.
&lt;/p&gt;
&lt;p&gt;
Summing things up, the spark processing workload distribution being driven by the ElasticSearch data distribution, both are impacted by the following parameters of an ES index:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;b&gt;index splitting&lt;/b&gt; strategy&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;index sharding&lt;/b&gt; strategy&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;replication&lt;/b&gt; strategy (factor)&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;sharding key&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;
The sharding key is not very important unless one has to implement a lot of joins in his processing scripts. In this case, one should carefully look at the various situations of these joins and find out which property is used most often as join key. 
&lt;br&gt;
The sharding key should be this very same join key, thus enabling spark to implement the joins with best data locality, most of the time on the local node, since all shards with same sharding key end up on same node.
&lt;br&gt;
This may be the topic of another article on the subject, but likely not soon ... since, after so much writing, I need to focus on something else than Spark and ElasticSearch for a little while ...
&lt;/p&gt;
&lt;p&gt;
As a last word on this topic for now, I would like to emphasize that not only this ELK-MS is working cool, in a simple, natural, efficient and performing way, but in addition all the UI consoles (Cerebro, Kibana, Mesos Console, Spark History Server) are state of the art, the Spark APIs is brilliantly designed and implemented, ElasticSearch itself in addition answers a whole range of use cases on its own, etc.
&lt;br&gt;
This stack is simply so amazingly cool.
&lt;/p&gt;


</description>          </item>
    <item>
    <guid isPermaLink="true">https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1</guid>
    <title>ELK-MS - ElasticSearch/LogStash/Kibana - Mesos/Spark : a lightweight and efficient alternative to the Hadoop Stack - part II : assessing behaviour</title>
    <dc:creator>Jerome Kehrli</dc:creator>
    <link>https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1</link>
        <pubDate>Wed, 23 Aug 2017 17:30:37 -0400</pubDate>
    <category>Big Data</category>
    <category>big-data</category>
    <category>elasticsearch</category>
    <category>elk</category>
    <category>elk-ms</category>
    <category>kibana</category>
    <category>logstash</category>
    <category>mesos</category>
    <category>spark</category>
    <atom:summary type="html">&lt;p&gt;
This article is the second article in my serie of two articles presenting the ELK-MS Stack and test cluster. 
&lt;/p&gt;
&lt;p&gt;
ELK-MS stands for ElasticSearch/LogStash/Kibana - Mesos/Spark. The ELK-MS stack is a simple, lightweight, efficient, low-latency and performing alternative to the Hadoop stack providing state of the art Data Analytics features.
&lt;/p&gt;
&lt;p&gt;
ELK-MS is especially interesting for people that don&apos;t want to settle down for anything but the best regarding Big Data Analytics functionalities but yet don&apos;t want to deploy a full-blend Hadoop distribution, for instance from Cloudera or HortonWorks.
&lt;br&gt;
Again, I am not saying that Cloudera and HortonWorks&apos; Hadoops distributions are not good. &lt;i&gt;Au contraire&lt;/i&gt;, they are awesome and really simplifies the overwhelming burden of configuring and maintaining the set of software components they provide.
&lt;br&gt;
But there is definitely room for something lighter and simpler in terms of deployment and complexity.
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/application_architecture.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;ELK-MS Application Architecture&quot; src=&quot;https://www.niceideas.ch/es_spark/images/application_architecture.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana&quot;&gt;The first article - entitled - ELK-MS - part I : setup the cluster&lt;/a&gt; in this serie presents the ELK-MS stack and how to set up a test cluster using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS.tar.gz&quot;&gt;niceideas ELK-MS package&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;This second article - ELK-MS - part II : assessing behaviour&lt;/a&gt; presents a few concerns, assesses the expected behaviour using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS_TEST.tar.gz&quot;&gt;niceideas ELK-MS TEST package&lt;/a&gt; and discusses the challenges and constraints on this ELK-MS environment.
&lt;/p&gt;
&lt;p&gt;
The conclusions of this serie of articles are presented in &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2&quot;&gt;the third and last article - ELK-MS - part III : so why is it cool?&lt;/a&gt; which presents, as the name suggests, why this ELK-MS stack is really really cool and works great.
&lt;/p&gt;
&lt;p&gt;
This article assumes a basic understanding of Big Data / NoSQL technologies in general by the reader.
&lt;/p&gt;</atom:summary>        <description>&lt;!-- ELK-MS - ElasticSearch/LogStash/Kibana - Mesos/Spark : a lightweight and efficient alternative to the Hadoop Stack - part II : assessing behaviour --&gt;

&lt;style&gt;
.container-wrapper {
  width: 100%;
  float: left;
}
.container {
  width: 100%;
  margin-left: auto;
  margin-right: auto;
}
.container figure {
  float: left;
  max-width: 23%;
  min-width: 160px;
  margin: 0 0 10px 2%;
}
/*.container figure:nth-child(1),
.container figure:nth-child(3) {
  margin-left: 0;
}
*/
.container_inner {
  height: 100px;
  max-height: 100px;
  overflow-y: hidden;
}
.container figure a img, .container figure img {
  max-width: 100%;
  float: left;
  clip: rect(0,100px,100px,0);
  position: relative;
  width: 100%;
}
&lt;/style&gt;

&lt;p&gt;&lt;i&gt;
&lt;b&gt;Edited 2017-10-30&lt;/b&gt;: I was using ES 5.0.0 with Spark 2.2.0 at the time of writing the initial version of this article. 
&lt;br&gt;
With ElasticSearch 6.x, and ES-Hadoop 6.x, the game changes a little. The Spark 2.2.0 Dynamic allocation system is now perfectly compatible with the way ES-Hadoop 6.x enforces data locality optimization and everything works just as expected.
&lt;/i&gt;
&lt;/p&gt;

&lt;p&gt;
This article is the second article in my serie of two articles presenting the ELK-MS Stack and test cluster. 
&lt;/p&gt;
&lt;p&gt;
ELK-MS stands for ElasticSearch/LogStash/Kibana - Mesos/Spark. The ELK-MS stack is a simple, lightweight, efficient, low-latency and performing alternative to the Hadoop stack providing state of the art Data Analytics features.
&lt;/p&gt;
&lt;p&gt;
ELK-MS is especially interesting for people that don&apos;t want to settle down for anything but the best regarding Big Data Analytics functionalities but yet don&apos;t want to deploy a full-blend Hadoop distribution, for instance from Cloudera or HortonWorks.
&lt;br&gt;
Again, I am not saying that Cloudera and HortonWorks&apos; Hadoops distributions are not good. &lt;i&gt;Au contraire&lt;/i&gt;, they are awesome and really simplifies the overwhelming burden of configuring and maintaining the set of software components they provide.
&lt;br&gt;
But there is definitely room for something lighter and simpler in terms of deployment and complexity.
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/application_architecture.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;ELK-MS Application Architecture&quot; src=&quot;https://www.niceideas.ch/es_spark/images/application_architecture.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana&quot;&gt;The first article - entitled - ELK-MS - part I : setup the cluster&lt;/a&gt; in this serie presents the ELK-MS stack and how to set up a test cluster using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS.tar.gz&quot;&gt;niceideas ELK-MS package&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;This second article - ELK-MS - part II : assessing behaviour&lt;/a&gt; presents a few concerns, assesses the expected behaviour using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS_TEST.tar.gz&quot;&gt;niceideas ELK-MS TEST package&lt;/a&gt; and discusses the challenges and constraints on this ELK-MS environment.
&lt;/p&gt;
&lt;p&gt;
The conclusions of this serie of articles are presented in &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2&quot;&gt;the third and last article - ELK-MS - part III : so why is it cool?&lt;/a&gt; which presents, as the name suggests, why this ELK-MS stack is really really cool and works great.
&lt;/p&gt;
&lt;p&gt;
This article assumes a basic understanding of Big Data / NoSQL technologies in general by the reader.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Summary&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec1&quot;&gt;1. Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec2&quot;&gt;2. Testing framework&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec21&quot;&gt;2.1 niceideas ELK-MS TEST&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec21&quot;&gt;2.2 Test Scenario Script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec23&quot;&gt;2.3 Used Dataset&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec24&quot;&gt;2.4 Test purposes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec3&quot;&gt;3. Conclusions from assessment tests&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec31&quot;&gt;3.1 ES-Hadoop and Data-locality enforcement &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec32&quot;&gt;3.2 Spark coarse grained scheduling by Mesos vs. Fine Grained&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec33&quot;&gt;3.3 Spark Static Resource Allocation vs. Dynamic Allocation&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec331&quot;&gt;3.3.1 ES-Hadoop 5.x&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec332&quot;&gt;3.3.2 ES-Hadoop 6.x&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec34&quot;&gt;3.4 Latency regarding Python instantiation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec35&quot;&gt;3.5 Other ES-Hadoop concerns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec36&quot;&gt;3.6 Other concerns&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec4&quot;&gt;4. Further work&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec5&quot;&gt;5. Details of Tests&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec51&quot;&gt;5.1 Nominal Tests&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec511&quot;&gt;5.1.1 Legacy RDD API on bank dataset&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec512&quot;&gt;5.1.2 Legacy DataFrame API on bank dataset&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec513&quot;&gt;5.1.3 DataFrame API on bank dataset&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec514&quot;&gt;5.1.4 DataFrame API on Apache-logs dataset&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec515&quot;&gt;5.1.5 DataFrame API on Shakespeare dataset&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec52&quot;&gt;5.2 Data-Locality tests&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec521&quot;&gt;5.2.1 Bank dataset with 1 shard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec522&quot;&gt;5.2.2 Bank dataset with 2 shards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec523&quot;&gt;5.2.3 Bank dataset with 3 shards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec524&quot;&gt;5.2.4 Bank dataset with 1 shard and replicas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec525&quot;&gt;5.2.5 Testing repartitioning&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec53&quot;&gt;5.3 Aggregation tests&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec531&quot;&gt;5.3.1 ES-side Aggregations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec532&quot;&gt;5.3.2 Spark-side Aggregations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec54&quot;&gt;5.4 Join test&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec55&quot;&gt;5.5 Concurrency test&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec6&quot;&gt;6. References&lt;/a&gt;&lt;/li&gt;



&lt;/ul&gt;
&lt;br&gt;



&lt;a name=&quot;sec1&quot;&gt;&lt;/a&gt;
&lt;h2&gt;1. Introduction &lt;/h2&gt;

&lt;p&gt;
The reader might want to refer to the &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana#sec1&quot;&gt;Introduction of the first article in the serie&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Summarizing it, this article is about assessing the behaviour of the ELK-MS Stack using the test cluster introduced in the first article.
&lt;br&gt;
Especially two questions need to be answered:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
First, how does data-locality optimization work using ES-Hadoop to read data from ElasticSearch to Spark? On a large cluster, achieving Data Locality is &lt;i&gt;the sinews of war&lt;/i&gt;. Before considering the ELK-MS stack as an actual alternative to a more standard Hadoop stack, assessing the sound behaviour and a good respect to data locality of the software stack is not optional.
&lt;/li&gt;
&lt;li&gt;
Second, how does Mesos schedule spark executors and how does it impact data-locality? Mesos needs to be an effective alternative to YARN when it comes to dispatching spark executors while still taking into account data-locality.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
These are the two main objectives of the tests for which I am reporting the conclusions hereafter, as well as a few other points.
&lt;br&gt;
This article is not about testing Spark or Mesos themselves, it&apos;s really about testing how ElasticSearch / Mesos / Spark behave all together to support the application architecture from the schema above.
&lt;/p&gt;
&lt;p&gt;
In addition, in contrary to the state of the art on Spark, in my current company, we are not going to be using Java or Scala to implement the spark processing logic, we are going to use python. 
&lt;br&gt;
The reason for this is simple: our Data Scientists know python, period. They do not know Java, they are not willing to learn Scala. Our Data Scientist know R and python and as such as Head of R&amp;D I have made python our standard language for our Data Analytics algorithms (not that I don&apos;t like R, &lt;i&gt;au contraire&lt;/i&gt;, but I believe python is at the right intersection between Data Science and Engineering).
&lt;br&gt;
Choosing python as processing language has an impact when it comes to programming Spark, the support of python is, as a matter of fact, a little under the support of Scala and Java.
&lt;/p&gt;
&lt;p&gt;
Now all of the above give this article is rationality: programming an ElasticSearch / Mesos / Spark Task with python is something that suffers from really little documentation available.
&lt;br&gt;
In the previous article I wanted to present how to set things up as well as share my setup tools and in this article I want to present how to use it, it&apos;s behaviour and share some short sample programs in the form of my tests package.
&lt;/p&gt;


&lt;a name=&quot;sec2&quot;&gt;&lt;/a&gt;
&lt;h2&gt;2. Testing Framework &lt;/h2&gt;

&lt;p&gt;
I would summarize the specificities of the usage of Spark in my current company as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data analytics use cases are implemented in pyspark and python scripts and not native Scala or Java APIs&lt;/li&gt;
&lt;li&gt;The input data and results are stored in ElasticSearch, not in HDFS&lt;/li&gt;
&lt;li&gt;Spark runs on Mesos and not the more standard YARN on Hadoop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
So I needed a way to test and assess that all of this is working as expected and that the behaviour of the Mesos/Spark stack, both from the perspective of concurrency and respect of data-locality in between ES nodes and Spark nodes, is sound.
&lt;br&gt;
This is the objective of the &lt;i&gt;niceideas_ELK-MS-TEST&lt;/i&gt; framework.
&lt;/p&gt;
&lt;p&gt;
I am presenting this framework, the approach and the tests it contains herunder.
&lt;br&gt;
The test framework is &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS_TEST.tar.gz&quot;&gt;available for download here&lt;/a&gt;.
&lt;/p&gt;

&lt;a name=&quot;sec21&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.1 niceideas ELK-MS TEST&lt;/h3&gt;

&lt;p&gt;
The &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS_TEST.tar.gz&quot;&gt;niceideas ELK-MS TEST package&lt;/a&gt; structure, after being properly extracted in a local folder, is as follows:
&lt;/p&gt;


&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/testing.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 450px;&quot; alt=&quot;ELK-MS TEST Structure&quot; src=&quot;https://www.niceideas.ch/es_spark/images/testing.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;./vm_execute.sh&lt;/code&gt;: this is the script one calls on the host machine to launch a test. The test to be executed should be given as argument.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;./tests/*&lt;/code&gt;: the test scenario scripts. 
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Executing a test on the ELK-MS Test cluster, is simply done, for instance, by the following command:
&lt;/p&gt;

&lt;pre&gt;
badtrash@badbook:/data/niceideas_ELK-MS-TEST$ ./vm_execute.sh scenarii/5_concurrency_1_swissdata_df.sh
&lt;/pre&gt;

&lt;p&gt;
This would execute the test 5_1 and show the spark driver logs on the console.
&lt;/p&gt;

&lt;a name=&quot;sec2&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.2 Test Scenario Script&lt;/h3&gt;

&lt;p&gt;
Each and every test scenario script has the very same structure :
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an ad&apos;hoc shell script taking care of downloading a data set and loading in into ElasticSearch&lt;/li&gt;
&lt;li&gt;Execute that Data Loading Shell script&lt;/li&gt;
&lt;li&gt;Create an ad&apos;hoc python script taking care of implementing the Spark processing&lt;/li&gt;
&lt;li&gt;Execute the Data Processing Python script&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
For instance, a test scenario &lt;code&gt;X_test_Y_variant.sh&lt;/code&gt; would have following structure:
&lt;/p&gt;

&lt;pre&gt;
#!/bin/bash

# 1. Create Data Ingestion script
# -----------------------------------------------------------------------------
cat &gt; X_test_Y_variant_do.sh &amp;lt;&amp;lt;- &quot;EOF&quot;
#!/bin/bash

# echo commands
set -x

&lt;span style=&quot;color: red;&quot;&gt;# ...
# Various shell commands to proceed with loading the data in ES
# ...&lt;/span&gt;

# turn off command echoing
set +x


EOF

# 2. Exexcute Data Ingestion Script
# -----------------------------------------------------------------------------

bash X_test_Y_variant_do.sh
if [[ $? != 0 ]]; then
    echo &quot;Script execution failed. See previous logs&quot;
    exit -1
fi


# 3. Create pyspark script
# -----------------------------------------------------------------------------
cat &gt; X_test_Y_variant.py &amp;lt;&amp;lt;- &quot;EOF&quot;

from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_X_Y&quot;)

# SparkContext and SQLContext
sc = SparkContext(conf=conf)
sqlContext = SQLContext(sc)

&lt;span style=&quot;color: red;&quot;&gt;# ...
# Various spark processing commands
# ...&lt;/span&gt;

EOF

# 4. Exexcute pyspark script
# -----------------------------------------------------------------------------

spark-submit X_test_Y_variant.py
if [[ $? != 0 ]]; then
    echo &quot;Script execution failed. See previous logs&quot;
    exit -1
fi
&lt;/pre&gt;

&lt;p&gt;
This key point of these scripts is that they are self contained and idempotent. They make no assumption about the state of the ELK-MS cluster before and they always start by cleaning all the data before reloading the data required for the tests.
&lt;/p&gt;

&lt;a name=&quot;sec23&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.3 Used Dataset&lt;/h3&gt;

&lt;p&gt;
All the tests scenarii from the &lt;i&gt;niceideas ELK-MS TEST&lt;/i&gt; package used either one of the following datasets:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;Bank Dataset&lt;/b&gt;: from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&lt;/a&gt; - a dataset of financial accounts with owner and balance information.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Shakespeare Dataset&lt;/b&gt;: from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/shakespeare.json&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/shakespeare.json&lt;/a&gt; - the complete work of Shakespeare, every line of every speech.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Apache logs Dataset&lt;/b&gt;: from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/logs.jsonl.gz&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/logs.jsonl.gz&lt;/a&gt; - a set or an apache web server log files.
&lt;/li&gt;
&lt;li&gt;	
&lt;b&gt;Swiss AirBnB&lt;/b&gt;: two datasets in fact:
&lt;ul&gt;
&lt;li&gt;
from &lt;a href=&quot;http://niceideas.ch/mes/swissairbnb/tomslee_airbnb_switzerland_1451_2017-07-11.csv&quot;&gt;http://niceideas.ch/mes/swissairbnb/tomslee_airbnb_switzerland_1451_2017-07-11.csv&lt;/a&gt; : the list of AirBnB offers in Switzerland as of July 2017.
&lt;/li&gt;
&lt;li&gt;
from &lt;a href=&quot;http://niceideas.ch/mes/swissairbnb/swisscitiespop.txt&quot;&gt;http://niceideas.ch/mes/swissairbnb/swisscitiespop.txt&lt;/a&gt; : the list of swiss cities with population and geoloc information.
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The last dataset, related to swiss AirBnB offers and cities information is required to test the behaviour of joins on Spark.
&lt;br&gt;
The other datasets represent different volumes and enable us to test various aspects.
&lt;/p&gt;

&lt;a name=&quot;sec24&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.4 Test purposes&lt;/h3&gt;

&lt;p&gt;
The tests from the &lt;i&gt;niceideas ELK-MS TEST&lt;/i&gt; package are presented in details with all results in section &lt;a href=&quot;#sec5&quot;&gt;5. Details of Tests&lt;/a&gt;.
&lt;br&gt;
Before presenting the conclusions inferred from these tests in the next section, this is a short summary of the purpose of every family of tests:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;b&gt;Nominal tests&lt;/b&gt; - assess how the various kinds of APIs of Spark are used to read data from ES: the RDD API, the legacy DataFrame API (SQLContext) and the new DataFrame API (SQLSession).
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Data-locality tests&lt;/b&gt; - assess how data-locality optimization between ES and Spark works and to what extent.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Aggregation tests&lt;/b&gt; - how aggregation on ES data works.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Join tests&lt;/b&gt; - how joining two data frames coming from ES works.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Concurrency tests&lt;/b&gt; - how does Mesos / Spark behave when running several jobs at a time.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Again, the section &lt;a href=&quot;#sec5&quot;&gt;5. Details of Tests&lt;/a&gt; presents each and every test in details, along with the screenshots of Cerebro, Spark History Server, the logs of the spark driver, etc. 
&lt;/p&gt;


&lt;a name=&quot;sec3&quot;&gt;&lt;/a&gt;
&lt;h2&gt;3. Conclusions from assessment tests&lt;/h2&gt;

&lt;p&gt;
I am reporting in this section already the conclusions that can be taken from the tests executed in the scope of this work.
&lt;br&gt;
The conclusions and important information are presented in this early section already, preventing the reader from the requirement to read all the individual tests presented in details in the next section.
&lt;/p&gt;



&lt;a name=&quot;sec31&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.1 ES-Hadoop and Data-locality enforcement &lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;Data locality&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Data locality is how close data is to the code processing it. There are several levels of locality based on the data’s current location. In order from closest to farthest:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;&lt;code&gt;PROCESS_LOCAL&lt;/code&gt;&lt;/b&gt; data is in the same JVM as the running code. This is the best locality possible
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;&lt;code&gt;NODE_LOCAL&lt;/code&gt;&lt;/b&gt; data is on the same node. Examples might be in HDFS on the same node, or in another executor on the same node. This is a little slower than PROCESS_LOCAL because the data has to travel between processes
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;&lt;code&gt;NO_PREF&lt;/code&gt;&lt;/b&gt; data is accessed equally quickly from anywhere and has no locality preference
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;&lt;code&gt;RACK_LOCAL&lt;/code&gt;&lt;/b&gt; data is on the same rack of servers. Data is on a different server on the same rack so needs to be sent over the network, typically through a single switch
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;&lt;code&gt;ANY&lt;/code&gt;&lt;/b&gt; data is elsewhere on the network and not in the same rack
Spark prefers to schedule all tasks at the best locality level, but this is not always possible. In situations where there is no unprocessed data on any idle executor, Spark switches to lower locality levels. There are two options: a) wait until a busy CPU frees up to start a task on data on the same server, or b) immediately start a new task in a farther away place that requires moving data there.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
What Spark typically does is wait a bit in the hopes that a busy CPU frees up. Once that timeout expires, it starts moving the data from far away to the free CPU.
&lt;br&gt;
The setting indicating how long it should wait before moving the processing elsewhere is &lt;code&gt;spark.locality.wait=10s&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;

&lt;b&gt;ES-Hadoop&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;

Data-locality enforcement works amazingly under nominal conditions. ES-Hadoop makes the Spark scheduler understand the topology of the shards on the ES cluster and Spark dispatches the processing accordingly. Mesos doesn&apos;t interfere in this regards.
&lt;/p&gt;
&lt;p&gt;

But again, it works only under nominal conditions.
&lt;br&gt;
As indicated above, there can be several factors compromising Data-locality:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
First, imagine that at resource allocation time the Mesos cluster is heavily loaded. Spark will wait for &lt;code&gt;spark.locality.wait=10s&lt;/code&gt; trying to get the processing executed on the node where ES stored the target data shard. 
&lt;br&gt;
But if in this period the node doesn&apos;t become free, spark will move the processing elsewhere.
&lt;/li&gt;
&lt;li&gt;
The second case it not anymore related to spark, but to ElasticSearch. Imagine that at the very moment the spark executor submits the request to ES (through the ES-Hadoop connector), the co-located ES node is busy doing something else (answering another request, indexing some data, etc.). 
&lt;br&gt;
In this case, ES will delegate the answering of the request to another node and local data-locality is broken.
&lt;/ol&gt;


&lt;a name=&quot;sec32&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.2 Spark coarse grained scheduling by Mesos vs. Fine Grained &lt;/h3&gt;

&lt;p&gt;
In &lt;i&gt;Coarse Grained&lt;/i&gt; scheduling mode, the default, Mesos considers spark only at the scale of the required &lt;i&gt;spark executor&lt;/i&gt; processes. All Mesos knows about spark is the executor processes on the nodes they are running. Mesos knows nothing of Spark&apos;s jobs internals such as stages and tasks.
&lt;br&gt;
In addition, static allocation makes Mesos Job pretty easy: try to allocate as many resources from the cluster to spark executors for pending jobs as are available. This has the following consequences:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
First, if a job is submitted to the cluster at a moment when the cluster is completely free, the job will be allocated the whole cluster. If another job comes even only just a few seconds after, it will still need to wait for the cluster to be freed by the first job, and that will happen only when the first job completes.
&lt;/li&gt;
&lt;li&gt;
Second, if several jobs are waiting to be executed, when the cluster is freed, Mesos will allocate the cluster resources evenly to each and every job. Now imagine that all these jobs are short-lived jobs and only one of them is a long-lived job. At allocation time (static allocation), that long-lived job got only a small portion of the cluster. Even if very soon the cluster becomes free, that job will still need to complete its execution on his small portion, making most of the cluster unused.
&lt;/ol&gt;

&lt;p&gt;
Historically, Mesos on Spark can benefit from a &lt;i&gt;Fine Grained&lt;/i&gt; scheduling mode instead, where Mesos will schedule not only spark executors on nodes in a rough fashion but really each and every individual spark task instead.
&lt;br&gt;
In regards to data-locality optimization, this doesn&apos;t seem to have any impact.
&lt;br&gt;
In regards to performance on the other hand, &lt;i&gt;Fine Grained&lt;/i&gt; scheduling mode really messes performances completely.
&lt;/p&gt;
&lt;p&gt;
The thing is that Mesos requires quite some time to negotiate with the resources providers. If that negotiation happens for every individual spark tasks, a huge amount of time is lost and eventually the impact on performance is not acceptable.
&lt;/p&gt;
&lt;p&gt;
For this reason (and others), the &lt;i&gt;Fine Grained&lt;/i&gt; scheduling mode is deprecated: &lt;a href=&quot;https://issues.apache.org/jira/browse/SPARK-11857&quot;&gt;https://issues.apache.org/jira/browse/SPARK-11857&lt;/a&gt;
&lt;/p&gt;

&lt;a name=&quot;sec33&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.3 Spark Static Resource Allocation vs. Dynamic Allocation &lt;/h3&gt;

&lt;p&gt;
By default, Spark&apos;s scheduler uses a &lt;b&gt;Static Resource Allocation&lt;/b&gt; system. This means that, at the job (or driver) initialization time, Spark, with the help of Mesos in this case, will decide what resource from the Mesos cluster can be allocated to the job. This decision is static, meaning that once decided the set of resources allocated to the job will never change in its whole life regardless of what happens on the cluster (other / additional nodes becoming free, etc.)
&lt;br&gt;
This has the consequences listed above in the previous section, the whole cluster is allocated to a single job, further jobs need to wait, etc. and as such it&apos;s not very optimal.
&lt;/p&gt;

&lt;p&gt;
Now of course Spark provides a solution to this, the &lt;b&gt;Dynamic Allocation&lt;/b&gt; System.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;And this is where Spark gets really cool.&lt;/b&gt; With Dynamic Allocation, the Spark / Mesos cluster is evenly shared between multiples jobs requesting execution on the cluster regardless of the time of appearance of the jobs.
&lt;br&gt;
And with ES-Hadoop 6.x, the Dynamic allocation system is perfectly able to respect the locality requirements communicated by the elastic-search spark connector and respects them as much as possible
&lt;/p&gt;

&lt;a name=&quot;sec331&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.3.1 ES-Hadoop 5.x and Spark 2.2&lt;/h3&gt;


&lt;p&gt;
With ES-Hadoop version 5.x, the way the elasticsearch-spark connector was enforcing data locality was incompatible with Spark 2.2.0 and as such 
But unfortunately, when using Dynamic Allocation, Spark simply doesn&apos;t take into consideration ES-Hadoop&apos;s requirements regarding data locality optimization anymore.
&lt;/p&gt;
&lt;p&gt;
Without going into details, the problem comes from the fact that ES-Hadoop makes spark request as many executors as shards and indicates as &lt;i&gt;preferred location&lt;/i&gt; the nodes owning the ES shards. 
&lt;br&gt;
But Dynamic allocation screws all of this by allocating executors only one after the other (more or less) and only after monitoring evolutions of the job processing needs and the amount of tasks created. In no way does the dynamic allocation system give any consideration for ES-Hadoop requirements.
&lt;/p&gt;


&lt;a name=&quot;sec332&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.3.2 ES-Hadoop 6.x&lt;/h3&gt;

&lt;p&gt;
As indicated in the release notes of the ElasticSearch-Hadoop connector 6.0.0, the ElasticTeam has added support for Spark 2.2.0. This support has fixed the messing up with Dynamic Allocation problem that was suffering ES-Hadoop 5.x.
&lt;/p&gt;
&lt;p&gt;
Now even with Dynamic Allocation properly enables, which is a requirement for us in order to optimize the Mesos Cluster resources consumption, Data Locality os optimized and properly enforced everywhen possible.
&lt;/p&gt;



&lt;a name=&quot;sec34&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.4 Latency regarding Python instantiation&lt;/h3&gt;

&lt;p&gt;
Executing some tasks in Python takes time in comparison to executing tasks natively in Java or Scala. The problem is that spark tasks in python require to launch the individual task processing in seperate process than the Spark JVM. Only Java and Scala Spark processings run natively in the Spark JVM.
&lt;/p&gt;
&lt;p&gt;
This problem is not necessarily a big deal since the DataFrame or RDD APIs exposed to python pyspark scripts are actually implemented by Scala code underneath, they resolve to native Scala code.
&lt;br&gt;
There is one noticeable exception in this regards: UDF (User Defined functions) implemented in python. While this is very possible, it should be avoided at all cost.
&lt;br&gt;
One can very well still use pyspark but write UDF in Scala.
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An explanation of this problem : &lt;a href=&quot;https://fr.slideshare.net/SparkSummit/getting-the-best-performance-with-pyspark&quot;&gt;https://fr.slideshare.net/SparkSummit/getting-the-best-performance-with-pyspark&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;UDF in Scala : &lt;a href=&quot;http://aseigneurin.github.io/2016/09/01/spark-calling-scala-code-from-pyspark.html&quot;&gt;http://aseigneurin.github.io/2016/09/01/spark-calling-scala-code-from-pyspark.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;a name=&quot;sec35&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.5 Other ES-Hadoop concerns&lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;Repartitioning&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
I couldn&apos;t find a way to make repartitioning work the way I want, meaning re-distributing the data on the cluster in order to scale out the further workload.
&lt;br&gt;
I am not saying there is no way, just that I haven&apos;t found one so far.
&lt;/p&gt;
&lt;p&gt;
As such, a sound approach regarding initial sharding in ES should be adopted. One should take into consideration that &lt;i&gt;a priori&lt;/i&gt;, initial sharding may well drive the way Spark will be able to scale the processing out on the cluster. 
&lt;br&gt;
While creating by default one shard per node in the cluster would definitely be overkill, the general idea should tend in this direction.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;ES level aggregations&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
It&apos;s simply impossible to forge a query from Spark to ElasticSearch through ES-Hadoop that would make ElasticSearch compute aggregation and returning them instead of the raw data. 
&lt;br&gt;
Such advanced querying features are not available from spark.
&lt;/p&gt;
&lt;p&gt;
The need is well identified but it remains &lt;i&gt;Work in Progress&lt;/i&gt; at the moment: &lt;a href=&quot;https://github.com/elastic/elasticsearch-hadoop/issues/276 &quot;&gt;https://github.com/elastic/elasticsearch-hadoop/issues/276&lt;/a&gt;.
&lt;/p&gt;


&lt;a name=&quot;sec36&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.6 Other concerns&lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;Spark History Server&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Running Spark in Mesos, there is no long-lived Spark process. Spark executors are created when required by Mesos and the Mesos master and slave processes are the only long lived process on the cluster in this regards.
&lt;/p&gt;
&lt;p&gt;
As such, the Spark Application UI (on ports 4040, 4041, etc.) only live for the time of the Spark processing. When the job is finished, the Spark UI application vanishes.
&lt;/p&gt;
&lt;p&gt;
For this reason, Spark provides an History server. The installation and operation of the History Server is presented in &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana&quot;&gt;the first article of this serie : ELK-MS - part I : setup the cluster&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Interestingly, that history server supports the same JSON / REST API that the usual Spark Console, with only a very few limitations.
&lt;br&gt;
For instance, one can use the REST API to discover about the Application-ID of running jobs in order to kill them (whenever required). For this, simply list the jobs and find out about those that have &lt;code&gt;&quot;endTimeEpoch&quot; : -1&lt;/code&gt;, meaning the application is still alive:
&lt;/p&gt;

&lt;pre&gt;
curl -XGET http://192.168.10.10:18080/api/v1/applications
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Limitations of the ELK-MS stack&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
As stated in the previous article, ElasticSearch is not a distributed filesystem, it&apos;s a document-oriented NoSQL database.
&lt;/p&gt;
&lt;p&gt;
There are situations where a distributed filesystem provides interesting possibilities. Those are not provided by the ELK-MS stack as is. It would be interesting to test Ceph on Mesos for this. See &lt;a href=&quot;http://tracker.ceph.com/projects/ceph/wiki/Ceph-mesos&quot;&gt; http://tracker.ceph.com/projects/ceph/wiki/Ceph-mesos&lt;/a&gt;.
&lt;/p&gt;

&lt;a name=&quot;sec4&quot;&gt;&lt;/a&gt;
&lt;h2&gt;4. Further work&lt;/h2&gt;

&lt;p&gt;
I am still considering some next steps on the topic of the ELK-MS stack testing since there are still a few things I would like to test ot assess:
&lt;/p&gt;
&lt;p&gt;
In a raw fashion:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Find out about how to set maximum nodes booked by Mesos for a single spark job in order to avoid fully booking the cluster.
&lt;/li&gt;

&lt;li&gt;
ElasticSearch on mesos
&lt;ul&gt;
&lt;li&gt;
This seems quite obvious. I expect the overall cluster performance to be way better if Mesos and ES don&apos;t compete with each other for hardware resources on nodes.
&lt;/li&gt;
&lt;li&gt;
There are workaround of course, such as configuring Mesos to avoid using all the CPUs of a node. But that will never be as efficient as letting Mesos distribute the global workload.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;
Find a way for repartitioning to work the way I intend it: data should get redistributed across the cluster!
&lt;/li&gt;

&lt;li&gt;
Give Spark Streaming a try to reduce latency.
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/hadoop/master/spark.html#spark-streaming&quot;&gt;https://www.elastic.co/guide/en/elasticsearch/hadoop/master/spark.html#spark-streaming&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;
Try FAIR Spark scheduler and play with it.
&lt;ul&gt;
&lt;li&gt; 
I got satisfying results using spark FIFO scheduler in terms of concurrency and haven&apos;t seen the need to change to FAIR.
&lt;/li&gt;
&lt;li&gt;
It really seems Mesos takes care of everything and I do really not see what the FAIR scheduler can change but I want to be sure.
&lt;/li&gt;
&lt;li&gt;
There are some chances that this makes me rewrite this whole article ... in another article.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;


&lt;li&gt;
Ceph integration on Mesos for binary files processing. 
&lt;ul&gt;
&lt;li&gt;
How to integrate Ceph and spark ? Here as well very little documentation seems to be available.
&lt;/li&gt;
&lt;li&gt;
I found pretty much only this : &lt;a href=&quot;https://indico.cern.ch/event/524549/contributions/2185930/attachments/1290231/1921189/2016.06.13_-_Spark_on_Ceph.pdf&quot;&gt;https://indico.cern.ch/event/524549/contributions/2185930/attachments/1290231/1921189/2016.06.13_-_Spark_on_Ceph.pdf&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;
What about HDFS on Mesos ?
&lt;ul&gt;
&lt;li&gt; 
I would want to give it a try even though I am really rather considering Ceph for the use cases ElasticSearch forbids me to address.
&lt;/li&gt;
&lt;li&gt;
The thing is that Ceph integrates much better in the UNIX unified filesystem than HDFS
&lt;/li&gt;
&lt;li&gt;
Even though there is an approach to reach same level of integration with HDFS based on Fuse &lt;a href=&quot;https://wiki.apache.org/hadoop/MountableHDFS&quot;&gt;https://wiki.apache.org/hadoop/MountableHDFS&lt;/a&gt;. But that is still limited (doesn&apos;t support ownership informations for now)
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;/ul&gt;


&lt;a name=&quot;sec5&quot;&gt;&lt;/a&gt;
&lt;h2&gt;5. Details of Tests&lt;/h2&gt;

&lt;p&gt;
This very big section now presents each and every tests in details, along with the results in the form the the logs of the script (data feeding and spark driver logs), the screenshots of the UI applications (Cerebro, Mesos Console, Spark History Server).
&lt;/p&gt;
&lt;p&gt;

The conclusions from the individual tests have been reported in the global &lt;a href=&quot;#sec3&quot;&gt;3. Conclusions from assessment tests&lt;/a&gt; section above.
&lt;/p&gt;

&lt;a name=&quot;sec51&quot;&gt;&lt;/a&gt;
&lt;h3&gt;5.1 Nominal Tests&lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;Nominal tests&lt;/b&gt; - assess how the various kinds of APIs of Spark are used to read data from ES: the RDD API, the legacy DataFrame API (SQLContext) and the new DataFrame API (SQLSession).
&lt;/p&gt;

&lt;a name=&quot;sec511&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.1.1 Legacy RDD API on bank dataset&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/1_nominal_1_test_bank_rdd_legacy.sh&quot;&gt;&lt;code&gt;1_nominal_1_test_bank_rdd_legacy.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Bank Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: see how Spark&apos;s RDD API can be used to fetch data from ElasticSearch and how sharding in ES impacts executors layout on the cluster
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_1_1&quot;)

# SparkContext and SQLContext
sc = SparkContext(conf=conf)
sqlContext = SQLContext(sc)

# Simplest possible query
q = &quot;?q=*&quot;

es_read_conf = {
    &quot;es.resource&quot; : &quot;bank&quot;,
    &quot;es.query&quot; : q
}

es_rdd = sc.newAPIHadoopRDD(
    inputFormatClass=&quot;org.elasticsearch.hadoop.mr.EsInputFormat&quot;,
    keyClass=&quot;org.apache.hadoop.io.NullWritable&quot;, 
    valueClass=&quot;org.elasticsearch.hadoop.mr.LinkedMapWritable&quot;, 
    conf=es_read_conf)

es_df = sqlContext.createDataFrame(es_rdd)

# I need to collect the result to show them on the console
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count : THIS IS FUNNY : 
# it relaunches the whole Distributed Data Frame Processing
print (&quot;Fetched %s accounts (re-computed)&quot;) % es_df.count()

# Print count 
print (&quot;Fetched %s accounts (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/1_nominal_1_test_bank_rdd_legacy.log&quot;&gt;1_nominal_1_test_bank_rdd_legacy.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-1 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-1 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-1 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_1_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_1_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-1 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Spark can read data from ElasticSearch using the ES-Hadoop connector and the RDD API really out of the box. 
&lt;br&gt;
One just needs to configure a few settings to the &lt;code&gt;newAPIHadoopRDD&lt;/code&gt; API:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;inputFormatClass=&quot;org.elasticsearch.hadoop.mr.EsInputFormat&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;keyClass=&quot;org.apache.hadoop.io.NullWritable&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;valueClass=&quot;org.elasticsearch.hadoop.mr.LinkedMapWritable&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Mesos spreads the workload on the cluster efficiently.
&lt;ul&gt;
&lt;li&gt;This test was run alone on the cluster&lt;/li&gt;
&lt;li&gt;2 nodes are sufficient to run the job since, thanks to replicas two nodes have actually all the shards &lt;/li&gt;
&lt;li&gt;Mesos creates a dedicated spark executor on each of the 2 nodes&lt;/li&gt;
&lt;li&gt;Sparks then successfully distribute the RDD on the 2 executors&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Data-locality optimization works out of the box.
&lt;ul&gt;
&lt;li&gt;There are 5 shards in ElasticSearch, which, with replicas, are well spread on the cluster&lt;/li&gt;
&lt;li&gt;Mesos / Spark dispatches the workload efficiently since it creates 5 RDD partitions for the 5 shards, each and every of them respecting data locality (&lt;code&gt;NODE_LOCAL&lt;/code&gt;) and as such respecting the requirements given by the ES-Hadoop connector.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;a name=&quot;sec512&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.1.2 Legacy DataFrame API on bank dataset&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/1_nominal_2_test_bank_df_legacy.sh&quot;&gt;&lt;code&gt;1_nominal_2_test_bank_df_legacy.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Bank Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: see how Spark&apos;s legacy DataFrame API can be used to fetch data from ElasticSearch and how sharding in ES impacts executors layout on the cluster
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_1_2&quot;)

## !!! Caution : this is pre 2.0 API !!! 

# SparkContext and SQLContext
sc = SparkContext(conf=conf)
sqlContext = SQLContext(sc)

es_df = sqlContext.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(pushdown=True) \
            .load(&quot;bank&quot;) \
            .where(&quot;gender=&apos;F&apos;&quot;)

# I need to collect the result to show them on the console
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count : THIS IS FUNNY : 
# it relaunches the whole Distributed Data Frame Processing
print (&quot;Fetched %s women accounts (re-computed)&quot;) % es_df.count()

# Print count 
print (&quot;Fetched %s women accounts (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/1_nominal_2_test_bank_df_legacy.log&quot;&gt;1_nominal_2_test_bank_df_legacy.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-2 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-2 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-2 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_2_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_2_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-2 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Spark can read data from ElasticSearch using the ES-Hadoop connector and the Legacy DataFrame API (SQLContext) really out of the box. 
&lt;br&gt;
The single configuration required is &lt;code&gt;format(&quot;org.elasticsearch.spark.sql&quot;) on the &lt;code&gt;SQLContext&lt;/code&gt; API&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
Here as well, the Dynamic allocation system allocates nodes to the job one after the other. 
&lt;br&gt;
After two nodes alolocated to the job, all shards (thx to replicas) become available locally and data localiy optimization can be satisfied without any other node required. The job executes on these 2 nodes.
&lt;/li&gt;
&lt;li&gt;
In this case, as seen on &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_2_job_0_stage_0.png&quot;&gt;result_1_2_job_0_stage_0.png&lt;/a&gt;, spark successfully respects data locality as well.
&lt;/li&gt;
&lt;/ul&gt;


&lt;a name=&quot;sec513&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.1.3 DataFrame API on bank dataset&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/1_nominal_3_test_bank_df.sh&quot;&gt;&lt;code&gt;1_nominal_3_test_bank_df.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Bank Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: see how Spark&apos;s New (&gt;= 2.0) DataFrame API can be used to fetch data from ElasticSearch and how sharding in ES impacts executors layout on the cluster
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark.conf import SparkConf
from pyspark.sql import SQLContext, SparkSession

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_1_3&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

es_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(pushdown=True) \
            .load(&quot;bank&quot;) \
            .where(&quot;gender=&apos;F&apos;&quot;)

# I need to collect the result to show them on the console
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count : THIS IS FUNNY : 
# it relaunches the whole Distributed Data Frame Processing
print (&quot;Fetched %s women accounts (re-computed)&quot;) % es_df.count()

# Print count 
print (&quot;Fetched %s women accounts (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/1_nominal_3_test_bank_df.log&quot;&gt;1_nominal_3_test_bank_df.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_3.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_3.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-3 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_3.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_3.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-3 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_3.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_3.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-3 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_3_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_3_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-3 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Spark can read data from ElasticSearch using the ES-Hadoop connector and the New DataFrame API (SQLSession) really out of the box. 
&lt;br&gt;
The single configuration required here as well is &lt;code&gt;format(&quot;org.elasticsearch.spark.sql&quot;) on the &lt;code&gt;SQLSession&lt;/code&gt; API&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
Nothing specific to report regarding the other aspects: Mesos and Spark&apos;s dynamic allocation system distribute the workload as expected, still creates a dedicated Spark Executor for 2 nodes of the cluster which is sufficient (thx replicas), Spark respects data locality strictly, etc.
&lt;/li&gt;
&lt;/ul&gt;



&lt;a name=&quot;sec514&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.1.4 DataFrame API on Apache-logs dataset&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/1_nominal_4_test_apache-logs_df.sh&quot;&gt;&lt;code&gt;1_nominal_4_test_apache-logs_df.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Apache Logs Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/logs.jsonl.gz&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/logs.jsonl.gz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: see how Spark&apos;s New (&gt;= 2.0) DataFrame API can be used to fetch data from ElasticSearch from another dataset and how sharding in ES impacts executors layout on the cluster
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark.conf import SparkConf
from pyspark.sql import SQLContext, SparkSession

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_1_4&quot;)

# es.read.field.exclude (default empty) : 
#  Fields/properties that are discarded when reading the documents 
#  from Elasticsearch
conf.set (&quot;es.read.field.exclude&quot;, &quot;relatedContent&quot;)

# es.read.field.as.array.include (default empty) : 
#  Fields/properties that should be considered as arrays/lists
conf.set (&quot;es.read.field.as.array.include&quot;, &quot;@tags,headings,links&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

# Query configuration only (cannot pass any ES conf here :-( )
es_query_conf= { 
    &quot;pushdown&quot;: True
}

es_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(conf=es_query_conf) \
            .load(&quot;apache-logs-*&quot;)


# I need to collect the result to show them on the console
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count : THIS IS FUNNY : 
# it relaunches the whole Distributed Data Frame Processing
print (&quot;Fetched %s logs (re-computed)&quot;) % es_df.count()

# Print count 
print (&quot;Fetched %s logs (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/1_nominal_4_test_apache-logs_df.log&quot;&gt;1_nominal_4_test_apache-logs_df.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_4.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_4.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-4 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_4.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_4.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-4 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_4.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_4.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-4 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_4_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_4_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-4 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
N.D (nothing to declare). Everything works as expected (see previous tests results from the &lt;a href=&quot;#sec51&quot;&gt;1 Nominal Tests&lt;/a&gt; family). 
&lt;br&gt;
Interestingly here, the workload justifies the booking of the three nodes of te cluster, which is successfully achieved since the job runs alone on the cluster.
&lt;/p&gt;

&lt;a name=&quot;sec515&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.1.5 DataFrame API on Shakespeare dataset&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/1_nominal_5_test_shakespeare.sh&quot;&gt;&lt;code&gt;1_nominal_5_test_shakespeare.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Shakespeare&apos;s Works Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/shakespeare.json&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/shakespeare.json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: see how Spark&apos;s New (&gt;= 2.0) DataFrame API can be used to fetch data from ElasticSearch from another dataset and how sharding in ES impacts executors layout on the cluster
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark.conf import SparkConf
from pyspark.sql import SQLContext, SparkSession

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_1_5&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

# Query configuration only (cannot pass any ES conf here :-( )
es_query_conf= { 
    &quot;pushdown&quot;: True
}

es_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(conf=es_query_conf) \
            .load(&quot;shakespeare*&quot;)

# Collect result to the driver
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count : THIS IS FUNNY : 
# it relaunches the whole Distributed Data Frame Processing
print (&quot;Fetched %s logs (re-computed)&quot;) % es_df.count()

# Print count 
print (&quot;Fetched %s logs (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/1_nominal_5_test_shakespeare.log&quot;&gt;1_nominal_5_test_shakespeare.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_5.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_1_5.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-5 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_5.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_1_5.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-5 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_5.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_5.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-5 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_5_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_1_5_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 1-5 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
N.D (nothing to declare). Everything works as expected (see previous tests results from the &lt;a href=&quot;#sec51&quot;&gt;1 Nominal Tests&lt;/a&gt; family).
&lt;br&gt;
This time, however, due to the lack of replicas, the three nodes are actually required to satisfy data localiy optimization. The allocation of the 2 nodes to the job happens successfully again since the job runs alone.
&lt;/p&gt;


&lt;a name=&quot;sec52&quot;&gt;&lt;/a&gt;
&lt;h3&gt;5.2 Data-locality tests&lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;Data-locality tests&lt;/b&gt; - assess how data-locality optimization between ES and Spark works and to what extent.
&lt;/p&gt;

&lt;a name=&quot;sec521&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.2.1 Bank dataset with 1 shard&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/2_collocation_1_bank_one_shard.sh&quot;&gt;&lt;code&gt;2_collocation_1_bank_one_shard.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Bank Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: Assess how data-locality works when using a dataset with a single shard on a single node of the cluster, see what decisions will Mesos / Spark take from ES-Hadoop&apos;s requirements.
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Expected Behaviour&lt;/b&gt;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_1.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;Data Architecture Test 2_1&quot; src=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_1.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark.conf import SparkConf
from pyspark.sql import SQLContext, SparkSession

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_2_1&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

# (1)
es_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(pushdown=True) \
            .load(&quot;bank&quot;) \
            .where(&quot;gender=&apos;F&apos;&quot;)

# (2) Print size of every partition on nodes
def f(iterable):
    # need to convert iterable to list to have len()
    print(&quot;Fetched % rows on node&quot;) % len(list(iterable)) 
es_df.foreachPartition(f)

# (3) I need to collect the result to show them on the console
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count 
print (&quot;Fetched %s women accounts (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/2_collocation_1_bank_one_shard.log&quot;&gt;2_collocation_1_bank_one_shard.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-1 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-1 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-1 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_1_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_1_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-1 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;In terms of workload distribution, this is where Dynamic Allocation is really cool.&lt;/b&gt; Since the single shard is on a single node, the Spark Dynamic Allocation System, with the help of Mesos, takes care of booking that single node as well for the Spark processing job
&lt;/li&gt;
&lt;li&gt;
As a sidenote, using static allocation here, mesos Spark would have booked the whole cluster for the job, which would have been far from optimal in terms of workload distribution. Since the cluster is fully available, Mesos would have booked it all for the Job to come. But eventually 2 of the 3 spark executors won&apos;t be used at all.
&lt;br&gt;
That wouldn&apos;t have been a big deal since this test is running alone. But if some more jobs are added to the cluster and requests an executor, they will have to wait for that first job to be finished before they can share the cluster among them. 
&lt;/li&gt;
&lt;li&gt;Data-locality works as expected. The single shard is located on &lt;code&gt;192.168.10.12&lt;/code&gt; and both the driver logs and the Spark Console for Job 0 / Stage 0 confirms that the co-located Spark executor has been the only one processing the data.
&lt;/li&gt;
&lt;/ul&gt;



&lt;a name=&quot;sec522&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.2.2 Bank dataset with 2 shards&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/2_collocation_2_bank_two_shards.sh&quot;&gt;&lt;code&gt;2_collocation_2_bank_two_shards.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Bank Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: Assess how data-locality optimization works when using a dataset with a two shards on two nodes of the cluster, see what decisions will Mesos / Spark take from ES-Hadoop&apos;s requirements.
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Expected Behaviour&lt;/b&gt;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_2.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;Data Architecture Test 2_2&quot; src=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_2.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark.conf import SparkConf
from pyspark.sql import SQLContext, SparkSession

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_2_2&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

# (1)
es_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(pushdown=True) \
            .load(&quot;bank&quot;) \
            .where(&quot;gender=&apos;F&apos;&quot;)

# (2) Print size of every partition on nodes
def f(iterable):
    # need to convert iterable to list to have len()
    print(&quot;Fetched % rows on node&quot;) % len(list(iterable)) 
es_df.foreachPartition(f)

# (3) I need to collect the result to show them on the console
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count 
print (&quot;Fetched %s women accounts (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/2_collocation_2_bank_two_shards.log&quot;&gt;2_collocation_2_bank_two_shards.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-2 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-2 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-2 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_2_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_2_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-2 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Same remark as above regarding workload distribution. 
&lt;br&gt;
&lt;b&gt;Dynamic Allocation is really cool.&lt;/b&gt; Since the two shards are on two nodes, the Spark Dynamic Allocation System, with the help of Mesos, takes care of booking the two corresponding nodes as well for the Spark processing job.
&lt;/li&gt;
&lt;/li&gt;
&lt;li&gt;Data locality works as expected. The two shards are on &lt;code&gt;192.168.10.10&lt;/code&gt; and &lt;code&gt;192.168.10.12&lt;/code&gt; and both the driver logs and the Spark Console for Job 0 / Stage 0 confirms that both co-located Spark executor have been used to process the 2 shards.
&lt;br&gt;
The tasks have been executed with &lt;code&gt;NODE_LOCAL&lt;/code&gt; locality level.
&lt;/li&gt;
&lt;/ul&gt;



&lt;a name=&quot;sec523&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.2.3 Bank dataset with 3 shards&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/2_collocation_3_bank_three_shards.sh&quot;&gt;&lt;code&gt;2_collocation_3_bank_three_shards.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Bank Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: Assess how data-locality optimization works when using a dataset with a three shards on three nodes of the cluster, see what decisions will Mesos / Spark take from ES-Hadoop&apos;s requirements.
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Expected Behaviour&lt;/b&gt;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_3.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px; &quot; alt=&quot;Data Architecture Test 2_3&quot; src=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_3.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark.conf import SparkConf
from pyspark.sql import SQLContext, SparkSession

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_2_3&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

# (1)
es_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(pushdown=True) \
            .load(&quot;bank&quot;) \
            .where(&quot;gender=&apos;F&apos;&quot;)

# (2) Print size of every partition on nodes
def f(iterable):
    # need to convert iterable to list to have len()
    print(&quot;Fetched % rows on node&quot;) % len(list(iterable)) 
es_df.foreachPartition(f)

# (3) I need to collect the result to show them on the console
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count 
print (&quot;Fetched %s women accounts (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/2_collocation_3_bank_three_shards.log&quot;&gt;2_collocation_3_bank_three_shards.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_3.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_3.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-3 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_3.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_3.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-3 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_3.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_3.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-3 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_3_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_3_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-3 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Three shards on three nodes so three nodes booked for processing, everything works as expected.
&lt;/li&gt;
&lt;li&gt;Data locality works as expected. The 3 spark executors &lt;i&gt;consumes&lt;/i&gt; data from their co-located shards. This is confirmed by everything behaving as expected as can be seen in the driver logs or in the Spark Application UI.
&lt;/li&gt;
&lt;/ul&gt;


&lt;a name=&quot;sec524&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.2.4 Bank dataset with 1 shard and replicas&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/2_collocation_4_bank_one_shard_with_replicas.sh&quot;&gt;&lt;code&gt;2_collocation_4_bank_one_shard_with_replicas.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Bank Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: Assess how data-locality works when using a dataset with one shard and two replicas on three nodes of the cluster, see what decisions will Mesos / Spark take from ES-Hadoop&apos;s requirements.
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Expected Behaviour&lt;/b&gt;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_4.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;Data Architecture Test 2_4&quot; src=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_4.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark.conf import SparkConf
from pyspark.sql import SQLContext, SparkSession

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_2_4&quot;)

# FIXME GET RID OF THESE TESTS
# Trying some ES settings
# conf.set (&quot;spark.es.input.max.docs.per.partition&quot;, 100)
# That doesn&apos;t really help =&gt; it split the dataframe on several nodes indeed 
# but it doesn&apos;t impact the fetching

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

# (1)
es_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(pushdown=True) \
            .load(&quot;bank&quot;) \
            .where(&quot;gender=&apos;F&apos;&quot;)

# (2) Print size of every partition on nodes
def f(iterable):
    # need to convert iterable to list to have len()
    print(&quot;Fetched % rows on node&quot;) % len(list(iterable)) 
es_df.foreachPartition(f)

# (3) I need to collect the result to show them on the console
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count 
print (&quot;Fetched %s women accounts (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/2_collocation_4_bank_one_shard_with_replicas.log&quot;&gt;2_collocation_4_bank_one_shard_with_replicas.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_4.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_4.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-4 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_4.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_4.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-4 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_4.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_4.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-4 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_4_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_4_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-4 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
In this case, it&apos;s really as if each and every ES node of the cluster has a copy of the data. ElasticSearch makes no distinction when it comes to serve requests between primary shards and secondary shards (replicas). 
&lt;/li&gt;
&lt;li&gt;
Which node will finally execute the processing is really random. Out of several executions I always ended up having a different Spark node executing the whole processing. Data co-locality still kicks in and one single node still does the whole processing every time
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Important note: All of the above works under normal behaviour. Under a heavily loaded cluster, the results can be significantly different. &lt;/b&gt; 
&lt;br&gt;
By running different scenarii under different conditions, I have been able to determine 2 different situations in addition to the nominal one (the one on a free cluster):
&lt;ul&gt;
&lt;li&gt;
First, It can happen that Mesos tries to distribute a specific spark processing part to the Spark executor co-located to the ES shard. 
&lt;br&gt;
But then, when the Spark processing finally queries that local node to get the shard, it can well happen that this ES node is busy answering a different request from a different client application.
&lt;br&gt;
In this case, that local ES node will report itself as busy and will ask another node from the ES cluster to server the request.
&lt;br&gt;
So even though initially Mesos / Spark distributed the workload to the local node to the shard in ES, &lt;b&gt;eventually the request will be served by another distant node from te cluster&lt;/b&gt;.
&lt;/li&gt;
&lt;li&gt;
Second, it can also happen that all nodes co-located to the ES node owning all shards (primary and replicas) are busy.
&lt;br&gt;
In this case, Mesos / Spark will only wait a few seconds expecting of this node to become free, and if that fails to happen, &lt;b&gt;eventually a different Mesos node will run the processing, indifferently for data locality&lt;/b&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
The difference here is that the existence of replicas suddenly &lt;b&gt;gives ElasticSearch the choice&lt;/b&gt;
&lt;br&gt;
ElasticSearch has the choice to answer and serve the data from another node than the local node if suddenly the local node is busy!
&lt;/li&gt;
&lt;li&gt;
In addition, Mesos / Spark will only wait &lt;code&gt;spark.locality.wait=10s&lt;/code&gt; to try to make the specific processing part local to the ES node owning a shard (or a replica BTW). If none of these nodes (owning one of the primary shard or replicas) becomes free and available for that amount of time, then Mesos will distribute the workload to another available node from the Mesos cluster.
&lt;/li&gt;
&lt;/ul&gt;



&lt;a name=&quot;sec525&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.2.5 Testing repartitioning&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/2_collocation_5_bank_one_shard_repartition_NOT_WORKING.sh&quot;&gt;&lt;code&gt;2_collocation_5_bank_one_shard_repartition_NOT_WORKING.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Bank Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: Assess how one can redistribute the data on the cluster after loading data from a sub-set of the cluster nodes such as, for instance, only one node, see how Spark can redistribute the data evenly on the cluster after having loaded an unbalanced data.
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Expected Behaviour&lt;/b&gt;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_5.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;Data Architecture Test 2_5&quot; src=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_2_5.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark.conf import SparkConf
from pyspark.sql import SQLContext, SparkSession

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_2_5&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

# (1)
es_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(pushdown=True) \
            .load(&quot;bank&quot;) \
            .where(&quot;gender=&apos;F&apos;&quot;) 

# Print size of every partition on nodes
def f(iterable):
    # need to convert iterable to list to have len()
    print(&quot;A - % rows stored on node&quot;) % len(list(iterable)) 
es_df.foreachPartition(f)

# Doesn&apos;t help
#es_df2 = es_df.coalesce(1) 
## Print size of every partition on nodes
#es_df2.foreachPartition(f)

# (2)
es_df3 = es_df.repartition(4 * 3) 
# Print size of every partition on nodes
es_df3.foreachPartition(f)

# (3) I need to collect the result to show them on the console
data_list = es_df3.collect()
print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count 
print (&quot;Fetched %s women accounts (from collected list)&quot;) % len (data_list)

# Print
print (ss._jsc.sc().getExecutorMemoryStatus().size())
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/2_collocation_5_bank_one_shard_repartition_NOT_WORKING.log&quot;&gt;2_collocation_5_bank_one_shard_repartition.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;


&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_5.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_2_5.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-5 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_5.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_2_5.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-5 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_5.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_5.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-5 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_5_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_2_5_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 2-5 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;I haven&apos;t been able to make repartitioning work the way I intended it to work&lt;/b&gt;.
&lt;ul&gt;
&lt;li&gt;Eventually all of my tests led to the underlying RDD being repartitioned, but all the partitions remain local to the initially owning node&lt;/li&gt;
&lt;li&gt;I never managed to find a way to make the Spark cluster redistribute the different partitions to the various Spark executors from the cluster&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
I don&apos;t know if that comes from Spark somehow &lt;i&gt;knowing&lt;/i&gt; that it doesn&apos;t need to do that for the post-processing to be done efficiently.
&lt;/li&gt;
&lt;li&gt;
Long story short, I have no real conclusions in this regards, reason why the above schema is crossed by an X.
&lt;/li&gt;
&lt;/ul&gt;



&lt;a name=&quot;sec53&quot;&gt;&lt;/a&gt;
&lt;h3&gt;5.3 Aggregation tests&lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;Aggregation tests&lt;/b&gt; - assess how aggregation on ES data works.
&lt;/p&gt;

&lt;a name=&quot;sec531&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.3.1 ES-side Aggregations&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/3_aggregation_1_es_shakespeare_rdd_legacy_NOT_WORKING.sh&quot;&gt;&lt;code&gt;3_aggregation_1_es_shakespeare_rdd_legacy_NOT_WORKING.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Shakespeare&apos;s Works Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/shakespeare.json&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/shakespeare.json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: see how Spark can exploit native ElasticSearch features such as ES-side aggregations instead of performing aggregations on its own.
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Expected Behaviour&lt;/b&gt;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_3_1.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;Data Architecture Test 3_1&quot; src=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_3_1.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_3_1&quot;)

# SparkContext and SQLContext
sc = SparkContext(conf=conf)
sqlContext = SQLContext(sc)

# -&gt; query dsl
es_aggregations_query = &apos;&apos;&apos;
{ 
    &quot;query&quot; : { &quot;match_all&quot;: {} },
    &quot;size&quot; : 0,
    &quot;aggregations&quot; : { 
        &quot;play_name&quot;: {
            &quot;terms&quot;: {
                &quot;field&quot; : &quot;play_name&quot;
            }
        }
    }
}
&apos;&apos;&apos;

es_read_conf = {
    &quot;es.resource&quot; : &quot;shakespeare&quot;,
    &quot;es.endpoint&quot; : &quot;_search&quot;,
    &quot;es.query&quot; : es_aggregations_query
}

# (1)
es_rdd = sc.newAPIHadoopRDD(
    inputFormatClass=&quot;org.elasticsearch.hadoop.mr.EsInputFormat&quot;,
    keyClass=&quot;org.apache.hadoop.io.NullWritable&quot;, 
    valueClass=&quot;org.elasticsearch.hadoop.mr.LinkedMapWritable&quot;, 
    conf=es_read_conf)

es_df = sqlContext.createDataFrame(es_rdd)

# I need to collect the result 
data_list = es_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count 
print (&quot;Fetched %s rows (from collected list)&quot;) % len (data_list)

&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/3_aggregation_1_es_shakespeare_rdd_legacy_NOT_WORKING.log&quot;&gt;3_aggregation_1_es_shakespeare_rdd_legacy.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_3_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_3_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 3-1 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_3_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_3_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 3-1 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_3_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_3_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 3-1 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_3_1_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_3_1_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 3-1 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;There is simply no way at the moment to submit specific requests, such as aggregation requests, from spark to ElasticSearch using the ES-Hadoop connector.&lt;/b&gt;
&lt;/li&gt;
&lt;li&gt;
The need is well identified but the solution is still work in progress: &lt;a href=&quot;https://github.com/elastic/elasticsearch-hadoop/issues/276&quot;&gt;https://github.com/elastic/elasticsearch-hadoop/issues/276&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Since it&apos;s impossible to make this work as expected, the schematic above is crossed with an X.
&lt;/li&gt;
&lt;/ul&gt;



&lt;a name=&quot;sec532&quot;&gt;&lt;/a&gt;
&lt;h4&gt;5.3.2 Spark-side Aggregations&lt;/h4&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/3_aggregation_2_spark_shakespeare.sh&quot;&gt;&lt;code&gt;3_aggregation_2_spark_shakespeare.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: Shakespeare&apos;s Works Dataset from &lt;a href=&quot;https://download.elastic.co/demos/kibana/gettingstarted/shakespeare.json&quot;&gt;https://download.elastic.co/demos/kibana/gettingstarted/shakespeare.json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: see how Spark performs aggregations on its own.
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Expected Behaviour&lt;/b&gt;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_3_2.png&quot;&gt;
&lt;img style=&quot;width: 600px;&quot; alt=&quot;Data Architecture Test 3_2&quot; src=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_3_2.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark.conf import SparkConf
from pyspark.sql import SQLContext, SparkSession

# Spark configuration 
conf = SparkConf().setAppName(&quot;ESTest_3_2&quot;)

# Every time there is a shuffle, Spark needs to decide how many partitions will 
# the shuffle RDD have. 
# 2 times the amount of CPUS on the cluster is a good value (default is 200) 
conf.set(&quot;spark.sql.shuffle.partitions&quot;, &quot;12&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

# Query configuration only (cannot pass any ES conf here :-( )
es_query_conf= { 
    &quot;pushdown&quot;: True
}

# (1)
es_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(conf=es_query_conf) \
            .load(&quot;shakespeare*&quot;)

# (2) Compute aggregates : I want the count of lines per book
agg_df = es_df.groupBy(es_df.play_name).count()

# (3) Collect result to the driver
data_list = agg_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count 
print (&quot;Fetched %s rows (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/3_aggregation_2_spark_shakespeare.log&quot;&gt;3_aggregation_2_spark_shakespeare.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_3_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_3_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 3-2 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_3_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_3_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 3-2 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_3_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_3_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 3-2 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_3_2_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_3_2_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 3-2 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There aren&apos;t a lof of things to conclude here. We can just mention that everything works as expected and return the user to the Data Flow schematic above.&lt;/li&gt;
&lt;li&gt;Data locality kicks-in, etc.
&lt;/ul&gt;



&lt;a name=&quot;sec54&quot;&gt;&lt;/a&gt;
&lt;h3&gt;5.4 Join test&lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/4_join_1_swissdata_df.sh&quot;&gt;&lt;code&gt;4_join_1_swissdata_df.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: two datasets in fact:
&lt;ul&gt;
&lt;li&gt;
from &lt;a href=&quot;http://niceideas.ch/mes/swissairbnb/tomslee_airbnb_switzerland_1451_2017-07-11.csv&quot;&gt;http://niceideas.ch/mes/swissairbnb/tomslee_airbnb_switzerland_1451_2017-07-11.csv&lt;/a&gt; : the list of AirBnB offers in Switzerland as of July 2017.
&lt;/li&gt;
&lt;li&gt;
from &lt;a href=&quot;http://niceideas.ch/mes/swissairbnb/swisscitiespop.txt&quot;&gt;http://niceideas.ch/mes/swissairbnb/swisscitiespop.txt&lt;/a&gt; : the list of swiss cities with population and geoloc information.
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: see how the ELK-MS stack behaves when its has several datasets to load from ES into Spark and then join.
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Expected Behaviour&lt;/b&gt;
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_4_1.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;Data Architecture Test 4_1&quot; src=&quot;https://www.niceideas.ch/es_spark/images/system_archi_data_4_1.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Relevant portion of spark Script&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext, SparkSession
import pyspark.sql.functions as F

# Spark configuration 
# all these options can be given to the command line to spark-submit
# (they would need to be prefixed by &quot;spark.&quot;)
conf = SparkConf().setAppName(&quot;ESTest_4_1&quot;)

# Every time there is a shuffle, Spark needs to decide how many partitions will 
# the shuffle RDD have. 
# 2 times the amount of CPUS oi nthe cluster is a good value (default is 200) 
conf.set(&quot;spark.sql.shuffle.partitions&quot;, &quot;12&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()


# Query configuration only (cannot pass any ES conf here :-( )
es_query_conf= { 
    &quot;pushdown&quot;: True
}

# (1).1 Read city and population
citypop_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(conf=es_query_conf) \
            .load(&quot;swiss-citypop&quot;) \
            .alias(&quot;citypop_df&quot;)

# (1).2. Read airbnb offers
airbnb_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(conf=es_query_conf) \
            .load(&quot;swiss-airbnb&quot;) \
            .alias(&quot;airbnb_df&quot;)

# (2) Join on city
joint_df = airbnb_df \
            .join( \
                  citypop_df, \
                  (F.lower(airbnb_df.city) == F.lower(citypop_df.accent_city)), \
                  &quot;left_outer&quot; \
                 ) \
            .select( \
                    &apos;room_id&apos;, &apos;airbnb_df.country&apos;, &apos;airbnb_df.city&apos;, \
                    &apos;room_type&apos;, &apos;bedrooms&apos;, &apos;bathrooms&apos;, &apos;price&apos;, &apos;reviews&apos;, \
                    &apos;overall_satisfaction&apos;, \
                    &apos;airbnb_df.latitude&apos;, &apos;airbnb_df.longitude&apos;, \
                    &apos;citypop_df.latitude&apos;, &apos;citypop_df.longitude&apos;, &apos;population&apos;, \
                    &apos;region&apos; \
                   )

# (3) Collect result to the driver
data_list = joint_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count 
print (&quot;Computed %s positions (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Logs of the Spark Driver&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/4_join_1_swissdata_df.log&quot;&gt;4_join_1_swissdata_df.log&lt;/a&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;


&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_4_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_cerebro/result_4_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 4-1 / Dataset in ES&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_4_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_4_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 4-1 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_4_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_4_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 4-1 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_4_1_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_4_1_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 4-1 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;      
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_4_1_job_0_stage_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_4_1_job_0_stage_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 4-1 / Job 0 / Stage 1&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;       
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Here as well there aren&apos;t a log of things to conclude. Everything works just as expected.
&lt;/li&gt;
&lt;li&gt;
Data locality kicks-in both at the ES data fetching side and on the private Spark Side for the join.
&lt;/li&gt;
&lt;/ul&gt;


&lt;a name=&quot;sec55&quot;&gt;&lt;/a&gt;
&lt;h3&gt;5.5 Concurrency test&lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;Test details&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Test Script&lt;/b&gt;: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/tests/scenarii/5_concurrency_1_swissdata_df.sh&quot;&gt;&lt;code&gt;5_concurrency_1_swissdata_df.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Dataset&lt;/b&gt;: two datasets in fact:
&lt;ul&gt;
&lt;li&gt;
from &lt;a href=&quot;http://niceideas.ch/mes/swissairbnb/tomslee_airbnb_switzerland_1451_2017-07-11.csv&quot;&gt;http://niceideas.ch/mes/swissairbnb/tomslee_airbnb_switzerland_1451_2017-07-11.csv&lt;/a&gt; : the list of AirBnB offers in Switzerland as of July 2017.
&lt;/li&gt;
&lt;li&gt;
from &lt;a href=&quot;http://niceideas.ch/mes/swissairbnb/swisscitiespop.txt&quot;&gt;http://niceideas.ch/mes/swissairbnb/swisscitiespop.txt&lt;/a&gt; : the list of swiss cities with population and geoloc information.
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Purpose&lt;/b&gt;: see how the ELK-MS stack behaves when submitting several jobs at the same time to the cluster and what happens in terms of concurrency.
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;The Spark Script&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
The concurrency tests simply executes four times in parallel the scenario inspired from &lt;a href=&quot;#sec532&quot;&gt;5.3.2 Spark-side Aggregations&lt;/a&gt; as follows:
&lt;/p&gt;

&lt;pre&gt;
from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext, SparkSession
import pyspark.sql.functions as F

# Spark configuration 
conf = SparkConf()

# Every time there is a shuffle, Spark needs to decide how many partitions will 
# the shuffle RDD have. 
# 2 times the amount of CPUS on the cluster is a good value (default is 200) 
conf.set(&quot;spark.sql.shuffle.partitions&quot;, &quot;12&quot;)

# Spark SQL Session 
ss = SparkSession.builder \
        .config(conf=conf) \
        .getOrCreate()

# Query configuration only (cannot pass any ES conf here :-( )
es_query_conf= { 
    &quot;pushdown&quot;: True
}

# 1. Read city and population
citypop_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(conf=es_query_conf) \
            .load(&quot;swiss-citypop&quot;) \
            .alias(&quot;citypop_df&quot;)

# 2. Read airbnb offers
airbnb_df = ss.read \
            .format(&quot;org.elasticsearch.spark.sql&quot;) \
            .options(conf=es_query_conf) \
            .load(&quot;swiss-airbnb&quot;) \
            .alias(&quot;airbnb_df&quot;)

# 3. Join on city
joint_df = airbnb_df \
            .join( \
                  citypop_df, \
                  (F.lower(airbnb_df.city) == F.lower(citypop_df.accent_city)), \
                  &quot;left_outer&quot; \
                 ) \
            .select( \
                    &apos;room_id&apos;, &apos;airbnb_df.country&apos;, &apos;airbnb_df.city&apos;, \
                    &apos;room_type&apos;, &apos;bedrooms&apos;, &apos;bathrooms&apos;, &apos;price&apos;, &apos;reviews&apos;, \
                    &apos;overall_satisfaction&apos;, \
                    &apos;airbnb_df.latitude&apos;, &apos;airbnb_df.longitude&apos;, \
                    &apos;citypop_df.latitude&apos;, &apos;citypop_df.longitude&apos;, &apos;population&apos;, \
                    &apos;region&apos; \
                   )

# Collect result to the driver
data_list = joint_df.collect()

print (&quot;Printing 10 first results&quot;)
for x in data_list[0:10]:
    print x

# Print count 
print (&quot;Computed %s positions (from collected list)&quot;) % len (data_list)
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Results&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;The various logs&lt;/b&gt;: 
&lt;ul&gt;
&lt;li&gt;Logs of the script : &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/5_concurrency_1_swissdata_df.log&quot;&gt;5_concurrency_1_swissdata_df.log&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Process P1 logs : &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/log_5_concurrency_1_swissdata_1.log&quot;&gt;log_5_concurrency_1_swissdata_1.log&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Process P2 logs : &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/log_5_concurrency_1_swissdata_2.log&quot;&gt;log_5_concurrency_1_swissdata_2.log&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Process P3 logs : &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/log_5_concurrency_1_swissdata_3.log&quot;&gt;log_5_concurrency_1_swissdata_3.log&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Process P4 logs : &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_logs/log_5_concurrency_1_swissdata_4.log&quot;&gt;log_5_concurrency_1_swissdata_4.log&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;Screenshots from the various admin console after the test execution&lt;/b&gt;:
&lt;/ul&gt;

&lt;p&gt;
First the mesos console showing the completion of the 4 jobs:
&lt;/p&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_5_1_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_5_1_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P1 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_5_1_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_5_1_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P2 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_5_1_3.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_5_1_3.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P3 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_5_1_4.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_mesos/mesos_fwk_5_1_4.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P4 / Job Completion in mesos&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
Overview of the 4 processes in Spark console, the specific view of each of the process:
&lt;/p&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P1 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P2 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P3 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P4 / Process Overview on Spark&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
Focusing on Job 1 (P1), each and every relevant views from the Spark Application UI:
&lt;/p&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1_job_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1_job_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P1 / Job 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P1 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1_job_0_stage_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1_job_0_stage_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P1 / Job 0 / Stage 1&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1_job_0_stage_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_1_job_0_stage_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P1 / Job 0 / Stage 2&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
Focusing on Job 2 (P2), each and every relevant views from the Spark Application UI:
&lt;/p&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2_job_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2_job_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P2 / Job 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P2 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2_job_0_stage_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2_job_0_stage_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P2 / Job 0 / Stage 1&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2_job_0_stage_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_2_job_0_stage_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P2 / Job 0 / Stage 2&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
Focusing on Job 3 (P3), each and every relevant views from the Spark Application UI:
&lt;/p&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3_job_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3_job_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P3 / Job 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P3 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3_job_0_stage_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3_job_0_stage_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P3 / Job 0 / Stage 1&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3_job_0_stage_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_3_job_0_stage_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P3 / Job 0 / Stage 2&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
Focusing on Job 4 (P4), each and every relevant views from the Spark Application UI:
&lt;/p&gt;

&lt;div class=&quot;container-wrapper&quot;&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4_job_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4_job_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P4 / Job 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4_job_0_stage_0.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4_job_0_stage_0.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P4 / Job 0 / Stage 0&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4_job_0_stage_1.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4_job_0_stage_1.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P4 / Job 0 / Stage 1&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt; 
  &lt;figure&gt;
    &lt;a style=&quot;border: 0px none;&quot; href=&quot;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4_job_0_stage_2.png&quot;&gt;
        &lt;div class=&quot;container_inner&quot;&gt;
            &lt;img src=&apos;https://www.niceideas.ch/es_spark/sandbox/result_spark/result_5_1_4_job_0_stage_2.png&apos; /&gt;
        &lt;/div&gt;
    &lt;/a&gt;
    &lt;figcaption&gt;&lt;b&gt;Test 5-1 / P4 / Job 0 / Stage 2&lt;/b&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;   
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;b&gt;Conclusions&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Before everything else let&apos;s mention that this test has been executed, first, using the FIFO scheduler (&lt;code&gt;spark.scheduler.mode=FIFO&lt;/code&gt;) and second, using the &lt;b&gt;Dynamic allocation system&lt;/b&gt; 
&lt;/li&gt;
&lt;li&gt;
Dynamic allocation seems to work a little slower that static allocation in this case.
&lt;/li&gt;
&lt;li&gt;
With static allocation (only actual way on ES-Hadoop 5.x), what happens is that the first job that is prepared by the drivre a tiny little bit before the 3 others will get the shole cluster, and only whenever that first job is done, the three next sones will get an even share of the cluster, i.e one node each and complete almost at the same time.
&lt;/li&gt;
&lt;li&gt;
With dynamic allocation, the cluster is well shares among jobs. Once in a while a job may get an additional executor and another job will need to wait but all in all the 4 jobs really run together on the three nodes.
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
In terms of concurrency, we can see on the following image that the cluster is used quite effectively, looking at the CPU consumption on the host machine:
&lt;/p&gt;&lt;br&gt;
&lt;div class=&quot;centering&quot;&gt;
    &lt;a href=&quot;https://www.niceideas.ch/es_spark/images/concurrency_performance.png&quot;&gt;
        &lt;img class=&quot;centered&quot; style=&quot;width: 800px; &quot;  alt=&quot;Concurrency test - view of CPU&quot; src=&apos;https://www.niceideas.ch/es_spark/images/concurrency_performance.png&apos; /&gt;
    &lt;/a&gt;
    &lt;span class=&quot;centered&quot;&gt;
    (Note : each and every of the 3 VMs can use up to 2 CPUS of the host which has 4 CPUs in total)
    &lt;/span&gt;
    &lt;br&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
Also, all my tests, including this one has been executed using &lt;b&gt;Coarse Grained Scheduling Mode&lt;/b&gt; (&lt;code&gt;spark.mesos.coarse=true&lt;/code&gt;).
&lt;ul&gt;
&lt;li&gt;
One might think that using Fine Grained Mode, things would be more efficient since each and ever task would be distributed on the cluster at will and we wouldn&apos;t end up in the &lt;i&gt;static topology&lt;/i&gt; described above.
&lt;/li&gt;
&lt;li&gt;
But unfortunately, Mesos latency when it comes to negotiating resources really messes up performances. The dynamic dispatching of tasks works well, but the overall processes performances are screwed by the time Mesos requires for negotiation. 
&lt;br&gt;
In the ends, Fine Grained Scheduling mode kills performance of the whole cluster down.
&lt;/li&gt;
&lt;li&gt;
I have executed this very same test using &lt;code&gt;spark.mesos.coarse=false&lt;/code&gt; and the dropdown in terms of cluster usage efficiency is seen by looking at the &lt;a href=&quot;https://www.niceideas.ch/es_spark/images/concurrency_performance_FINE-GRAINED.png&quot;&gt;CPU consumption on the host machine for test 5 - 1 using Fine Grained Mode&lt;/a&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
In regards to data locality, since the 3 last processes get one single node of the cluster each, only one third of the tasks will execute with locality level &lt;code&gt;NODE_LOCAL&lt;/code&gt;. Two thirds of them will require to fetch data from the network.
&lt;/li&gt;
&lt;/ul&gt;

&lt;a name=&quot;sec6&quot;&gt;&lt;/a&gt;
&lt;h2&gt;6. References&lt;/h2&gt;

&lt;p&gt;
&lt;b&gt;Spark and mesos&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href=&quot;https://spark.apache.org/docs/latest/running-on-mesos.html&quot;&gt;https://spark.apache.org/docs/latest/running-on-mesos.html (specific spark mesos configuration)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;ES Hadoop doc&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Spark : &lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/hadoop/current/spark.html&quot;&gt;https://www.elastic.co/guide/en/elasticsearch/hadoop/current/spark.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Configuration : &lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/hadoop/current/configuration.html#_querying&quot;&gt;https://www.elastic.co/guide/en/elasticsearch/hadoop/current/configuration.html#_querying&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Pyspark.sql doc&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
2.2 : &lt;a href=&quot;https://spark.apache.org/docs/2.2.0/api/python/pyspark.sql.html&quot;&gt;https://spark.apache.org/docs/2.2.0/api/python/pyspark.sql.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
1.6 : &lt;a href=&quot;https://spark.apache.org/docs/1.6.2/api/python/pyspark.sql.html&quot;&gt;https://spark.apache.org/docs/1.6.2/api/python/pyspark.sql.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Spark Doc&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Configuration : &lt;a href=&quot;https://spark.apache.org/docs/latest/configuration.html&quot;&gt;https://spark.apache.org/docs/latest/configuration.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Spark history server : &lt;a href=&quot;https://spark.apache.org/docs/latest/monitoring.html&quot;&gt;https://spark.apache.org/docs/latest/monitoring.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Dynamic resource allocation : &lt;a href=&quot;https://spark.apache.org/docs/latest/job-scheduling.html#dynamic-resource-allocation&quot;&gt;https://spark.apache.org/docs/latest/job-scheduling.html#dynamic-resource-allocation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Other Pyspark specificities&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Pyspark RDD API : &lt;a href=&quot;https://spark.apache.org/docs/2.2.0/api/python/pyspark.html#pyspark.RDD&quot;&gt;https://spark.apache.org/docs/2.2.0/api/python/pyspark.html#pyspark.RDD&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Pyspark performance : &lt;a href=&quot;https://fr.slideshare.net/SparkSummit/getting-the-best-performance-with-pyspark&quot;&gt;https://fr.slideshare.net/SparkSummit/getting-the-best-performance-with-pyspark&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


</description>          </item>
    <item>
    <guid isPermaLink="true">https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana</guid>
    <title>ELK-MS - ElasticSearch/LogStash/Kibana - Mesos/Spark : a lightweight and efficient alternative to the Hadoop Stack - part I : setup the cluster</title>
    <dc:creator>Jerome Kehrli</dc:creator>
    <link>https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana</link>
        <pubDate>Wed, 23 Aug 2017 17:29:12 -0400</pubDate>
    <category>Big Data</category>
    <category>big-data</category>
    <category>elasticsearch</category>
    <category>elk</category>
    <category>elk-ms</category>
    <category>kibana</category>
    <category>logstash</category>
    <category>mesos</category>
    <category>spark</category>
    <atom:summary type="html">&lt;p&gt;
In my current company, we implement heavy Data Analytics algorithms and use cases for our customers. Historically, these heavy computations were taking a whole lot of different forms, mostly custom computation scripts in python or else using RDBMS databases to store data and results.
&lt;br&gt;
A few years ago, we started to hit the limits of what we were able to achieve using traditional architectures and had to move both our storage and processing layers to NoSQL / Big Data technologies.
&lt;/p&gt;
&lt;p&gt;
We considered a whole lot of different approaches, but eventually, and contrary to what I expected first, we didn&apos;t settle for a standard Hadoop stack. We are using ElasticSearch as key storage backend and Apache Spark as processing backend.
&lt;br&gt;
Now of course we were initially still considering a Hadoop stack for the single purpose of using YARN as resource management layer for Spark ... until we discovered Apache Mesos.
&lt;/p&gt;
&lt;p&gt;
Today this state of the art ELK-MS - for ElasticSearch/Logstash/Kibana - Mesos/Spark stack performs amazingly and I believe it to be a really &lt;b&gt;lightweight, efficient, low latency and performing&lt;/b&gt; alternative to a plain old Hadoop Stack.
&lt;br&gt;
I am writing a serie of two articles to present this stack and why it&apos;s cool.
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/technical_archi_simple.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 500px;&quot; alt=&quot;ELK-MS Simple Technical Architecture&quot; src=&quot;https://www.niceideas.ch/es_spark/images/technical_archi_simple.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana&quot;&gt;This first article - ELK-MS - part I : setup the cluster&lt;/a&gt; in this serie presents the ELK-MS stack and how to set up a test cluster using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS.tar.gz&quot;&gt;niceideas ELK-MS package&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;The second article - ELK-MS - part II : assessing behaviour&lt;/a&gt; presents a few concerns, assesses the expected behaviour using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS_TEST.tar.gz&quot;&gt;niceideas ELK-MS TEST package&lt;/a&gt; and discusses challenges and constraints in this ELK-MS environment.
&lt;/p&gt;
&lt;p&gt;
The conclusions of this serie of articles are presented in &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2&quot;&gt;the third and last article - ELK-MS - part III : so why is it cool?&lt;/a&gt; which presents, as the name suggests, why this ELK-MS stack is really really cool and works great.
&lt;/p&gt;
&lt;p&gt;
This article assumes a basic understanding of Hadoop and Big Data / NoSQL technologies in general by the reader.
&lt;/p&gt;</atom:summary>        <description>&lt;!-- ELK-MS - ElasticSearch/LogStash/Kibana - Mesos/Spark : a lightweight and efficient alternative to the Hadoop Stack - part I : setup the cluster --&gt;

&lt;p&gt;&lt;i&gt;
&lt;b&gt;Edited 2017-10-30&lt;/b&gt;: I was using ES 5.0.0 with Spark 2.2.0 at the time of writing the initial version of this article. 
&lt;br&gt;
With ElasticSearch 6.x, and ES-Hadoop 6.x, the game changes a little. The Spark 2.2.0 Dynamic allocation system is now perfectly compatible with the way ES-Hadoop 6.x enforces data locality optimization and everything works just as expected.
&lt;/i&gt;
&lt;/p&gt;

&lt;p&gt;
In my current company, we implement heavy Data Analytics algorithms and use cases for our customers. Historically, these heavy computations were taking a whole lot of different forms, mostly custom computation scripts in python or else using RDBMS databases to store data and results.
&lt;br&gt;
A few years ago, we started to hit the limits of what we were able to achieve using traditional architectures and had to move both our storage and processing layers to NoSQL / Big Data technologies.
&lt;/p&gt;
&lt;p&gt;
We considered a whole lot of different approaches, but eventually, and contrary to what I expected first, we didn&apos;t settle for a standard Hadoop stack. We are using ElasticSearch as key storage backend and Apache Spark as processing backend.
&lt;br&gt;
Now of course we were initially still considering a Hadoop stack for the single purpose of using YARN as resource management layer for Spark ... until we discovered Apache Mesos.
&lt;/p&gt;
&lt;p&gt;
Today this state of the art ELK-MS - for ElasticSearch/Logstash/Kibana - Mesos/Spark stack performs amazingly and I believe it to be a really &lt;b&gt;lightweight, efficient, low latency and performing&lt;/b&gt; alternative to a plain old Hadoop Stack.
&lt;br&gt;
I am writing a serie of two articles to present this stack and why it&apos;s cool.
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/technical_archi_simple.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 500px;&quot; alt=&quot;ELK-MS Simple Technical Architecture&quot; src=&quot;https://www.niceideas.ch/es_spark/images/technical_archi_simple.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana&quot;&gt;This first article - ELK-MS - part I : setup the cluster&lt;/a&gt; in this serie presents the ELK-MS stack and how to set up a test cluster using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS.tar.gz&quot;&gt;niceideas ELK-MS package&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;The second article - ELK-MS - part II : assessing behaviour&lt;/a&gt; presents a few concerns, assesses the expected behaviour using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS_TEST.tar.gz&quot;&gt;niceideas ELK-MS TEST package&lt;/a&gt; and discusses challenges and constraints in this ELK-MS environment.
&lt;/p&gt;
&lt;p&gt;
The conclusions of this serie of articles are presented in &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2&quot;&gt;the third and last article - ELK-MS - part III : so why is it cool?&lt;/a&gt; which presents, as the name suggests, why this ELK-MS stack is really really cool and works great.
&lt;/p&gt;
&lt;p&gt;
This article assumes a basic understanding of Hadoop and Big Data / NoSQL technologies in general by the reader.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Summary&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec1&quot;&gt;1. Introduction&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec11&quot;&gt;1.1 Rationality&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec12&quot;&gt;1.2 Purpose of this serie of articles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec2&quot;&gt;2. Target Architecture&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec21&quot;&gt;2.1 Technical Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec22&quot;&gt;2.2 Components&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec221&quot;&gt;2.2.1 ElasticSearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec222&quot;&gt;2.2.2 Logstash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec223&quot;&gt;2.2.3 Kibana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec224&quot;&gt;2.2.4 Cerebro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec225&quot;&gt;2.2.5 Spark&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec226&quot;&gt;2.2.6 Mesos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec227&quot;&gt;2.2.7 Spark on Mesos specificities&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec23&quot;&gt;2.3 Making it work together : ES-Hadoop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec24&quot;&gt;2.4 Application Architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec3&quot;&gt;3. niceideas ELK-MS&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec31&quot;&gt;3.1 System and principles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec32&quot;&gt;3.2 The build system&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec321&quot;&gt;3.2.1 Required Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec322&quot;&gt;3.2.2 Build System Project Layout&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec33&quot;&gt;3.3 Calling the build system and results&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec34&quot;&gt;3.4 Testing the System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec35&quot;&gt;3.5 Tips &amp; Tricks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec4&quot;&gt;4. Noteworthy configuration elements&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sec41&quot;&gt;4.1 NTP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec42&quot;&gt;4.2 Zookeeper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec43&quot;&gt;4.3 Elasticsearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec44&quot;&gt;4.4 Logstash, Kibana, Cerebro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec45&quot;&gt;4.5 Mesos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec46&quot;&gt;4.6 Spark&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sec47&quot;&gt;4.7 ES-Hadoop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;#sec4&quot;&gt;5. Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;a name=&quot;sec1&quot;&gt;&lt;/a&gt;
&lt;h2&gt;1. Introduction &lt;/h2&gt;

&lt;p&gt;
Actually deploying a whole Hadoop stack is, let&apos;s say, at least &lt;i&gt;heavy&lt;/i&gt;. Having HDFS, YARN, the Map Reduce framework and maybe Tez up and running is one thing, and it&apos;s maybe not that complicated, sure. 
&lt;/p&gt;
&lt;p&gt;
But with such a &lt;i&gt;vanilla&lt;/i&gt; stack you&apos;re not going very far. You&apos;ll at least add the following minimal set of software components: &lt;a href=&quot;http://sqoop.apache.org/&quot;&gt;Apache Sqoop&lt;/a&gt; for importing data in your HDFS cluster, &lt;a href=&quot;https://pig.apache.org/&quot;&gt;Apache Pig&lt;/a&gt; for processing this data, &lt;a href=&quot;https://hive.apache.org/&quot;&gt;Apache Hive&lt;/a&gt; for querying it. But yeah, then, Hive is so slow for small queries returning small datasets, you&apos;ll likely add Stinger ... and then a whole lot of other components.
&lt;br&gt;
Now setting all of these software components up and running and tuning them well is a real hassle so one might consider a HortonWorks or Cloudera distribution instead, and this is where it gets really heavy.
&lt;br&gt;
Don&apos;t get me wrong, both HortonWorks and Cloudera are doing an amazing job and their distributions are awesome.
&lt;br&gt;
But I am working in a context where we want something lighter, something more efficient, something easier to set up, master and monitor.
&lt;/p&gt;
&lt;p&gt;
In addition, HDFS is great. But it&apos;s really only about distributed storage of data. Vanilla Hadoop doesn&apos;t really provide anything on top of this data aside from MapReduce. On the other hand, the NoSQL landscape is filled with plenty of solutions achieving the same resilience and performance than HDFS but providing advanced data querying features on top of this data.
&lt;br&gt;
Among all these solutions, &lt;a href=&quot;https://www.elastic.co/products/elasticsearch&quot;&gt;ElasticSearch&lt;/a&gt; is the &lt;i&gt;one stop shop&lt;/i&gt; for our use cases. It fulfills 100% of our requirements and provides us out of the box with all the querying features we require (and some striking advanced features).
&lt;br&gt;
Using ElasticSearch for our data storage needs, we have no usage whatsoever for HDFS. 
&lt;br&gt;
In addition, ElasticSearch comes out of the box with a pretty awesome replacement of Sqoop: &lt;a href=&quot;https://www.elastic.co/products/logstash&quot;&gt;Logstash&lt;/a&gt; and a brilliant Data Visualization tool that has no free alternative in the Hadoop world: &lt;a href=&quot;https://www.elastic.co/products/kibana&quot;&gt;Kibana&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Now regarding Data Processing, here as well we found our &lt;i&gt;one stop shop&lt;/i&gt; in the form of &lt;a href=&quot;https://spark.apache.org/&quot;&gt;Apache Spark&lt;/a&gt;. Spark is a (vary) fast and general engine for large-scale data processing. At the ground of our processing needs, there is not one single use case we cannot map easily and naturally to Spark&apos;S API, either using low level RDDs or using the DataFrame API (SparkSQL).
&lt;/p&gt;
&lt;p&gt;
Now Spark requires some external scheduler and resources manager. It can run without it of course but fails in achieving concurrency when doing so. 
&lt;br&gt;
We were seriously considering deploying Hadoop and YARN for this until we discovered &lt;a href=&quot;http://mesos.apache.org/&quot;&gt;Apache Mesos&lt;/a&gt;. Mesos is a distributed systems kernel built using the same principles as the Linux kernel, only at a different level of abstraction. The Mesos kernel runs on every machine and provides Spark with API’s for resource management and scheduling across entire Data-center and cloud environments.
&lt;/p&gt;


&lt;a name=&quot;sec11&quot;&gt;&lt;/a&gt;
&lt;h3&gt;1.1 Rationality &lt;/h3&gt;

&lt;p&gt;
I call the software stack formed by the above components the ELK-MS stack, for &lt;i&gt;ElasticSearch/LogStash/Kibana - Mesos/Spark&lt;/i&gt;. 
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;The ELK-MS stack is a simple, lightweight, efficient, low-latency and performing alternative to the Hadoop stack providing state of the art Data Analytics features&lt;/b&gt;:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;lightweight&lt;/b&gt; : ELK-MS is lightweight both in terms of &lt;i&gt;setup&lt;/i&gt; and &lt;i&gt;runtime&lt;/i&gt;. 
&lt;br&gt;
In terms of setup, the distributed storage engine, ElasticSearch, the resource manager, Mesos, and the distributed processing engine, spark, are amazingly easy to setup and configure. They really work almost out of the box and only very few configuration properties have to be set when it comes to configuring resources in Mesos, honestly trying to optimize anything other than the default value really tends to worsen things. 
&lt;br&gt;
In terms of runtime, ElasticSearch, Mesos and some components of Spark, the only long-running daemons have a very low memory footprint under low workload. Now of course, both ElasticSearch and Spark have pretty heavy memory needs when working.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;efficient&lt;/b&gt; : ElasticSearch, in contrary to HDFS, is not just a wide and simple distributed storage engine. ElasticSearch is in addition a real-time querying engine. It provides pretty advanced features such as aggregations and, up to a certain level, even distributed processing (scripted fields or else). With ELK-MS, the storage layer itself provides basic data analytics features.
&lt;br&gt;
In addition, Spark supports through the RDD API most if not all of what we can achieve using low-level Map Reduce. It obviously also supports plain old MapReduce. But the really striking feature of Spark is the DataFrame API and SparqSQL.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;low-latency&lt;/b&gt; : Spark is by design much faster than Hadoop. In addition, jobs on spark can be implemented in such as way that the processing time and job initialization time is much shorter than on Hadoop MapReduce (Tez makes things more even on Hadoop though). &lt;br&gt;
But there again Spark has a joker: the Spark Streaming extension.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;performing&lt;/b&gt; : in addition to the above, both ElasticSearch and Spark share a common gene, not necessarily widely spread among the NoSQL landscape: the capacity to benefit as much from a big cluster with thousands of nodes than from a big machine with a hundreds of processor. 
&lt;br&gt;
Spark and ElasticSearch are very good on a large cluster of small machines (and to be honest, the scaling out is really the preferred way to achieve optimal performance with both).
&lt;br&gt;
&lt;b&gt;But in contrary to Hadoop, both Spark and ElasticSearch also works pretty good on a single fat machine with hundreds of processors&lt;/b&gt;, able to benefit from the multi-processor architecture of one single machine.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1#sec3&quot;&gt;conclusions of the behaviour assessment tests&lt;/a&gt;, at the end of the second article, as well as The &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2&quot;&gt;conclusion of this serie of articles&lt;/a&gt; give some more leads on why the ELK-MS stack is cool.
&lt;/p&gt;
&lt;p&gt;
For these reasons, we are extensively using the ELK-MS stack for our Data Analytics needs in my current company.
&lt;/p&gt;


&lt;a name=&quot;sec12&quot;&gt;&lt;/a&gt;
&lt;h3&gt;1.2 Purpose of this serie of articles&lt;/h3&gt;

&lt;p&gt;
Setting up the ELK-MS stack in a nominal working mode is easy, but still requires a few steps. In addition, when assessing the stack and for testing purpose, I needed a way to setup a cluster and test key features such as optimization of data-locality between ElasticSearch and Spark.
&lt;/p&gt;
&lt;p&gt;
I have written a set of scripts taking care of the nominal setup and a test framework based on &lt;a href=&quot;https://www.vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt; and &lt;a href=&quot;https://www.virtualbox.org/&quot;&gt;VirtualBox&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana&quot;&gt;This first article - ELK-MS - part I : setup the cluster&lt;/a&gt; in this serie presents the ELK-MS stack and how to set up a test cluster using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS.tar.gz&quot;&gt;niceideas ELK-MS package&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;The second article - ELK-MS - part II : assessing behaviour&lt;/a&gt; presents a few concerns, assesses the expected behaviour using the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS_TEST.tar.gz&quot;&gt;niceideas ELK-MS TEST package&lt;/a&gt; and discusses challenges and constraints in this ELK-MS environment.
&lt;/p&gt;
&lt;p&gt;
The conclusions of this serie of articles are presented in &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana2&quot;&gt;the third and last article - ELK-MS - part III : so why is it cool?&lt;/a&gt; which presents, as the name suggests, why this ELK-MS stack is really really cool and works great.
&lt;/p&gt;



&lt;a name=&quot;sec2&quot;&gt;&lt;/a&gt;
&lt;h2&gt;2. Target Architecture &lt;/h2&gt;

&lt;p&gt;
Before presenting the components and some noteworthy configuration aspects, let&apos;s dig into the architecture of the ELK-MS stack.
&lt;/p&gt;

&lt;a name=&quot;sec21&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.1 Technical Architecture&lt;/h3&gt;

&lt;p&gt;
The &lt;b&gt;technical architecture&lt;/b&gt; of the ELK-MS stack is as follows
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/technical_archi_master.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px; &quot; alt=&quot;ELK-MS Technical Architecture&quot; src=&quot;https://www.niceideas.ch/es_spark/images/technical_archi_master.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
The components in grey are provided out of the box at OS level by &lt;b&gt;Debian Stretch&lt;/b&gt; distribution. 
&lt;br&gt;
The components in yellow are provided by Elastic in the ELK Stack.
&lt;br&gt;
Mesos is in light red.
&lt;br&gt;
The components in blue are from the Spark Framework.
&lt;/p&gt;
&lt;p&gt;
Let&apos;s present all these components.
&lt;/p&gt;

&lt;a name=&quot;sec22&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.2 Components&lt;/h3&gt;

&lt;p&gt;
This section presents the most essential components of the ELK-MS stack.
&lt;/p&gt;


&lt;a name=&quot;sec221&quot;&gt;&lt;/a&gt;
&lt;h4&gt;2.2.1 ElasticSearch&lt;/h4&gt;


&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;ElasticSearch Logo&quot; src=&quot;https://www.niceideas.ch/es_spark/images/elasticsearch_logo.png&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
From &lt;a href=&quot;https://www.elastic.co/products/elasticsearch&quot;&gt;ElasticSearch&apos;s web site&lt;/a&gt; : &quot;&lt;i&gt;ElasticSearch is a distributed, RESTful search and analytics engine capable of solving a growing number of use cases. As the heart of the Elastic Stack, it centrally stores your data so you can discover the expected and uncover the unexpected.&lt;/i&gt;&quot;
&lt;/p&gt;
&lt;p&gt;
ElasticSearch is a NoSQL Document-oriented database benefitting from the NoSQL Genes: data distribution by sharding (partitioning) and replication. It can run on all kind of hardware, from a big fat hundred CPUs machine to a multi-data centers cluster of commodity hardware.
&lt;br&gt;
The native document storage format is JSON.
&lt;/p&gt;
&lt;p&gt;
ElasticSearch support real-time querying of data and advanced analytics features such as aggregation, scripted fields, advanced memory management models and even some support for MapReduce directly in ElasticSearch&apos;s engine.
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;a name=&quot;sec222&quot;&gt;&lt;/a&gt;
&lt;h4&gt;2.2.2 Logstash&lt;/h4&gt;


&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;Logstash Logo&quot; src=&quot;https://www.niceideas.ch/es_spark/images/logstash_logo.png&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
From &lt;a href=&quot;https://www.elastic.co/products/logstash&quot;&gt;Logstash&apos;s web site&lt;/a&gt; : &quot;&lt;i&gt;Logstash is an open source, server-side data processing pipeline that ingests data from a multitude of sources simultaneously, transforms it, and then sends it to your favorite &quot;stash.&quot; (Ours is Elasticsearch, naturally.).&lt;/i&gt;&quot;
&lt;/p&gt;
&lt;p&gt;
Logstash is really the equivalent of Sqoop in the Elastic world. It&apos;s a largely configurable data processing engine whose primary intent is to feed ElasticSearch with data that can come from pretty much all imaginable data sources and formats. Of course Logstash can also output data to a very extended set of sinks in addition to ElasticSearch.
&lt;br&gt;
It&apos;s easily extendable through plugins which are straightforward to build, should the 200 provided plugins not be sufficient.
&lt;/p&gt;
&lt;p&gt;
Logstash can also be distributed just as ElasticSearch, enabling not only to scale out the data ingestion processing but also enabling smart co-location strategies with ElasticSearch.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;a name=&quot;sec223&quot;&gt;&lt;/a&gt;
&lt;h4&gt;2.2.3 Kibana&lt;/h4&gt;

&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;Kibana Logo&quot; src=&quot;https://www.niceideas.ch/es_spark/images/kibana_logo.png&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
From &lt;a href=&quot;https://www.elastic.co/products/kibana&quot;&gt;Kibana&apos;s web site&lt;/a&gt; : &quot;&lt;i&gt;Kibana lets you visualize your ElasticSearch data and navigate the Elastic Stack, so you can do anything from learning why you&apos;re getting paged at 2:00 a.m. to understanding the impact rain might have on your quarterly numbers.&lt;/i&gt;&quot;
&lt;/p&gt;
&lt;p&gt;
Kibana core ships with the classics: histograms, line graphs, pie charts, sunbursts, and more. They leverage the full aggregation capabilities of ElasticSearch.
&lt;br&gt;
Kibana as well is easily extendable and integrating any kind of native D3.js visualization is usually done in a few hours of coding.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;In the context of ELK-MS&lt;/b&gt;, Kibana is an amazing addition to ElasticSearch, since we can write Spark programs that work with data from ES but also stores their results in ES. As such, Kibana can be used out of the box to visualize not only the input data but also the results of the Spark scripts.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;a name=&quot;sec224&quot;&gt;&lt;/a&gt;
&lt;h4&gt;2.2.4 Cerebro&lt;/h4&gt;

&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;Cerebro Logo&quot; src=&quot;https://www.niceideas.ch/es_spark/images/cerebro_logo.png&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
From &lt;a href=&quot;https://github.com/lmenezes/cerebro&quot;&gt;Cerebro&apos;s web site&lt;/a&gt; : &quot;&lt;i&gt;Cerebro is an open source(MIT License) ElasticSearch web admin tool built using Scala, Play Framework, AngularJS and Bootstrap..&lt;/i&gt;&quot;
&lt;/p&gt;
&lt;p&gt;
Cerebro is the one-stop-shop, little and simple but efficient, monitoring and administration tool for ElasticSearch.
&lt;/p&gt;
&lt;p&gt;
Cerebro is a must have with ElasticSearch since working only with the REST API to understand ElasticSearch&apos;s topology and perform most trivial administration tasks (such as defining mapping templates, etc.) is a real hassle.
&lt;br&gt;
Cerebro is far from perfect but really does the job.
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;a name=&quot;sec225&quot;&gt;&lt;/a&gt;
&lt;h4&gt;2.2.5 Spark&lt;/h4&gt;

&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;Spark Logo&quot; src=&quot;https://www.niceideas.ch/es_spark/images/spark_logo.png&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
From &lt;a href=&quot;https://spark.apache.org/&quot;&gt;Spark&apos;s web site&lt;/a&gt; : &quot;&lt;i&gt;Apache Spark is a fast and general engine for large-scale data processing.&lt;/i&gt;&quot;
&lt;/p&gt;
&lt;p&gt;
From &lt;a href=&quot;https://en.wikipedia.org/wiki/Apache_Spark&quot;&gt;Wikipedia&apos;s Spark article&lt;/a&gt;: &quot;&lt;i&gt;Apache Spark provides programmers with an application programming 
interface centered on a data structure called the resilient distributed dataset (RDD), a read-only multiset of data items distributed over a cluster of machines, 
that is maintained in a fault-tolerant way.&lt;/i&gt;
&lt;br&gt;
&lt;i&gt;It was developed in response to limitations in the MapReduce cluster computing paradigm, which forces a particular linear dataflow structure on distributed programs: MapReduce programs read input data from disk, map a function across the data, reduce the results of the map, and store reduction results on disk. Spark&apos;s RDDs function as a working set for distributed programs that offers a (deliberately) restricted form of distributed shared memory.&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;The availability of RDDs facilitates the implementation of both iterative algorithms, that visit their dataset multiple times in a loop, and interactive/exploratory data analysis, i.e., the repeated database-style querying of data. The latency of such applications (compared to a MapReduce implementation, as was common in Apache Hadoop stacks) may be reduced by several orders of magnitude.&lt;/i&gt;&quot;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;a name=&quot;sec226&quot;&gt;&lt;/a&gt;
&lt;h4&gt;2.2.6 Mesos&lt;/h4&gt;

&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;Mesos Logo&quot; src=&quot;https://www.niceideas.ch/es_spark/images/mesos_logo.png&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
From &lt;a href=&quot;http://mesos.apache.org/&quot;&gt;Mesos&apos; web site&lt;/a&gt; : &quot;&lt;i&gt;Apache Mesos abstracts CPU, memory, storage, and other compute resources away from machines (physical or virtual), enabling fault-tolerant and elastic distributed systems to easily be built and run effectively.&lt;/i&gt;
&lt;br&gt;
&lt;i&gt;Mesos is a distributed systems kernel, built using the same principles as the Linux kernel, only at a different level of abstraction. The Mesos
kernel runs on every machine and provides applications (e.g., Hadoop, Spark, Kafka, Elasticsearch) with API’s for
resource management and scheduling across entire Datacenter and cloud environments.&lt;/i&gt;&quot;
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;In the context of ELK-MS&lt;/b&gt;, and in a general way when considering running Spark in a production environment, Mesos is the way to go if one doesn&apos;t want to deploy a full Hadoop stack to support Spark. In the end, it appears that Mesos performs amazingly, both by suffering only form a very small memory footprint on the cluster and by being incredibly easy to setup and administer.
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;a name=&quot;sec227&quot;&gt;&lt;/a&gt;
&lt;h4&gt;2.2.7 Spark on Mesos specificities&lt;/h4&gt;

&lt;p&gt;
Happily Spark and Mesos, both products from the Apache fundation, know about each other and are designed to work with each other.
&lt;br&gt;
There are some specificities though when it comes to run Spark on Mesos as opposed to running Spark on the more usual YARN, as explained below,
&lt;/p&gt;

&lt;b&gt;Spark Mesos Dispatcher&lt;/b&gt;


&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;Spark Mesos Dispatcher Logo&quot; src=&quot;https://www.niceideas.ch/es_spark/images/spark-mesos-dispatcher_logo.png&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
Interestingly, mesos handles spark workers in a pretty amazing way. Not only does Mesos consider &lt;i&gt;node locality&lt;/i&gt; requirements between spark and ElasticSearch, but Mesos also provides required retry policies and else.
&lt;/p&gt;
&lt;p&gt;
When launching a spark job, there is nevertheless one &lt;i&gt;Single Point of Failure&lt;/i&gt; that remains: the spark driver that lives outside of the Mesos/Spark cluster, on the machine it is launched by the user or the driving process.
&lt;/p&gt;
&lt;p&gt;
For this reason, spark provides the &lt;b&gt;Spark Mesos Dispatcher&lt;/b&gt; that can be used to &lt;b&gt;dispatch the Spark Driver itself on the Mesos/Spark cluster&lt;/b&gt;.
&lt;br&gt;
Using the &lt;i&gt;Spark Mesos Dispatcher&lt;/i&gt;, the driver itself, just as the spark processing is balanced on the cluster to an available node and can be supervised (retried, monitored in terms of memory consumption, etc.).
&lt;/p&gt;
&lt;p&gt;
The &lt;i&gt;Spark Mesos Dispatcher&lt;/i&gt; addresses the single weakness of a spark process: the driver that can crash or exhaust resources and handles it just as any other bit of spark processing.
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;
&lt;b&gt;Spark History Server&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
In contrary to spark running in standalone mode, when spark runs on Mesos, it has no long life running backend that the user can use to interact with when Spark is not actually executing a job. 
&lt;br&gt;
Mesos takes care of creating and dispatching Spark workers when required. When no Spark job is being executed, there is no spark process somewhere one can interact with to query, for instance, the results of a previous job.
&lt;/p&gt;
&lt;p&gt;
Happily spark provides a solution out of the box for this : the &lt;b&gt;spark History Server&lt;/b&gt;.
&lt;br&gt;
The Spark History Server is a lightweight process that presents the results stored in the Spark &lt;i&gt;Event Log folder&lt;/i&gt;, that folder on the filesystem where Spark stores consolidated results from the various workers. 
&lt;br&gt;
The documentation of Spark is very unclear about this, but since only the spark driver stores consolidated results in the &lt;i&gt;event log folder&lt;/i&gt;, if all drivers are launched on the same machine (for instance the Mesos master machine), there is no specific needs for HDFS.
&lt;/p&gt;
&lt;p&gt;
One should note that running the Spark History Server without HDFS to store the event log can be a problem if one uses the &lt;i&gt;Spark Mesos Dispatcher&lt;/i&gt; to distribute the driver program itself on the Mesos cluster. In this case using a common NFS share for instance would solve the problem.
&lt;/p&gt;

&lt;a name=&quot;sec23&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.3. Making it work together : ES-Hadoop&lt;/h3&gt;


&lt;table style=&quot;border: 0px none;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100px; border: 0px none;&quot;&gt;
&lt;img style=&quot;width: 100px; min-width: 100px; border: 0px none;&quot; alt=&quot;ES-Hadoop Logo&quot; src=&quot;https://www.niceideas.ch/es_spark/images/es-hadoop_logo.png&quot; /&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 100%; border: 0px none;&quot;&gt;
&lt;p&gt;
From &lt;a href=&quot;https://www.elastic.co/products/hadoop&quot;&gt;ES-Hadoop&apos;s web site&lt;/a&gt; : &quot;&lt;i&gt;Connect the massive data storage and deep processing power of Hadoop with the real-time search and analytics of Elasticsearch. The Elasticsearch-Hadoop (ES-Hadoop) connector lets you get quick insight from your big data and makes working in the Hadoop ecosystem even better.&lt;/i&gt;&quot;
&lt;/p&gt;
&lt;p&gt;
Initially ES-Hadoop contains the set of classes implementing the connectors for pretty much all &lt;i&gt;de facto &quot;standards&quot;&lt;/i&gt; components of a full hadoop stack, such as Hive, Pig, Spark, etc.
&lt;br&gt;
Interestingly, as far as Spark is concerned, Spark can perfectly use ES-Hadoop to load from or store data to ElasticSearch &lt;b&gt;outside of an Hadoop stack&lt;/b&gt;. In fact, the spark connector from the ES-Hadoop library has no dependency on a Hadoop stack whatsoever.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;In the context of ELK-MS, the ES-Hadoop connector is one of the most important components.&lt;/b&gt; When one considers building a large collocated ES / Mesos / Spark cluster and execute tasks requiring to fetch large datasets from ES to Spark, the &lt;b&gt;data-locality knowledge&lt;/b&gt; supported by ES-Hadoop is utmost important. The &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;second article of this serie&lt;/a&gt; is largely devoted to assessing how and how far the optimization of data-locality works.
&lt;/p&gt;
&lt;p&gt;
When launching a job using Spark, the connector determines the locations of the shards in ElasticSearch that it will be targeting and creates a partition per shard (or even further to allow for greater parallelism). Each of these partition definitions carries with it the index name, the shard id, the slice id and the addresses of the machines where it can find this data on locally. It then relies on Spark&apos;s task scheduling to achieve data locality.
&lt;br&gt;
Spark will stand up a task for each of the input partitions, and each reading task is pinned to a node that is hosting the shards. This just means that the task will always try to read from that node first, but will target other nodes if that node fails the processing or fails from becoming available before the timeout.
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;a name=&quot;sec24&quot;&gt;&lt;/a&gt;
&lt;h3&gt;2.4 Application Architecture&lt;/h3&gt;

&lt;p&gt;
Typical Data Flows on the ELK-MS platform is illustrated by the following &lt;b&gt;Application Architecture&lt;/b&gt; schema:
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/application_architecture.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 600px;&quot; alt=&quot;ELK-MS Application Architecture&quot; src=&quot;https://www.niceideas.ch/es_spark/images/application_architecture.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
The tests presented &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;&quot;in the second article in this serie: ELK-MS - part II : assessing behaviour&quot;&lt;/a&gt; are intended to assess the well behaviour of this application architecture.
&lt;/p&gt;


&lt;a name=&quot;sec3&quot;&gt;&lt;/a&gt;
&lt;h2&gt;3. niceideas ELK-MS&lt;/h2&gt;

&lt;p&gt;
So. Again as stated in introduction before, when playing with ES / Mesos / Spark, it happened quite fast that I got two urgent needs:
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
First, I needed a &lt;b&gt;reference for configuring the various software&lt;/b&gt; so that they work well together. Instead of writing pages of documentation indicating the settings to tune, I ended up putting all of that in setup scripts aimed at helping me re-apply the configuration at will.
&lt;/li&gt;
&lt;li&gt;
Second, I needed a &lt;b&gt;test cluster&lt;/b&gt; allowing me to assess how various key features were working, among which ensuring optimization of data-locality was one of the most important.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
In the end I wrote a set of scripts using Vagrant and VirtualBox aimed at making it possible for me to rebuild the test cluster and reapply the configuration at will. I packaged all these scripts together and call this package the &lt;b&gt;niceideas_ELK-MS&lt;/b&gt; package.
&lt;/p&gt;
&lt;p&gt;
This package is &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS.tar.gz&quot;&gt;available for download here&lt;/a&gt;.
&lt;/p&gt;


&lt;a name=&quot;sec31&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.1 System and principles&lt;/h3&gt;

&lt;p&gt;
The &lt;b&gt;System Architecture&lt;/b&gt; of the ELK-MS platform as build by the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package is as follows:
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/system_archi.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 400px;&quot; alt=&quot;ELK-MS System Architecture&quot; src=&quot;https://www.niceideas.ch/es_spark/images/system_archi.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;ul&gt;
&lt;li&gt;
The master node, &lt;b&gt;MES Master&lt;/b&gt; (for Mesos/Elasticsearch/Spark) is called &lt;code&gt;mes_master&lt;/code&gt;. It contains the full stack of software including the management UIs. The Master node is also a data node.
&lt;/li&gt;
&lt;li&gt;
The two data nodes, &lt;b&gt;MES Slave X&lt;/b&gt; are called &lt;code&gt;mes_node1&lt;/code&gt; and &lt;code&gt;mes_node2&lt;/code&gt;. They only provide an ElasticSearch instance and a Mesos worker instance to drive Spark Executors.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Having two possible &lt;i&gt;Mesos Masters&lt;/i&gt; is not considered for now but the technical stack is deployed with this possibility wide open by using zookeeper to manage mesos masters.
&lt;/p&gt;


&lt;a name=&quot;sec32&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.2 The build system&lt;/h3&gt;

&lt;p&gt;
The remainder of this section is a description of the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package build system and a presentation of the expected results.
&lt;/p&gt;

&lt;a name=&quot;sec321&quot;&gt;&lt;/a&gt;
&lt;h4&gt;3.2.1 Required Tools&lt;/h4&gt;

&lt;p&gt;
First the build system is really intended to work on Linux, but would work as well on Windows except that vagrant commands need to be called directly.
&lt;/p&gt;
&lt;p&gt;
But before digging into this, the following tools need to be installed and properly working on the host machine where the ELK-MS test cluster has to be built:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;VirtualBox&lt;/b&gt;: is an x86 and AMD64/Intel64 virtualization solution.
&lt;br&gt;
The &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package will build a cluster of nodes taking the form of VMs running on the host machine (the user computer).
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Vagrant&lt;/b&gt;: is a tool for building and managing virtual machine environments in a single workflow.
&lt;br&gt;
The &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package uses Vagrant to build and manage the VMs without any user interaction required and to drive the provisioning scripts execution.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;vagrant-reload&lt;/b&gt; vagrant plugin is require to reload the machines after some changes applied by the provisionning scripts requiring a VM reboot.
&lt;br&gt;
See &lt;a href=&quot;https://github.com/aidanns/vagrant-reload/blob/master/README.md&quot;&gt;https://github.com/aidanns/vagrant-reload/blob/master/README.md&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;


&lt;a name=&quot;sec322&quot;&gt;&lt;/a&gt;
&lt;h4&gt;3.2.2 Build System Project Layout&lt;/h4&gt;

&lt;p&gt;
The &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package structure, after being properly extracted in a local folder, is as follows:
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/provisionning.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 300px;&quot; alt=&quot;ELK-MS Provisionning&quot; src=&quot;https://www.niceideas.ch/es_spark/images/provisionning.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;./setup.sh&lt;/code&gt;: basically takes care of everything by calling vagrant to build the 3 VMs
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;./vagrant/VagrantFile&lt;/code&gt;: vagrant definition file to define the 3 VMs and the provisioning scripts
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;./provisionning/*&lt;/code&gt;: the provisoning scripts. The entry point is &lt;code&gt;setup.sh&lt;/code&gt; that calls each and every other script.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Rationality&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
In a DevOps world, there are better tools than shell scripts to proceed with VM or machine provisioning, such as Ansible, Chef, Puppet, etc.
&lt;br&gt;
But in my case, I want it to be possible for me to go on any VM, any machine and re-apply my configuration to Spark, Mesos, ElasticSearch or else by simply calling a shell script with a few arguments.
&lt;br&gt;
So even though there are more efficient alternatives, I kept shell scripts here for the sake of simplicity.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Building the ELK-MS test cluster on Windows&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
With VirtualBox and Vagrant properly installed on Windows, nothing should prevent someone from building the cluster on Windows.
&lt;br&gt;
But in this case, of course, the root scripts &lt;code&gt;setup.sh&lt;/code&gt;, &lt;code&gt;start_cluster.sh&lt;/code&gt;, &lt;code&gt;stop_cluster.sh&lt;/code&gt; are not usable (or else cygwin ? MingW ?).
&lt;/p&gt;
&lt;p&gt;
In this case, the user should call vagrant manually to build the 3 VMs &lt;code&gt;mes_master&lt;/code&gt;, &lt;code&gt;mes_node1&lt;/code&gt; and &lt;code&gt;mes_node2&lt;/code&gt; as follows:
&lt;/p&gt;

&lt;pre&gt;
c:\niceideas_ELK-MS\vagrant&gt; vagrant up mes_master
...
c:\niceideas_ELK-MS\vagrant&gt; vagrant up mes_node1
...
c:\niceideas_ELK-MS\vagrant&gt; vagrant up mes_node2
...
&lt;/pre&gt;


&lt;a name=&quot;sec33&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.3 Calling the build system and results&lt;/h3&gt;

&lt;p&gt;
Again, calling the build system to fully build the cluster, on Linux, is as simple as:
&lt;/p&gt;

&lt;pre&gt;
badtrash@badbook:/data/niceideas_ELK-MS/setup$ ./setup.sh 
&lt;/pre&gt;

&lt;p&gt;
A full dump of the result of the &lt;code&gt;setup.sh&lt;/code&gt; script is &lt;a href=&quot;http://www.niceideas.ch/es_spark/setuplog.html&quot;&gt;available here&lt;/a&gt;.
&lt;/p&gt;

&lt;a name=&quot;sec34&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.4 Testing the System&lt;/h3&gt;

&lt;p&gt;
After calling the &lt;code&gt;setup.sh&lt;/code&gt; script above, the 3 VMs are properly created, as one can check in VirtualBox:
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/virtualbox_manager.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 500px;&quot; alt=&quot;The three VMs in VirtualBox Manager&quot; src=&quot;https://www.niceideas.ch/es_spark/images/virtualbox_manager.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
In addition, the 4 UI applications should be available at following addresses (caution, the links below return to your cluster, not niceideas.ch):
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href=&quot;http://192.168.10.10:9000/#/overview?host=http:%2F%2Flocalhost:9200&quot;&gt;Cerebro on http://192.168.10.10:9000/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;http://192.168.10.10:5050/&quot;&gt;Mesos Console on http://192.168.10.10:5050/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;http://192.168.10.10:18080/&quot;&gt;Spark History Server on http://192.168.10.10:18080/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;http://192.168.10.10:5601/&quot;&gt;Kibana on http://192.168.10.10:5601/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;b&gt;Cerebro:&lt;/b&gt; (&lt;a href=&quot;http://192.168.10.10:9000/#/overview?host=http:%2F%2Flocalhost:9200&quot;&gt;http://192.168.10.10:9000/&lt;/a&gt;)
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/cerebro_empty.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 750px; &quot; alt=&quot;Cerebro - ES management&quot; src=&quot;https://www.niceideas.ch/es_spark/images/cerebro_empty.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
(One can see the 3 nodes available)
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Mesos:&lt;/b&gt; (&lt;a href=&quot;http://192.168.10.10:5050/&quot;&gt;http://192.168.10.10:5050/&lt;/a&gt;)
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/mesos_agents.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 750px; &quot; alt=&quot;Mesos - the 3 agents&quot; src=&quot;https://www.niceideas.ch/es_spark/images/mesos_agents.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
(One can see the 3 nodes available)
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Spark History Server:&lt;/b&gt; (&lt;a href=&quot;http://192.168.10.10:18080/&quot;&gt;http://192.168.10.10:18080/&lt;/a&gt;)
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/history_server.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 750px; &quot; alt=&quot;Spark History Server&quot; src=&quot;https://www.niceideas.ch/es_spark/images/history_server.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;b&gt;Kibana:&lt;/b&gt; (&lt;a href=&quot;http://192.168.10.10:5601/&quot;&gt;http://192.168.10.10:5601/&lt;/a&gt;)
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;a href=&quot;https://www.niceideas.ch/es_spark/images/kibana_empty.png&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 750px; &quot; alt=&quot;Spark History Server&quot; src=&quot;https://www.niceideas.ch/es_spark/images/kibana_empty.png&quot; /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;a name=&quot;sec36&quot;&gt;&lt;/a&gt;
&lt;h3&gt;3.5 Tips &amp; Tricks&lt;/h3&gt;

&lt;p&gt;
&lt;b&gt;This closes the presentation of the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package. The remainder of this article gives some hints regarding the configuration of the different software components&lt;/b&gt;.
&lt;br&gt;
Readers interested in understanding what the build system of &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; presented above does without the hassle of analyzing the setup scripts can continue reading hereunder.
&lt;br&gt;
Reader interested only in understanding the cluster layout and the concerns of the ES / Spark integration can move to &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;the second article in this serie: ELK-MS - part II : assessing behaviour&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Killing a stuck job&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Once in a while, for various reasons, a job gets stuck. In this case the easiest way to kill it is using the Spark Web console.
&lt;br&gt;
But wait, hold on, you just said above that such a console is not available when running through Mesos ?
&lt;br&gt;
Well actually, the Spark console is available as long as the spark job is alive ... which is the case, happily, when a spark job is stuck.
&lt;/p&gt;
&lt;p&gt;
So one can follow the link provided by Mesos on the Spark console and use the usual &lt;i&gt;kill&lt;/i&gt; link from there.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Spark fine grained scheduling by Mesos&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
When reading about Mesos &lt;i&gt;fine grained&lt;/i&gt; scheduling of spark job, one might think it makes sense to give it a try ... don&apos;t!
&lt;/p&gt;
&lt;p&gt;
Spark &lt;i&gt;fine grained&lt;/i&gt; scheduling by Mesos is really really messed up. 
&lt;br&gt;
One might believe that it helps concurrency and better resource allocation but it really doesn&apos;t, In practice what happens is that an amazing proportion of time is lost scheduling all the individual spark tasks, plus it often compromises co-location of data between ES and Spark.
&lt;/p&gt;
&lt;p&gt;
It&apos;s even deprecated in the latest spark versions.
&lt;br&gt;
More information in this regards is available here: &lt;a href=&quot;https://issues.apache.org/jira/browse/SPARK-11857&quot;&gt;https://issues.apache.org/jira/browse/SPARK-11857&lt;/a&gt;.
&lt;/p&gt;

&lt;a name=&quot;sec4&quot;&gt;&lt;/a&gt;
&lt;h2&gt;4. Noteworthy configuration elements&lt;/h2&gt;

&lt;p&gt;
The below presents the important configuration aspects taken care of by the provisioning scripts.
&lt;/p&gt;

&lt;a name=&quot;sec41&quot;&gt;&lt;/a&gt;
&lt;h3&gt;4.1 NTP&lt;/h3&gt;

&lt;p&gt;
Related scripts from the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuration script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/setupNTP.sh&quot;&gt;&lt;code&gt;&lt;/code&gt;setupNTP.sh&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Just as with every big data or NoSQL cluster, having a shared common understanding of time in the cluster is key. So NTP needs to be properly set up.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;On master &lt;code&gt;mes_master&lt;/code&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Sample portion from &lt;code&gt;/etc/ntp.conf&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;
pool ntp1.hetzner.de iburst
pool ntp2.hetzner.com iburst
pool ntp3.hetzner.net iburst
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;On slaves &lt;code&gt;mes_node1&lt;/code&gt; and &lt;code&gt;mes_node2&lt;/code&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Sample portion from &lt;code&gt;/etc/ntp.conf&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;
server 192.168.10.10

#enabling mes_master to set time
restrict 192.168.10.10 mask 255.255.255.255 nomodify notrap nopeer noquery

#disable maximum offset of 1000 seconds
tinker panic 0
&lt;/pre&gt;


&lt;a name=&quot;sec42&quot;&gt;&lt;/a&gt;
&lt;h3&gt;4.2 Zookeeper&lt;/h3&gt;

&lt;p&gt;
Related scripts from the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuration script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/setupZookeeper.sh&quot;&gt;&lt;code&gt;setupZookeeper.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Zookeeper is really only required when considering several Mesos master since in this case we need the &lt;i&gt;quorum&lt;/i&gt; feature of zookeeper to proceed with proper election of the master and to track their state.
&lt;br&gt;
At the moment ELK-MS has only one Mesos master, but we&apos;ll make it production and HA ready by already setting up and using zookeeper.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;On master &lt;code&gt;mes_master&lt;/code&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Sample portion from &lt;code&gt;/etc/zookeeper/conf/zoo.cfg&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;
server.1=192.168.10.10:2888:3888
&lt;/pre&gt;

&lt;p&gt;
In addition, we need to set zookeeper master id in &lt;code&gt;/etc/zookeeper/conf/myid&lt;/code&gt;.
&lt;br&gt;
Let&apos;s just put a single character &quot;1&quot; in it for now.
&lt;/p&gt;


&lt;a name=&quot;sec43&quot;&gt;&lt;/a&gt;
&lt;h3&gt;4.3 Elasticsearch&lt;/h3&gt;

&lt;p&gt;
Related scripts from the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installation script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/installElasticSearch.sh&quot;&gt;&lt;code&gt;installElasticSearch.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Configuration script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/setupElasticSearch.sh&quot;&gt;&lt;code&gt;setupElasticSearch.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Systemd service file: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/elasticsearch.service&quot;&gt;&lt;code&gt;elasticsearch.service&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
There&apos;s not a whole lot of things to configure in ES. The installation and setup scripts are really just created a dedicated users, a whole bunch of folders and simlinks, etc.
&lt;br&gt;
The only important configuration elements are as follows:
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;On master &lt;code&gt;mes_master&lt;/code&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Sample portion from &lt;code&gt;/usr/local/lib/elasticsearch-6.0.0/config/elasticsearch.yml &lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;
# name of the cluster (has to be common)
cluster.name: mes-es-cluster

# name of the node (has to be unique)
node.name: mes_master

# Bind on all interfaces (internal and external)
network.host: 0.0.0.0

# We&apos;re good with one node
discovery.zen.minimum_master_nodes: 1

#If you set a network.host that results in multiple bind addresses 
#yet rely on a specific address for node-to-node communication, you 
#should explicitly set network.publish_host
network.publish_host: 192.168.10.10
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;On slaves &lt;code&gt;mes_node1&lt;/code&gt; and &lt;code&gt;mes_node2&lt;/code&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Sample portion from &lt;code&gt;/usr/local/lib/elasticsearch-6.0.0/config/elasticsearch.yml &lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;
# name of the cluster (has to be common)
cluster.name: mes-es-cluster

# name of the node (has to be unique, this is for node1)
node.name: mes_node1

# Bind on all interfaces (internal and external)
network.host: 0.0.0.0

# We&apos;re good with one node
discovery.zen.minimum_master_nodes: 1

# enabling discovery of master
discovery.zen.ping.unicast.hosts: [&quot;192.168.10.10&quot;]

#If you set a network.host that results in multiple bind addresses 
#yet rely on a specific address for node-to-node communication, you 
#should explicitly set network.publish_host
# (this is for node1)
network.publish_host: 192.168.10.11
&lt;/pre&gt;


&lt;a name=&quot;sec44&quot;&gt;&lt;/a&gt;
&lt;h3&gt;4.4 Logstash, Kibana, Cerebro&lt;/h3&gt;

&lt;p&gt;
Related scripts from the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logstash Installation script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/installLogstash.sh&quot;&gt;&lt;code&gt;installLogstash.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Logstash Configuration script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/setupLogstash.sh&quot;&gt;&lt;code&gt;setupLogstash.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;ul&gt;
&lt;li&gt;Cerebro Installation script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/installCerebro.sh&quot;&gt;&lt;code&gt;installCerebro.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cerebro Configuration script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/setupCerebro.sh&quot;&gt;&lt;code&gt;setupCerebro.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cerebro Systemd service file: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/cerebro.service&quot;&gt;&lt;code&gt;cerebro.service&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;ul&gt;
&lt;li&gt;Kibana Installation script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/installKibana.sh&quot;&gt;&lt;code&gt;installKibana.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Kibana Configuration script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/setupKibana.sh&quot;&gt;&lt;code&gt;setupKibana.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Kibana Systemd service file: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/kibana.service&quot;&gt;&lt;code&gt;kibana.service&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
There is really nothing specific to report in terms of configuration for these 3 tools.
&lt;/p&gt;


&lt;a name=&quot;sec45&quot;&gt;&lt;/a&gt;
&lt;h3&gt;4.5 Mesos&lt;/h3&gt;

&lt;p&gt;
Related scripts from the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installation script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/installMesos.sh&quot;&gt;&lt;code&gt;installMesos.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Configuration script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/setupMesos.sh&quot;&gt;&lt;code&gt;setupMesos.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Mesos startup script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/mesos-init-wrapper.sh&quot;&gt;&lt;code&gt;mesos-init-wrapper.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Mesos Master Systemd startup file: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/mesos-master.service&quot;&gt;&lt;code&gt;mesos-master.service&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Mesos Slave Systemd startup file: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/mesos-slave.service&quot;&gt;&lt;code&gt;mesos-slave.service&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The noteworthy configuration aspects are as follows.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;On both master and slaves&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
The file &lt;code&gt;/usr/local/etc/mesos/mesos-env.sh&lt;/code&gt; contains common configuration for both mesos-master and mesos-slave.
&lt;br&gt;
So we should create this file on every node of the cluster.
&lt;/p&gt;

&lt;pre&gt;
#Working configuration
export MESOS_log_dir=/var/log/mesos

#Specify a human readable name for the cluster
export MESOS_cluster=mes_cluster

#Avoid issues with systems that have multiple ethernet interfaces when the Master 
#or Slave registers with a loopback or otherwise undesirable interface.
# (This is for master, put IP of the node)
export MESOS_ip=192.168.10.10

#By default, the Master will use the system hostname which can result in issues 
#in the event the system name isn&apos;t resolvable via your DNS server.
# (This is for master, put IP of the node)
export MESOS_hostname=192.168.10.10
&lt;/pre&gt;

&lt;p&gt;
Then, the file &lt;code&gt;/usr/local/etc/mesos/mesos-slave-env.sh&lt;/code&gt; configures mesos-slave. 
&lt;br&gt;
Since we run a mesos-slave process on the mes_master machine as well, we define this file on every node of the cluster as well.
&lt;/p&gt;

&lt;pre&gt;
#Path of the slave work directory.
#This is where executor sandboxes will be placed, as well as the agent&apos;s checkpointed state.
export MESOS_work_dir=/var/lib/mesos/slave

#we need the Slave to discover the Master.
#This is accomplished by updating the master argument to the master Zookeeper URL
export MESOS_master=zk://$MASTER_IP:2181/mesos
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;On master &lt;code&gt;mes_master&lt;/code&gt; only:&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
The mesos-master process is configured by &lt;code&gt;/usr/local/etc/mesos/mesos-master-env.sh&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;
#Path of the master work directory.
#This is where the persistent information of the cluster will be stored
export MESOS_work_dir=/var/lib/mesos/master

#Specify the master Zookeeper URL which the Mesos Master will register with
export MESOS_zk=zk://$192.168.10.10:2181/mesos

# Change quorum for a greater value if one has more than one master 
# (only 1 in our case)
export MESOS_quorum=1
&lt;/pre&gt;

&lt;a name=&quot;sec46&quot;&gt;&lt;/a&gt;
&lt;h3&gt;4.6 Spark&lt;/h3&gt;

&lt;p&gt;
Related scripts from the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installation script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/installSpark.sh&quot;&gt;&lt;code&gt;installSpark.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Configuration script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/setupSpark.sh&quot;&gt;&lt;code&gt;setupSpark.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Dynamic Allocation Configuration script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/setupSparkDynamicAllocation.sh&quot;&gt;&lt;code&gt;setupSparkDynamicAllocation.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Spark History Server start wrapper: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/start-spark-history-server-wrapper.sh&quot;&gt;&lt;code&gt;start-spark-history-server-wrapper.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Spark History Server Systemd startup file: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/spark-history-server.service&quot;&gt;&lt;code&gt;spark-history-server.service&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Spark Mesos Dispatcher start wrapper: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/start-spark-mesos-dispatcher-wrapper.sh&quot;&gt;&lt;code&gt;start-spark-mesos-dispatcher-wrapper.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Spark Mesos Dispatcher Systemd startup file: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/utils/spark-mesos-dispatcher.service&quot;&gt;&lt;code&gt;spark-mesos-dispatcher.service&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Aside from the specific startup wrappers and systemd service configuration files required for the &lt;i&gt;Spark History Server&lt;/i&gt; and the &lt;i&gt;Spark Mesos Dispatcher&lt;/i&gt;, the noteworthy configuration elements are as follows.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;On both master and slaves&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
The file &lt;code&gt;/usr/local/lib/spark-2.2.0/conf/spark-env.sh&lt;/code&gt; defines common environment variables required by spark workers and drivers.
&lt;br&gt;
So we should create this file on every node of the cluster (in addition the master also executes spark workers).
&lt;/p&gt;

&lt;pre&gt;
#point to your libmesos.so if you use Mesos
export MESOS_NATIVE_JAVA_LIBRARY=/usr/local/lib/mesos-1.3.0/lib/libmesos.so

#Important configuration directories
export SPARK_CONF_DIR=/usr/local/lib/spark-2.2.0/conf
export SPARK_LOG_DIR=/usr/local/lib/spark-2.2.0/logs
&lt;/pre&gt;

&lt;p&gt;
The file &lt;code&gt;/usr/local/lib/spark-2.2.0/conf/spark-defaults.conf&lt;/code&gt; defines common configuration properties required by spark workers and drivers.
&lt;br&gt;
So we should create this file on every node of the cluster (since the master as well executes spark workers).
&lt;/p&gt;

&lt;pre&gt;
#Finding the mesos master through zookeeper
spark.master=mesos://zk://$MASTER_IP:2181/mesos

#Activating EventLog stuff (required by history server)
spark.eventLog.enabled=true
spark.eventLog.dir=/var/lib/spark/eventlog

#Default serializer
spark.serializer=org.apache.spark.serializer.KryoSerializer

#Limiting the driver (client) memory
spark.driver.memory=800m

#Settings required for Spark driver distribution over mesos cluster 
#(Cluster Mode through Mesos Dispatcher)
spark.mesos.executor.home=/usr/local/lib/spark-2.2.0/

#If set to true, runs over Mesos clusters in coarse-grained sharing mode,
#where Spark acquires one long-lived Mesos task on each machine.
#If set to false, runs over Mesos cluster in fine-grained sharing mode,
#where one Mesos task is created per Spark task.
#(Fine grained mode is deprecated and one should consider dynamic allocation 
#instead)
spark.mesos.coarse=true

#ElasticSearch setting (first node to be reached =&gt; can use localhost everywhere)
spark.es.nodes=localhost
spark.es.port=9200
es.nodes.data.only=false

#The scheduling mode between jobs submitted to the same SparkContext.
#Can be FIFO or FAIR. FAIR Seem not to work well with mesos
#(FIFO is the default BTW ...)
spark.scheduler.mode=FIFO

#How long to wait to launch a data-local task before giving up 
#and launching it on a less-local node.
spark.locality.wait=20s

# Configuring dynamic allocation
# (See Spark configuration page online for more information)
spark.dynamicAllocation.enabled=true
#(Caution here : small values cause issues. I have executors killed with 10s for instance)
spark.dynamicAllocation.executorIdleTimeout=120s
spark.dynamicAllocation.cachedExecutorIdleTimeout=300s

# Configuring spark shuffle service (required for dynamic allocation)
spark.shuffle.service.enabled=true

&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;On master &lt;code&gt;mes_master&lt;/code&gt; only&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
In the very same file &lt;code&gt;/usr/local/lib/spark-2.2.0/conf/spark-defaults.conf&lt;/code&gt;, we add what is required for Spark History Server:
&lt;/p&gt;

&lt;pre&gt;
#For the filesystem history provider, 
#the directory containing application event logs to load.
spark.history.fs.logDirectory=file:///var/lib/spark/eventlog

#The period at which to check for new or updated logs in the log directory.
spark.history.fs.update.interval=5s
&lt;/pre&gt;

&lt;a name=&quot;sec47&quot;&gt;&lt;/a&gt;
&lt;h3&gt;4.7 ES-Hadoop&lt;/h3&gt;

&lt;p&gt;
Related scripts from the &lt;i&gt;niceideas_ELK-MS&lt;/i&gt; package are as follows:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installation script: &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/setup/provisionning/installESHadoop.sh&quot;&gt;&lt;code&gt;installESHadoop.sh&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Nothing specific to report, basically the only thing to be done to install ES-Hadoop is to copy the spark driver &lt;code&gt;elasticsearch-spark-20_2.11-6.0.0.jar&lt;/code&gt; to the spark jars folder &lt;code&gt;/usr/local/lib/spark-2.2.0/jars/&lt;/code&gt;.
&lt;/p&gt;


&lt;a name=&quot;sec5&quot;&gt;&lt;/a&gt;
&lt;h2&gt;5. Conclusion&lt;/h2&gt;

&lt;p&gt;
With all of the information above, you should be able to set up your own ElasticSearch / Mesos / Spark Cluster in no time.
&lt;br&gt;
Or simply use the &lt;a href=&quot;https://www.niceideas.ch/es_spark/sandbox/niceideas_ELK-MS.tar.gz&quot;&gt;niceideas_ELK-MS&lt;/a&gt; package to build a test cluster using one single command.
&lt;/p&gt;
&lt;p&gt;
Now the next article in this serie, &lt;a href=&quot;https://www.niceideas.ch/roller2/badtrash/entry/elk-ms-elasticsearch-logstash-kibana1&quot;&gt;ELK-MS - part II : assessing behaviour&lt;/a&gt; will present the tests I did on this test cluster and the conclusions in terms of behaviour assessment.
&lt;/p&gt;
&lt;p&gt;
I&apos;m already telling you the big conclusion: Using ElasticSearch / Mesos / Spark for your Big Data Analytics needs is mind-joggling. It works really amazingly and supports a striking range of use cases while being a hundred times lighter than a plain old Hadoop stack both to setup and to operate.
&lt;/p&gt;
&lt;p&gt;
Kuddos to the folks at Apache and at Elastic for making this possible.
&lt;/p&gt;

</description>          </item>
    <item>
    <guid isPermaLink="true">https://www.niceideas.ch/roller2/badtrash/entry/big-data-and-private-banking</guid>
    <title>Big Data and private banking, what for ?</title>
    <dc:creator>Jerome Kehrli</dc:creator>
    <link>https://www.niceideas.ch/roller2/badtrash/entry/big-data-and-private-banking</link>
        <pubDate>Wed, 5 Oct 2016 04:50:22 -0400</pubDate>
    <category>Big Data</category>
    <category>banking</category>
    <category>big-data</category>
    <category>finance</category>
    <category>private-bank</category>
    <atom:summary type="html">&lt;p&gt;
Big Data technologies are increasingly used in retail banking institutions for customer profiling or other marketing activities. In private banking institutions, however, applications are less obvious and there are only very few initiatives. &lt;br&gt;
Yet, as a matter of fact, there are opportunities in such institutions and they can be quite surprising.
&lt;/p&gt;
&lt;p&gt;
Big Data technologies, initiated by the Web Giants such as Google or Amazon, enable to analyze very massive amount of data (ranging from Terabytes to Petabytes). &lt;a href=&quot;http://hadoop.apache.org/&quot;&gt;Apache Hadoop&lt;/a&gt; is the de-facto standard nowadays when it comes to considering Open Source Big Data technologies but it is increasingly challenged by alternatives such as &lt;a href=&quot;http://spark.apache.org/&quot;&gt;Apache Spark&lt;/a&gt; or others providing less constraining programming paradigms  than Map-Reduce.
&lt;/p&gt;
&lt;p&gt;
These Big Data Processing Platform benefits from the NoSQL genes : the CAP Theorem when it comes to storing data, the usage of commodity hardware, the capacity to scale-out (almost) linearly (instead of scaling up your Oracle DB) and a much lower TCO (Total Cost of Ownership) than standard architectures.
&lt;/p&gt;
&lt;p&gt;
Most essential applications for such technologies in retail banking institutions consist in gathering knowledge and insights on the customer base, customer&apos;s profiles and their tendencies by using cutting-edge Machine Learning techniques on such data.
&lt;/p&gt;
&lt;p&gt;
In contrary to retail banking institutions that are exploiting such technologies for many years, private banking institution, with their very low amount of transactions and their limited customer base are considering these technologies with a lot of skepticism and condescension.
&lt;/p&gt;
&lt;p&gt;
However, in contrary to preconceived ideas, use case exist and present surprising opportunities, mostly around three topics :
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Enhance proximity with customers &lt;/li&gt;
&lt;li&gt; Improve investment advisory services &lt;/li&gt;
&lt;li&gt; Reduce computation costs &lt;/li&gt;
&lt;/ul&gt;
</atom:summary>        <description>&lt;!-- Big Data and private banking, what for ? --&gt;

&lt;p&gt;
Big Data technologies are increasingly used in retail banking institutions for customer profiling or other marketing activities. In private banking institutions, however, applications are less obvious and there are only very few initiatives. &lt;br&gt;
Yet, as a matter of fact, there are opportunities in such institutions and they can be quite surprising.
&lt;/p&gt;
&lt;p&gt;
Big Data technologies, initiated by the Web Giants such as Google or Amazon, enable to analyze very massive amount of data (ranging from Terabytes to Petabytes). &lt;a href=&quot;http://hadoop.apache.org/&quot;&gt;Apache Hadoop&lt;/a&gt; is the de-facto standard nowadays when it comes to considering Open Source Big Data technologies but it is increasingly challenged by alternatives such as &lt;a href=&quot;http://spark.apache.org/&quot;&gt;Apache Spark&lt;/a&gt; or others providing less constraining programming paradigms  than Map-Reduce.
&lt;/p&gt;
&lt;p&gt;
These Big Data Processing Platform benefits from the NoSQL genes : the CAP Theorem when it comes to storing data, the usage of commodity hardware, the capacity to scale-out (almost) linearly (instead of scaling up your Oracle DB) and a much lower TCO (Total Cost of Ownership) than standard architectures.
&lt;/p&gt;
&lt;p&gt;
Most essential applications for such technologies in retail banking institutions consist in gathering knowledge and insights on the customer base, customer&apos;s profiles and their tendencies by using cutting-edge Machine Learning techniques on such data.
&lt;/p&gt;
&lt;p&gt;
In contrary to retail banking institutions that are exploiting such technologies for many years, private banking institution, with their very low amount of transactions and their limited customer base are considering these technologies with a lot of skepticism and condescension.
&lt;/p&gt;
&lt;p&gt;
However, in contrary to preconceived ideas, use case exist and present surprising opportunities, mostly around three topics :
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Enhance proximity with customers &lt;/li&gt;
&lt;li&gt; Improve investment advisory services &lt;/li&gt;
&lt;li&gt; Reduce computation costs &lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt; Enhance proximity with customers&lt;/h2&gt;

&lt;p&gt;
Private banking institutions are increasingly challenged by new external asset management business models such as multi-family offices. These new kind of financial services firms provide their customers with a very high level of personalized service and a very close relationship management, up to a certain form of intimacy, able to seduce UHNWI (Ultra-High Net Worth Individuals).
&lt;/p&gt;
&lt;p&gt;
The progressive denormalization of customer data, their transactions and all the other kinds of related data, even very indirectly, inside a hadoop cluster, then their massive exploitation with cutting-edge machine learning techniques enables traditional institutions to sharpen and refine their knowledge of their customer.  &lt;br&gt;
This consists in importing within hadoop all the different data in an incremental way. After every new stage, one needs to study carefully the new analysis opportunities.
&lt;/p&gt;
&lt;p&gt;
The new knowledge and insights gained this way enables private banking institutions to reach a level of proximity, understanding of their customers and customized investment advisory services close to family offices. They may this way easier keep their top customers seduced by such asset management models.
&lt;/p&gt;


&lt;h2&gt; Improve investment advisory services&lt;/h2&gt;

&lt;p&gt;
Customer profiling to find out about tendencies in terms in investment in peer groups propose a certain interest. Profiles can be examined from various perspective and angles by combining characteristics of customers such as their age, origins, wealth level, activity sector or even their family situation.
&lt;/p&gt;
&lt;p&gt;
The banking institutions should typically use the same hadoop cluster deployed for the above use case that already holds all the required information for such analysis.
&lt;/p&gt;
&lt;p&gt;
There are several objectives there. For instance one might want to adapt investment advices by comparing a specific customer situation with the profile of her peer group or simply with the general tendencies of the market. &lt;br&gt;
Another example is related to the advanced possibilities offered by such knowledge when it comes to optimize investigations on investments or unusual customers most essentially to detect frauds.
&lt;/p&gt;

&lt;h2&gt; Reduce computation costs&lt;/h2&gt;

&lt;p&gt;
For instance, recent NoSQL technologies such as Cassandra are very efficient when it comes to storing and manipulating time series. Infinispan enables to structure an impressive amount of information in memory for massive and complex computations. One could also mention Storm, very efficient when it comes to analyzing market events in real-time. &lt;br&gt;
These new technologies from the Big Data / NoSQL landscape offer unprecedented opportunities for quantitative research on very massive amount of market data.
&lt;/p&gt;
&lt;p&gt;
They have the opportunity to form a little revolution in the world of private banking institutions who finally have very cheap ways for massive and real-time computations of key risk and performance metrics. Even better, these same platforms can be used for optimization, rebalancing or even simulation of financial portfolios at a very large scale and in near-real time. They provide interesting alternatives to more traditional approaches such as Bloomberg&apos;s analytical platform or other very expensive home-made developments on terradata.
&lt;/p&gt;
&lt;p&gt;
Deploying such ambitious technologies inside a private banking institutions is however not innocuous. Adopting an iterative approach consisting in building the software bricks, importing the data and implementing analysis step by step is a key factor of success.
&lt;/p&gt;

&lt;h2&gt;Typical Architecture&lt;/h2&gt;

&lt;p&gt;
A typical architecture of such system would be as follows :
&lt;/p&gt;

&lt;div class=&quot;centering&quot;&gt;
&lt;img class=&quot;centered&quot; style=&quot;width: 750px;&quot; alt=&quot;big data in private banking architecture&quot; src=&quot;https://niceideas.ch/roller2/badtrash/mediaresource/9267e781-b4db-476d-bdf3-e9d110db44c5&quot; /&gt;
&lt;br&gt;
&lt;div class=&quot;centered&quot;&gt;
&lt;i&gt;(Image is copyrighted OCTO Technology SA / 2014)&lt;/i&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;

&lt;p&gt;
&lt;i&gt;(Paper originally published by myself in ICT Journal / March 2014)&lt;/i&gt;
&lt;/p&gt;

</description>          </item>
  </channel>
</rss>