<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sumit</title>
    <description>The latest articles on DEV Community by Sumit (@sumit0k).</description>
    <link>https://dev.to/sumit0k</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F129544%2F1f55882a-5f87-4d0e-b6e9-70674660cde3.jpg</url>
      <title>DEV Community: Sumit</title>
      <link>https://dev.to/sumit0k</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sumit0k"/>
    <language>en</language>
    <item>
      <title>Why Postman Data Engineering chose Apache Spark for ETL (Extract-Transform-Load)</title>
      <dc:creator>Sumit</dc:creator>
      <pubDate>Fri, 20 Sep 2019 11:37:30 +0000</pubDate>
      <link>https://dev.to/sumit0k/why-we-chose-apache-spark-for-etl-extract-transform-load-58op</link>
      <guid>https://dev.to/sumit0k/why-we-chose-apache-spark-for-etl-extract-transform-load-58op</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AG7_FggWo15o5qVbF4COeUA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AG7_FggWo15o5qVbF4COeUA.png"&gt;&lt;/a&gt;Credit: &lt;a href="http://bit.ly/2D9vPjo" rel="noopener noreferrer"&gt;Undraw&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even before I joined Postman, my colleagues here were dealing at a scale of handling 6 million users all around the world. The amount of data which needed to be processed to get some meaningful insight was huge. Here is a taste of its scale:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;100+ million requests per day spread across 30+ micro-services&lt;/li&gt;
&lt;li&gt;Resting around 10 TB of data&lt;/li&gt;
&lt;li&gt;Ingesting around 1TB of monthly internal service logs&lt;/li&gt;
&lt;li&gt;100k+ peak concurrent web socket connections&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Back Story:
&lt;/h3&gt;

&lt;p&gt;Some months were in for me at Postman. I got assigned to a project which needs to handle millions of rows in service logs. These spans over GBs of data.&lt;/p&gt;

&lt;p&gt;Without a doubt, we could have processed these logs in vanilla code and maybe use some libraries too. But this would incur more cost for operating and maintaining the code base. Moreover, libraries which are not tested rigorously increases the surface area for bugs. All these added libraries and infrastructure results in increased human hours. Then we decided to look for something else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea:
&lt;/h3&gt;

&lt;p&gt;With prior experience in distributed systems, the team and I knew of its advantage and limitations. Keeping that in mind the next step for us was to look for solutions in distributed processing. And don’t forget the Map-Reduce functionality.&lt;/p&gt;

&lt;p&gt;Postman believes in a philosophy that human hours are the most valuable resources. We always strive for a managed solution as much as possible. Maintained solution handles upgrades of software and hardware by itself (3rd party). We need to focus only on logic not anything else around it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We were at &lt;a href="http://bit.ly/2TLcJXz" rel="noopener noreferrer"&gt;AWS Community Day 2018, Bengaluru&lt;/a&gt;. If you want to check out the photos, &lt;a href="http://bit.ly/2QLcSZc" rel="noopener noreferrer"&gt;visit here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For the uninitiated &lt;a href="https://spark.apache.org/" rel="noopener noreferrer"&gt;What is Apache Spark?&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Debate:
&lt;/h3&gt;

&lt;p&gt;With the above philosophy in mind we primarily wanted to optimize the following:&lt;/p&gt;

&lt;h4&gt;
  
  
  i. Time for Development
&lt;/h4&gt;

&lt;p&gt;So which method is faster?&lt;/p&gt;

&lt;p&gt;Developing any project in a vanilla code of any programming language&lt;br&gt;&lt;br&gt;
OR&lt;br&gt;&lt;br&gt;
using libraries available in the Apache Spark ecosystem.&lt;/p&gt;

&lt;p&gt;An advantage of vanilla code is you are familiar with basic concepts. You could have skills and tricks to do something in a way which makes development faster for you. The caveat here is could you propagate the same learnings to your team members? You might want to have better control over what you want to achieve. Could you be sure that you can transfer the same knowledge and need for control to other developers? A blunt question for you to ask, do they actually need it?&lt;/p&gt;

&lt;p&gt;One can argue about a similar set of knowledge in the ecosystem of tools. So then what makes Apache Spark ecosystem or any other tools ecosystem weigh much heavier than vanilla alternatives?&lt;/p&gt;

&lt;p&gt;According to my viewpoint&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;support of a community,
&lt;/li&gt;
&lt;li&gt;better documentation of any methodology,
&lt;/li&gt;
&lt;li&gt;system paradigms
&lt;/li&gt;
&lt;li&gt;and the added advantage of potential chances of learning from other people mistakes&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;P.S.:&lt;/strong&gt; With Apache Spark being an open source tool you also don’t lose your control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F517%2F1%2Aic7shvGnlpir0KLZlSZKkQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F517%2F1%2Aic7shvGnlpir0KLZlSZKkQ.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  ii. Modularisation
&lt;/h4&gt;

&lt;p&gt;In my early years of programming one of my colleague beautifully put a thought in my mind. I can say this actually transformed the way, I write code. I won’t put any effort into explaining this, casually putting it here.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Code is like poetry.”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tamilmani58" rel="noopener noreferrer"&gt;Tamil Selvan&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I can not put more emphasis on how difficult it is to modularise any code. Also then maintain the same if you are not the only developer on the project. A single developer project enables you to put your thoughts (read opinions) on how you structure the code. It might be good or maybe not. The real test of skills happens when there are more than one contributors to the project. Your modularisation should be consumable without you explaining to each one of them.&lt;/p&gt;

&lt;p&gt;With tools such as Apache Spark, the contributed code is very small. Why? Because all the nitty-gritty of core functionality is hidden away in library code. What you have is a very simple small liner of the ETL process.&lt;/p&gt;

&lt;p&gt;For e.g. A small but complete ETL process could be summarised as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spark.read.parquet("/source/path) # Extract
    .filter(...).agg(...) # Transform
    .write.parquet("/destination/path") # Load
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a lot of support for simple readers and writers from the Apache Spark community. This enables you to easily modularise your code and also stick to one paradigm. So what do you get finally? You get a beautiful structure code, which everyone can understand and contribute to.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;P.S.:&lt;/strong&gt; You can always extend the default readers and writers to perfectly match with your requirements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F600%2F1%2AgWpLuVf43QxUKBT4B477Gw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F600%2F1%2AgWpLuVf43QxUKBT4B477Gw.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  iii. Maintainability
&lt;/h4&gt;

&lt;p&gt;I have a very strong belief in the power of community. For me, community boils down to something like a league of superheroes fighting for a common goal. Here is a quote to put my thought process in very simple words.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Two is better than one if two act as one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Mike_Krzyzewski" rel="noopener noreferrer"&gt;Mike Krzyzewski&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why I believe in that is because if one fails, the other one will help him. There can be a debate using this proverb.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Too many cooks spoil the broth&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proverb&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;which means that if there are many people involved in doing the same thing, the final result will not be good. But this happens when things happen behind closed doors in a kitchen.&lt;/p&gt;

&lt;p&gt;Open source community has solved this problem very beautifully and proved its mettle. Quality and quantity of open source projects and community are proofs for it. Apache Spark is one of them. This means that its quality, maintainability, and ease of use is much better. At least better than few chefs trying to build vanilla products behind closed doors. No shit, Sherlock!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;P.S.:&lt;/strong&gt; Active open source community means there are a lot of people already maintaining and actually doing the work for you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  iv. Time to Production
&lt;/h4&gt;

&lt;p&gt;Time to development is one thing and actually deploying the code in production is another. Most of the times projects stay in “PoC” mode and never come out of it. I have seen some companies use the same “PoC” in production server. These “PoC”s don’t give much thought on whether they will be able to handle the current traffic and rate at which load increases.&lt;/p&gt;

&lt;p&gt;Inherent nature of distributed systems such as Apache Spark makes supporting large scale a cakewalk. These systems are designed solely for the very same reason “to handle scale”.&lt;/p&gt;

&lt;p&gt;While building a vanilla system most of the times it is designed to handle current load presuming it won’t increase. This might be true in an ideal world, but we don’t live in one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.:&lt;/strong&gt; While I try to &lt;a href="https://dev.to/sumit0k/optimising-e-commerce-data-2nna"&gt;vertically scale most of the times&lt;/a&gt; but I have done horizontal scaling as well, which is buttery smooth in distributed systems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F568%2F1%2AoufjjHZQVsVmCZO5AY1KEw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F568%2F1%2AoufjjHZQVsVmCZO5AY1KEw.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  v. After production caveats
&lt;/h4&gt;

&lt;p&gt;Two words&lt;/p&gt;

&lt;p&gt;Monitoring and Observability.&lt;/p&gt;

&lt;p&gt;I won’t go into details of these terms as there is a lot of content around it already. For production deployments, you might hope to “do it and forget it” in an ideal world but again we don’t live in it. Deploying anything in production brings a lot of itsy-bitsy or larger problems. Systems in production should be continuously monitored and be designed for observability. Don’t forget the alerts too which could subside under monitoring. Apache Spark with its web UI and added support from AWS makes it a much better alternative than building custom solutions in vanilla code.&lt;/p&gt;

&lt;p&gt;So do you actually want to reinvent the wheel?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.:&lt;/strong&gt; Probably you don’t. I am not judging.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion:
&lt;/h3&gt;

&lt;p&gt;To conclude all my blabbering on top, here is a &lt;strong&gt;TL;DR&lt;/strong&gt; version on why we chose to use Apache Spark for ETL&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWS Support (Our primary requirement)&lt;/li&gt;
&lt;li&gt;Distributed System (To handle scalability)&lt;/li&gt;
&lt;li&gt;Open source (Control)&lt;/li&gt;
&lt;li&gt;Community power (Superpower)&lt;/li&gt;
&lt;li&gt;Documentation (Ease of on-boarding)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I usually write about Data. Find more posts from me &lt;a href="https://sumit0k.medium.com/" rel="noopener noreferrer"&gt;on medium&lt;/a&gt; or on the &lt;a href="https://dev.to/sumit0k"&gt;dev.to&lt;/a&gt; community.&lt;/p&gt;




</description>
      <category>spark</category>
      <category>pyspark</category>
      <category>postman</category>
      <category>etl</category>
    </item>
    <item>
      <title>How I reduced storage cost of ElasticSearch by 60x</title>
      <dc:creator>Sumit</dc:creator>
      <pubDate>Tue, 22 Jan 2019 14:11:01 +0000</pubDate>
      <link>https://dev.to/sumit0k/optimising-highly-indexed-document-storage---know-your-data-kyd-3g42</link>
      <guid>https://dev.to/sumit0k/optimising-highly-indexed-document-storage---know-your-data-kyd-3g42</guid>
      <description>&lt;h3&gt;
  
  
  Optimising Highly Indexed Document Storage — Know Your Data (KYD)
&lt;/h3&gt;

&lt;p&gt;This blog is in continuation of &lt;a href="https://dev.to/sumit0k/know-your-data-kyd-39a6"&gt;Know Your Data (KYD)&lt;/a&gt; series and &lt;a href="https://dev.to/sumit0k/optimising-e-commerce-data-2nna"&gt;Optimising E-Commerce Data&lt;/a&gt; sub-series. In &lt;a href="https://dev.to/sumit0k/optimising-document-based-storage---know-your-data-kyd-1hp8"&gt;previous blog&lt;/a&gt; I mentioned about using compression as a solution for optimising storage on field which we don’t tend to use manually, here I address the problem of Explosion of Keys in a Highly Indexed Document Storage. In my case it was ElasticSearch and I was able to reduce the index size by 60 times after applying multiple data modelling changes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Back Story:
&lt;/h4&gt;

&lt;p&gt;As we support multiple types of e-commerce clients, we need to serve their users data in the form shown by the store which means storing and sending back lot of different fields in our organisation datastore.&lt;/p&gt;

&lt;p&gt;Problem started when different stores had different fields across categories and everything has to be ingested by us to serve with correct data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F750%2F0%2AgRdNOOKWkniF_zGd" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F750%2F0%2AgRdNOOKWkniF_zGd"&gt;&lt;/a&gt;Source &lt;a href="https://giphy.com/gifs/disneystudios-disney-9V5kjx3MRcVyE3kYpN" rel="noopener noreferrer"&gt;GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our main principle of not sampling any data and serving with same filters as store serves with features on top was killing us in storage size, even if the store had small catalog. The problem here lied in fields which were being indexed and the storage cost that index incurred.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2ARl2FNrnXDphJbeCB" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2ARl2FNrnXDphJbeCB"&gt;&lt;/a&gt;Source &lt;a href="https://giphy.com/gifs/disneystudios-disney-3Xw6TGuAa39J2X3a1q" rel="noopener noreferrer"&gt;GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Idea:
&lt;/h4&gt;

&lt;p&gt;Inspiration and motivation to solve this problem of Key Explosion came when we were thinking of upgrading Elasticsearch version from 2.x to 6.x. Elasticsearch started putting &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/6.0/mapping.html" rel="noopener noreferrer"&gt;restriction on number of fields in a mapping by setting the default to 1000&lt;/a&gt;. Even if this setting is adjustable keeping it low is a preferable state to be in. So I started to look around the indices on where I could cut number of fields which should be indexed. The solution came in the form of segregating fields in two parts&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fields on which only filtering has to be applied&lt;/li&gt;
&lt;li&gt;Fields which need to be used for aggregations&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The advantage this segregation provided us was to reduce the number of fields which need to be indexed for aggregation support.&lt;/p&gt;

&lt;p&gt;Our initial documents looked similar to this, where some common fields across products are present like &lt;code&gt;_id&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt; and some fields which might change based on product type like if it is something like apparel they will have &lt;code&gt;size&lt;/code&gt; and &lt;code&gt;color&lt;/code&gt; as attribute and if they are something like furniture or cutlery they will something like &lt;code&gt;material&lt;/code&gt;, &lt;code&gt;luster&lt;/code&gt; etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "\_id": "product id 1",
    "price": 232,
    "size": [
      "x",
      "xl"
    ],
    "color": [
      "red",
      "black"
    ],
    "views\_lastweek": 100,
    "views\_desktop\_lastweek": 80,
    ...
  },
  {
    "\_id": "product id 2",
    "price": 14,
    "material": [
      "steel",
      "brass"
    ],
    "luster": [
      "silver"
    ],
    "views\_lastweek": 40,
    "views\_desktop\_lastweek": 20,
    ...
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will go with assumption that we need not show &lt;code&gt;luster&lt;/code&gt; as options anywhere in the store and &lt;code&gt;material&lt;/code&gt; has to be shown may be in side navigation/filter widget. Similarly &lt;code&gt;size&lt;/code&gt; need not be shown in side widget and &lt;code&gt;color&lt;/code&gt; has to be populated there.&lt;/p&gt;

&lt;h4&gt;
  
  
  Goals:
&lt;/h4&gt;

&lt;p&gt;I decided to approach this problem with three goals in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To reduce the number of keys, which need to be indexed.&lt;/li&gt;
&lt;li&gt;To not compromise with quality of query results we currently deliver with old model and not to reduce any functionality.&lt;/li&gt;
&lt;li&gt;Keep it scalable to handle any number of unique fields a store can have&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Process:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;I. Reduce the number of attributes&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To achieve the above goals primary step was to segregate fields in two types filter keys and aggregator keys.&lt;/p&gt;

&lt;p&gt;Now any key which need only be filtered upon and not be aggregated on will help us remove that from index and use it just as values in a generic field across all product catalog for e.g. &lt;code&gt;tags&lt;/code&gt;, &lt;code&gt;attributes&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;So taking the above example and assumption of using &lt;code&gt;size&lt;/code&gt; and &lt;code&gt;luster&lt;/code&gt; as only filter keys I converted my existing data model to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "\_id": "product id 1",
    "price": 232,
**"tags": [  
      "size-&amp;gt;x",  
      "size-&amp;gt;xl"  
    ],**  
    "color": [
      "red",
      "black"
    ],
    "views\_lastweek": 100,
    "views\_desktop\_lastweek": 80,
    …
  },
  {
    "\_id": "product id 2",
    "price": 14,
    "material": [
      "steel",
      "brass"
    ],
  **"tags": [  
      "luster-&amp;gt;silver"  
    ],**  
    "views\_lastweek": 40,
    "views\_desktop\_lastweek": 20,
    …
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will notice that we were able to reduce two indexed keys &lt;code&gt;size&lt;/code&gt; and &lt;code&gt;luster&lt;/code&gt; to one single &lt;code&gt;tags&lt;/code&gt; field.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;II. Reduce the number of Metric Keys&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
As you can see in the sample above, we have some metric keys on each product which can multiply to come around 100 keys due to increase in number of segments or duration we have&lt;/p&gt;

&lt;p&gt;For e.g.&lt;br&gt;&lt;br&gt;
Metric type = [views, purchases, add to cart, …],&lt;br&gt;&lt;br&gt;
Duration = [lastweek, lastmonth, yesterday, Jan-2018, etc.]&lt;br&gt;&lt;br&gt;
Segment = [desktop, mobile, tablet, ads, email, etc.]&lt;/p&gt;

&lt;p&gt;To reduce these keys I evaluated and segmented each product numeric score into textual value of high, medium and low based on how store is performing in those metrics. For e.g. if store received 100 added to cart and current product has a high performing product with around 30 add to cart then it would be placed in high segment than a product which received only 1 added to cart and placed in low segment.&lt;/p&gt;

&lt;p&gt;Using this as a principle I reduced all the metric keys into 3 keys, one for each segment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "\_id": "product id 1",
    "price": 232,
    "tags": [
      "size-&amp;gt;x",
      "size-&amp;gt;xl"
    ],
    "color": [
      "red",
      "black"
    ],
    **"metrics\_h": [  
      "views\_lastweek",  
      "views\_desktop\_lastweek"  
    ],**  
    "metrics\_l": [

    ],
    "metrics\_m": [

    ]
  },
  {
    "\_id": "product id 2",
    "price": 14,
    "material": [
      "steel",
      "brass"
    ],
    "tags": [
      "luster-&amp;gt;silver"
    ],
  **"metrics\_m": [  
      "views\_lastweek",  
      "views\_desktop\_lastweek"  
    ],**  
    "metrics\_l": [

    ],
    "metrics\_h": [

    ]
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This could have been stored in the form of single key &lt;code&gt;metrics&lt;/code&gt; and value as &lt;code&gt;views_lastweek -&amp;gt; h&lt;/code&gt; but our requirement was to have index level boosting on fields like “*_h” should have boost 30 and “*_m” should have boost 20 and so on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;III. Not Indexing field, but keeping in datastore&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Some of the fields in product catalog were supposed to be delivered as is and were not required for querying, filtering, aggregating or sorting upon. Those fields were marked as &lt;code&gt;“index”: false&lt;/code&gt; in mapping which further helped in reducing the storage for index.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IV: Keeping low index profile&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
We tend not to do any partial match query or match phrase query in our datastore, which gave us advantage of declaring our most of &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/6.0/index-options.html" rel="noopener noreferrer"&gt;index options as &lt;code&gt;docs&lt;/code&gt;&lt;/a&gt; to keep the lowest index footprint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "index\_options": "docs",
  "type": "keyword"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Benchmarks:
&lt;/h4&gt;

&lt;p&gt;Let’s talk in numbers now.&lt;/p&gt;

&lt;p&gt;With optimisation in step I, I was able to achieve&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For one of our client Indexing time reduced to 2 minutes from 60 minutes which boils to more than 30x time reduction in Indexing Store’s product catalog to Elasticsearch, albeit both times bulk indexing was used.&lt;/li&gt;
&lt;li&gt;Index size reduced from 7168 MB (7 GB) to mere 220 MB.&lt;/li&gt;
&lt;li&gt;Number of keys reduced from +30k to &amp;gt; 250 and we still have around 750 keys to spare for Elasticsearch default limit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After applying Step II of the optimisation, I was able to achieve&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Previously optimised to 2 minutes Indexing process, was further reduced to 50 seconds&lt;/li&gt;
&lt;li&gt;Index storage size reduced from 220 MB to 110 MB&lt;/li&gt;
&lt;li&gt;Number of keys reduced further from 250 to around 200&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now with all optimisation in place and after cutting down on indexed fields and marking some of the fields as non-indexed, index size of 110 MB was further reduced to 65 MB while in Elasticsearch 2.0 .&lt;/p&gt;

&lt;p&gt;Upgrading Elasticsearch to version 6.x, gave us further reduction in Index size from 65 MB to 34.7 MB, which might be due to large number of sparse data presence and &lt;a href="https://www.elastic.co/blog/minimize-index-storage-size-elasticsearch-6-0" rel="noopener noreferrer"&gt;Elasticsearch 6 has lot of space saving improvements&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion:
&lt;/h4&gt;

&lt;p&gt;With all optimisation in place and after upgrading to Elasticsearch 6.x, I was able to reduce an Index of size 7.1 GB to 34.7 MB and also achieve an indexing time for 18k large size documents from 1 hour to 50 seconds.&lt;/p&gt;

&lt;p&gt;Version upgrade from Elasticsearch 2 to 6 gave us saving on only 30 MB as all the optimisation were already implemented in Elasticsearch version 2, which was able to give us around 65 MB.&lt;/p&gt;

&lt;p&gt;Index size from 7.1 GB. So, version upgrade is preferred step but not a mandatory step for these optimisations to be implemented.&lt;/p&gt;

&lt;p&gt;While most of optimisations are tool specific, one generic conclusion can be derived is Know Your Data.&lt;/p&gt;

&lt;p&gt;P.S.&lt;/p&gt;

&lt;p&gt;Upgradation of Elasticsearch should be handled with &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/6.0/removal-of-types.html" rel="noopener noreferrer"&gt;removal of &lt;code&gt;_type&lt;/code&gt; field in mapping&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am also active in &lt;a href="http://stackoverflow.com/users/4453633/sumit-kumar?tab=profile" rel="noopener noreferrer"&gt;StackOverflow community&lt;/a&gt;and primarily has answered Elasticsearch questions in past.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Other posts in Series&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/sumit0k/know-your-data-kyd-39a6"&gt;Know Your Data (KYD) - Sumit Kumar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sumit0k/optimising-e-commerce-data-2nna"&gt;Optimising E-Commerce Data - Sumit Kumar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sumit0k/optimising-document-based-storage---know-your-data-kyd-1hp8"&gt;Optimising Document Based Storage - Know Your Data (KYD)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>elasticsearch</category>
      <category>nosql</category>
      <category>database</category>
      <category>storage</category>
    </item>
    <item>
      <title>I saved 7x from storage cost of MongDB</title>
      <dc:creator>Sumit</dc:creator>
      <pubDate>Tue, 15 Jan 2019 14:06:02 +0000</pubDate>
      <link>https://dev.to/sumit0k/optimising-document-based-storage---know-your-data-kyd-1hp8</link>
      <guid>https://dev.to/sumit0k/optimising-document-based-storage---know-your-data-kyd-1hp8</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;Optimising Document Based Storage — &lt;/strong&gt; Know Your Data (KYD)
&lt;/h3&gt;

&lt;p&gt;As mentioned in &lt;a href="https://dev.to/sumit0k/optimising-e-commerce-data-17af-temp-slug-4168828"&gt;the introductory post &lt;/a&gt;, this blog mentions details about how we found a solution for Storage of Serialised HyperLogLog (HLL) Registers’ problem and were able to reduce our storage costs by 7 times.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YzsScde---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/636/1%2Ax9DD7BVlvFmlS6vW4nU7xA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YzsScde---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/636/1%2Ax9DD7BVlvFmlS6vW4nU7xA.gif" alt="" width="636" height="288"&gt;&lt;/a&gt;Image Source &lt;a href="https://www.gizmodo.com.au/2015/02/mits-well-on-its-way-to-perfecting-auto-zipping-zippers/"&gt;GIZMODO&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Back Story:
&lt;/h4&gt;

&lt;p&gt;A single string conversion of HLL Register gives us 8192 character long string which is independent of value it represents. To read a detailed but engaging post about HLL refer to this &lt;a href="http://bit.ly/bloom-filters-medium"&gt;link&lt;/a&gt;. The post talks about Bloom filters. HLL is based on similar fundamental implementation. I might try to publish a shorter version later.&lt;/p&gt;

&lt;p&gt;So the problem we faced was whether HLL String represents value 1 or value 22k or something larger it always occupied same storage space. This methodology lead us to store same amount of data for each store irrespective of their traffic and catalog size, which boils down to low ROI on small traffic customers as they are in lower price plan.&lt;/p&gt;

&lt;p&gt;There was a dire need of optimisation for this storage as there were large number of small traffic size store signing up and hence our storage costs were increasing.&lt;/p&gt;

&lt;h4&gt;
  
  
  Idea:
&lt;/h4&gt;

&lt;p&gt;The idea on how to optimise this came after having a look on what is there in a HLL String, which was nothing but a large number of padding 0 and very few occurrences of any other digit like 1 or 2 for when it represents a smaller value like 1. Something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'000000000000000000000000000.....0000000001000000000........0000000'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where first occurrence of 1 was at 5029th position with only 0s in front.&lt;/p&gt;

&lt;p&gt;And you might have guessed by now that this is a perfect data to compress, a lot of repeating characters, or if you haven’t here is a fun link to read more about &lt;a href="https://en.wikipedia.org/wiki/Zip_bomb"&gt;Zip Bomb&lt;/a&gt; on how petabytes of data were compressed into 42Kbs of zip file.&lt;/p&gt;

&lt;p&gt;To analyse on which compression engine will suit our use case, there was a war between the lots of compression engine available and lot of blogs to reference too. But each one of them has their own advantage and own use-cases to cater to.&lt;/p&gt;

&lt;p&gt;What we needed was which engine is best for our use-case and best method to do that was by benchmarking different engines on our data strings.&lt;/p&gt;

&lt;h4&gt;
  
  
  Goals:
&lt;/h4&gt;

&lt;p&gt;The points on which one can decide a compression engine are&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Compression Speed&lt;/li&gt;
&lt;li&gt;Decompression Speed&lt;/li&gt;
&lt;li&gt;Compression Factor&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now in best case scenario I would like to have all of them in one compression engine, but most of the times you don’t get what you want. So what we needed was&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Decompression Speed fastest on highest priority as decompressed data was to be served real time&lt;/li&gt;
&lt;li&gt;An above average Compression factor to save storage costs and&lt;/li&gt;
&lt;li&gt;Last but not the least a good compression speed to handle scale&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Benchmarks:
&lt;/h4&gt;

&lt;p&gt;So I ran set of scripts and put together bunch of graphs to help me choose the best fighter for my war with storage. In each of graphs below vertical Y axis represents percentage of data left after leading zeros in a string, which means lower the percentage lower the value it represents.&lt;/p&gt;

&lt;p&gt;For e.g. 0.01% represents a HLL string whose cardinality is 1. There are legends on right to represent different compression engines I tested. In overall I did 4 comparisons to finalise on which engine would suite our need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I. Compression Speed Comparison&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here in this graph the horizontal X axis represents time taken to compress 8192 Bytes of data via each compression engine in seconds. There is no High level of data analysis power required to derive that the fastest compression engine is of &lt;code&gt;blosclz&lt;/code&gt;, &lt;code&gt;lz4&lt;/code&gt; and &lt;code&gt;snappy&lt;/code&gt;. &lt;code&gt;Lz4hc&lt;/code&gt; comes into the 4th place in this comparison which is high compression configuration for &lt;code&gt;lz4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--scgKGzn_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A2OnhImCRu3AS3bL6" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--scgKGzn_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A2OnhImCRu3AS3bL6" alt="" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;II. Decompression speed comparison&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;2nd graph is a visualisation of decompression speed of all the engines in seconds and if you remember our priorities from above paragraphs our primary need was fastest decompression speed and we can see that on an average &lt;code&gt;lz4hc&lt;/code&gt; comes first, even when &lt;code&gt;blosclz&lt;/code&gt; was fastest in smaller value representing strings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qTJ6p3oM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A3Zi6Ut3Xek9DBru9" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qTJ6p3oM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A3Zi6Ut3Xek9DBru9" alt="" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;III. Decompression Vs. Compression Speed Comparison&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What added another point in favour of &lt;code&gt;lz4hc&lt;/code&gt; was this graph, where I am comparing ration of Decompression time vs Compression time for same engine, and smaller is better which means engine takes relatively less time decompressing than other engine takes in comparison to other engines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--22WFkzSv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A97Nf4MB3pTM77xiE" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--22WFkzSv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A97Nf4MB3pTM77xiE" alt="" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IV. Compressed Size Comparison&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As clear from above points, I was in dilemma of to decide the final winner of this comparison and this graph made it all clear. Here we are comparing compressed size of HLL string from 8192 bytes. We can see that &lt;code&gt;zlib&lt;/code&gt; and &lt;code&gt;zstd&lt;/code&gt; are the clear winners with consistent smallest size with &lt;code&gt;lz4hc&lt;/code&gt; coming in 3rd.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1mSFqRms--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AwZ9IhOfqmP_rOXWM" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1mSFqRms--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AwZ9IhOfqmP_rOXWM" alt="" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion:
&lt;/h4&gt;

&lt;p&gt;Taking a decision is easy, what is difficult is to live with the consequences it can bring.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Nothing is more difficult, and therefore more precious, than to be able to decide.”&lt;/p&gt;

&lt;p&gt;-Napoleon Bonaparte&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When all data is with you, it’s not difficult to take a decision. Even if “blosclz” was the fastest in compression, “zstd” was smallest in size, “lz4hc” was the only one which checked all boxes of our priorities with being fastest in decompression and relatively smaller compressed file size than most of the engines in most of the cases and relatively faster compression time and 50% of the engines I benchmarked.&lt;/p&gt;

&lt;p&gt;I went ahead with using &lt;code&gt;lz4hc&lt;/code&gt; for our use case and it helped us reduce MongoDB storage by 7 times than what it used to be before compression.&lt;/p&gt;

&lt;p&gt;We got support of MongoDB Binary Data Type to store the compressed binary data which further helped in interoperability of compressed string between different language libraries for &lt;code&gt;lz4hc&lt;/code&gt;. We primarily use Node.JS for serving app users and Python for background processes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You might not see reduction in disk space claimed by MongoDB if you are optimising on same instance as &lt;a href="https://cyantificmusings.wordpress.com/2016/04/17/reclaiming-disk-space-from-mongodb/"&gt;MongoDB does not release the disk space back&lt;/a&gt;. Seems like they got inspired by Pirates&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4rA90sNL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/720/1%2Az-n0jQdbYbF_XP3YCpmiCA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4rA90sNL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/720/1%2Az-n0jQdbYbF_XP3YCpmiCA.gif" alt="" width="720" height="300"&gt;&lt;/a&gt;Source &lt;a href="https://giphy.com/gifs/reactionseditor-3o7btQtMuwv4FtXu0M"&gt;GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Library Links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://python-lz4.readthedocs.io/en/stable/"&gt;LZ4 compression library bindings for Python - python-lz4 2.1.0 documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://python-blosc.blosc.org/"&gt;Welcome to python-blosc's documentation! - python-blosc 1.5.0 documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Other posts in Series&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/sumit0k/know-your-data-kyd-45e6-temp-slug-3424402"&gt;Know Your Data (KYD) - Sumit Kumar - Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sumit0k/optimising-e-commerce-data-17af-temp-slug-4168828"&gt;Optimising E-Commerce Data - Sumit Kumar - Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sumit0k/optimising-highly-indexed-document-storage---know-your-data-kyd-3g42"&gt;Optimising Highly Indexed Document Storage - Know Your Data (KYD)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>database</category>
      <category>compression</category>
      <category>mongodb</category>
      <category>nosql</category>
    </item>
    <item>
      <title>Saving 1000 of dollars in storage cost in an early stage startup</title>
      <dc:creator>Sumit</dc:creator>
      <pubDate>Tue, 08 Jan 2019 12:17:54 +0000</pubDate>
      <link>https://dev.to/sumit0k/optimising-e-commerce-data-2nna</link>
      <guid>https://dev.to/sumit0k/optimising-e-commerce-data-2nna</guid>
      <description>&lt;h3&gt;
  
  
  Optimising E-Commerce Data — Know Your Data (KYD)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YgQsyWS6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/960/1%2AtsdMwVAFslnq5XEHfAqThQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YgQsyWS6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/960/1%2AtsdMwVAFslnq5XEHfAqThQ.gif" alt="" width="800" height="241"&gt;&lt;/a&gt;Source &lt;a href="http://www.thewebfusion.com/services/web-development/website-web-design-and-graphic-designing/"&gt;WebFusion&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my previous organisation (Choice.AI), we had customers (read E-Commerce Shops) ranging from small size handling upto maximum of 100–1000 unique visitors per month to mid-size handling around 30k-50k of unique traffic per month to their stores to finally large customers with 50k+ regular shoppers on websites. Based on their traffic size, each store came under different pricing plan of organisation, so our investment on them also should be planned based on their ROIs.&lt;/p&gt;

&lt;p&gt;To deliver faster and equal value to all types of customers, we built solutions which were independent of Store catalog and traffic size. This approach started costing us more as more stores became our clients, because they needed nearly same amount of investment in terms of computing resources and power.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z_jDu9Px--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/804/1%2AEe_ftZOzIdkgggs-2j4YqA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z_jDu9Px--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/804/1%2AEe_ftZOzIdkgggs-2j4YqA.gif" alt="" width="800" height="713"&gt;&lt;/a&gt;Source &lt;a href="https://bkwebdesigns.com/web-development/"&gt;BK Website Designs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here in this series of blog I will talk about major problems which we solved by “knowing” and understanding what our data contains and their solution helped us in terms of optimised allocation of resources to stores based on their catalog and traffic size without compromising in terms of quality, relevance and features organisation offered.&lt;/p&gt;

&lt;h4&gt;
  
  
  Storage of Serialized HyperLogLog (HLL) Registers
&lt;/h4&gt;

&lt;p&gt;Our primary problem was handling aggregated user events analytics in a document based data storage (MongoDB in our case). Our main goal was to count number of unique visitors across different dimensions and segments where dimensions could be Campaigns or Experiments and Segments could be Devices or Traffic Sources.&lt;/p&gt;

&lt;p&gt;To get the number of unique visitors across different span of time which was only available at query time, we needed to store HLL Registers’ serialised data in a data store which would be deserialised and merged to give the value required.&lt;/p&gt;

&lt;p&gt;This string was of length 8192 in bytes to be exact, considering 8-bit for a single character and total string length of 8192 characters. It is independent of value it represents whether it could be as small as 1 or as large as 50k, all of the string are of same length.&lt;/p&gt;

&lt;h4&gt;
  
  
  Explosion of Keys of Product Catalog
&lt;/h4&gt;

&lt;p&gt;Our customers were ranging from different areas of e-commerce and had different and unique products to offer to end consumer. Because of our primary principal of treating every customer data in similar way, the most common issue which we faced was interference of problems from one customer’s badly structured data into processing of another customer’s clean structured hierarchical data.&lt;/p&gt;

&lt;p&gt;We allowed our customers to import as many attributes of a product as they want and they will get filtering and aggregation support on those attributes. This approach resulted in keys explosion, which means more fields to index in Highly Indexed Document based Storage System (Elasticsearch in our case) and ultimately occupying large disk size and more time to index and retrieve data on filters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Next Posts in Series&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/sumit0k/optimising-document-based-storage---know-your-data-kyd-1hp8"&gt;Optimising Document Based Storage - Know Your Data (KYD)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sumit0k/optimising-highly-indexed-document-storage---know-your-data-kyd-3g42"&gt;Optimising Highly Indexed Document Storage - Know Your Data (KYD)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>mongodb</category>
      <category>elasticsearch</category>
      <category>data</category>
      <category>engineering</category>
    </item>
    <item>
      <title>Know Your Data (KYD)</title>
      <dc:creator>Sumit</dc:creator>
      <pubDate>Tue, 01 Jan 2019 13:16:00 +0000</pubDate>
      <link>https://dev.to/sumit0k/know-your-data-kyd-39a6</link>
      <guid>https://dev.to/sumit0k/know-your-data-kyd-39a6</guid>
      <description>&lt;h3&gt;
  
  
  Introduction — Know Your Data (KYD)
&lt;/h3&gt;

&lt;p&gt;In this new era of artificial intelligence and machine learning, you need not be expert to realise that data is the new diamond, more the merrier. But unless your diamonds are shiny, polished, multi-faceted and easily accessible with low maintenance they are nothing more than just a piece of rock.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XYm5x021--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AsZ1adV_WEtfozQtp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XYm5x021--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AsZ1adV_WEtfozQtp" alt="" width="800" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my previous organisation (to be called organisation from now on), we analysed millions of user events per day and produced shiny multi-faceted analytics from it. As we know that diamonds come in all shapes and sizes, so they should be maintained based on their potential to fetch money or in simple business terms their ROI.&lt;/p&gt;

&lt;p&gt;In my current organisation, we handle data of size in terms of billions of events per day mainly comprised of communication logs between different microservices.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On another note there is nice must-read series of write-ups from Ankit Sobti (CTO, Postman) on how Postman implemented Microservices. Here is &lt;a href="https://medium.com/postman-engineering/conquering-the-microservices-dependency-hell-at-postman-with-postman-part-1-introduction-a1ae019bb934"&gt;link for first one&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Handling data at this scale and complexity, results in plethora of complications and problems. I will write about our approaches to solve these problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  SPOILER ALERT
&lt;/h3&gt;

&lt;p&gt;…&lt;/p&gt;

&lt;p&gt;…&lt;/p&gt;

&lt;p&gt;The solution always lies in the direction realised only after knowing our data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Next Posts in Series&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/sumitkumar1209/optimising-e-commerce-data-2nna"&gt;Optimising E-Commerce Data - Sumit&lt;/a&gt;&lt;/p&gt;




</description>
      <category>engineering</category>
      <category>data</category>
      <category>datamodeling</category>
      <category>optimisation</category>
    </item>
  </channel>
</rss>
