<?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: Sathyasarathi</title>
    <description>The latest articles on DEV Community by Sathyasarathi (@sathyasarathi90).</description>
    <link>https://dev.to/sathyasarathi90</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%2F334509%2F6f9151d3-0709-4a54-a840-071eede4916b.jpg</url>
      <title>DEV Community: Sathyasarathi</title>
      <link>https://dev.to/sathyasarathi90</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sathyasarathi90"/>
    <language>en</language>
    <item>
      <title>Event Streaming Platforms: Kafka - A Hands-On Tutorial</title>
      <dc:creator>Sathyasarathi</dc:creator>
      <pubDate>Thu, 01 Jun 2023 14:22:54 +0000</pubDate>
      <link>https://dev.to/sathyasarathi90/event-streaming-platforms-kafka-a-hands-on-tutorial-213</link>
      <guid>https://dev.to/sathyasarathi90/event-streaming-platforms-kafka-a-hands-on-tutorial-213</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%2Fdatawrangler.mo.cloudinary.net%2Fimages%2Ffeatured-post%2Fpost18.jpg" 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%2Fdatawrangler.mo.cloudinary.net%2Fimages%2Ffeatured-post%2Fpost18.jpg" alt="Kafka"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ever wondered how systems such as Apache Kafka [Open Source], Google Pub/Sub [Google Managed], Azure Event Hubs [Azure Managed], etc. functions? &lt;/p&gt;

&lt;p&gt;These distributed messaging/event streaming platform-systems facilitate the the near-realtime data streaming and parallel processing for ETL and analytical capabilities.&lt;/p&gt;

&lt;p&gt;The practical applications include ability to build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Near-real time data pipelines - E.g. Geolocation updates from mobile phones, Shipping orders, Order Deliveries&lt;/li&gt;
&lt;li&gt;Large scale data pipelines where the batch jobs can be too expensive - E.g. Payment transactions, Sensor measurements from IoT devices or medical equipment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simply put, these are message transportation systems that are highly performant and resilient. This post will help you understand the components of the ELK stack and will get you up and running to process logs on your local machine.  Kafka, being a stateful system gives the ability to read the stream at different positions and different speeds and replay the messages from the past (at least from the set expiry time).&lt;/p&gt;

&lt;h2&gt;
  
  
  Components of Kafka
&lt;/h2&gt;

&lt;p&gt;Apache Kafka consists of several key components that work together to provide a scalable and distributed streaming platform. &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%2Fdatawrangler.mo.cloudinary.net%2Fimages%2Fpost%2F18-kafka%2Fimg1.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%2Fdatawrangler.mo.cloudinary.net%2Fimages%2Fpost%2F18-kafka%2Fimg1.png" alt="Fig1: The Kafka Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main components of Kafka are mentioned as follows:&lt;/p&gt;

&lt;h3&gt;
  
  
  Topics
&lt;/h3&gt;

&lt;p&gt;Topics hold the logical stream of data. It is synonymous to a folder in a filesystem or a table in a database. The events are synonymous to the files in a folder or the rows in a table&lt;/p&gt;

&lt;p&gt;You can have any number of topics. Applications write directly or publish the messages to the topics. Internally, topics are made up of multiple partitions and the packets are distributed for resilience across multiple nodes (also known as Brokers).&lt;/p&gt;

&lt;h3&gt;
  
  
  Partitions &amp;amp; Offsets
&lt;/h3&gt;

&lt;p&gt;As mentioned earlier, topics are stored as multiple partitions across different nodes for data resilience. The messages are stored within a partition, gets incremental id's - known as offsets. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The offsets are incremental and once assigned, offset can never be re-assigned ever again even if the messages get flushed. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The sorting order of the offsets are maintained inside the partition but not guaranteed when sent across different partitions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data is retained in the offsets only for a limited time (Default is 1 week). This expiry time can be modified to other durations too.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data is &lt;strong&gt;immutable&lt;/strong&gt;  and can't be manipulated once after it has been written to a partition.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data is assigned to a partition randomly unless the partition is forcefully defined.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But, does it matter if the partition is randomly assigned? &lt;/p&gt;

&lt;h3&gt;
  
  
  Brokers
&lt;/h3&gt;

&lt;p&gt;Event streaming platforms are multi-node distributed system containing multi-noded clusters. The nodes of the clusters are known as brokers. At least three nodes/brokers are required to make a perfectly functioning cluster. The data is randomly distributed and replicated across these brokers. &lt;/p&gt;

&lt;p&gt;Like any other distributed system, connecting to a single broker (&lt;strong&gt;&lt;em&gt;Bootstrap Broker&lt;/em&gt;&lt;/strong&gt;) will give access to the entire cluster. Topics are universally assigned and distributed across the brokers. However, the data distribution across the number of brokers is decided based on the &lt;strong&gt;&lt;em&gt;replication factor&lt;/em&gt;&lt;/strong&gt;. This brings the resilience into the picture, making sure that: If a broker is down, another broker can serve the data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Replication Golden Rule:&lt;/em&gt;&lt;/strong&gt; Even though multiple brokers can have the copy of the data, only one of the broker can be a leader for a given partition. The other brokers will synchronize and replicate the data. If the leader goes down, one of the followers will get elected to become the leader.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each partition has a leader and multiple ISRs (in-sync replica). Distribution coordination services such as Apache Zookeeper will decide on this and take care of replication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing Data to Kafka (Write)
&lt;/h2&gt;

&lt;p&gt;To write data to Apache Kafka, you need to create a producer application that connects to the Kafka cluster and publishes messages to the desired Kafka topic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Producers
&lt;/h3&gt;

&lt;p&gt;Applications known as &lt;strong&gt;Producers&lt;/strong&gt; writes the data to topics. They know to which broker and partition to write to. During failures, the producers will auto recover. The load is balanced across the brokers. When sending the data, if the key is not specified, the producer sends the data to brokers based on round robin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Send Modes
&lt;/h3&gt;

&lt;p&gt;Producers can be configured whether to receive the acknowledgement for data writes. The following are the possible send modes, one of them can be configured for the producers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Send Mode&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Data Loss&lt;/th&gt;
&lt;th&gt;Use-case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;acks=0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Producer won't wait for acknowledgement - very dangerous but no lag in performance&lt;/td&gt;
&lt;td&gt;Possible data loss&lt;/td&gt;
&lt;td&gt;Suitable for high volume data transfers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;acks=1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Producer will wait for the leader broker to acknowledge&lt;/td&gt;
&lt;td&gt;limited data loss&lt;/td&gt;
&lt;td&gt;Suitable for data streams related (Widely Used)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;acks=all&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Leader and all other replicas get the data and acknowledge&lt;/td&gt;
&lt;td&gt;no data loss but poor performance&lt;/td&gt;
&lt;td&gt;Suitable for secure and persisted storages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Message Keys
&lt;/h3&gt;

&lt;p&gt;If the ordering of the message matters, the message keys are mandatory. For example, consider an ecommerce or a delivery app in which the key can be as &lt;code&gt;order_id&lt;/code&gt;s. There are different event types for the processing of an order such as: "ordered", "shipped", "in-transit" and "delivered" that is highly crucial to be processed in the same sequence and this is done by assigning to them to the same message key.&lt;/p&gt;

&lt;p&gt;Message keys can be a hash, number, string, number, etc. If message key is null, data is sent round robin (i.e. in case of two brokers - first message is sent to broker 1, second message to broker 2, third message to broker 1, etc.).&lt;/p&gt;

&lt;p&gt;If a key is null or not provided, the data will be sent to any partition based on round robin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subscribing to Data in Kafka (Read)
&lt;/h2&gt;

&lt;p&gt;Applications known as &lt;strong&gt;Consumers&lt;/strong&gt; reads the data from the consumer groups, also known as subscriptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consumers
&lt;/h3&gt;

&lt;p&gt;Consumers read the data from topics. They know which broker to read from. Consumers can auto-recover, in case of failures. Data is read in order within each partition.&lt;/p&gt;

&lt;p&gt;In case of consumers reading from multiple partitions, the reading order can be random but however within each partition, the data is read in order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consumer Groups
&lt;/h3&gt;

&lt;p&gt;Consumers read from multiple partitions by reading in Consumer Groups. Work is divided among the consumer groups. Internally, Consumers will use a Group Coordinator and a Consumer Coordinator to assign consumers to a partition. &lt;/p&gt;

&lt;p&gt;If there are too many consumers and just a few partitions, some of the consumers may be inactive. These inactive consumers can be helpful when one of the consumers go down, so that the inactive consumer can replace the failed consumer.&lt;/p&gt;

&lt;p&gt;For Example:&lt;/p&gt;

&lt;p&gt;A Dashboard application can have two consumers under a consumer group 1 and can read from three partitions at a time.&lt;br&gt;
A notification application can have one consumer reading from multiple partitions at the same time.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing Kafka
&lt;/h3&gt;

&lt;p&gt;Setting up Apache Kafka involves: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Downloading Kafka&lt;/li&gt;
&lt;li&gt;Configuring the Kafka cluster&lt;/li&gt;
&lt;li&gt;Starting the necessary components. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a high-level overview of the steps to set up Kafka:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download Kafka:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to the Apache Kafka website (&lt;a href="https://kafka.apache.org/downloads" rel="noopener noreferrer"&gt;https://kafka.apache.org/downloads&lt;/a&gt;) and download the desired Kafka version.&lt;br&gt;
Extract the downloaded archive file to a directory on your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure Kafka:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the Kafka installation directory and locate the config subdirectory.&lt;br&gt;
Modify the configuration files as per your requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;config/server.properties&lt;/code&gt;: This file contains the configuration for Kafka brokers. You may need to update properties such as &lt;code&gt;broker.id&lt;/code&gt;, &lt;code&gt;listeners&lt;/code&gt;, &lt;code&gt;log.dirs&lt;/code&gt;, and &lt;code&gt;zookeeper.connect&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;config/zookeeper.properties&lt;/code&gt;: This file contains the configuration for the ZooKeeper server used by Kafka. Update properties such as &lt;code&gt;dataDir&lt;/code&gt; and &lt;code&gt;clientPort&lt;/code&gt; if necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Starting the Necessary Components&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Start ZooKeeper&lt;/em&gt;&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kafka relies on ZooKeeper for coordination and maintaining cluster state. Start ZooKeeper by executing the following command in a new terminal or command prompt window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;bin/zookeeper-server-start.sh config/zookeeper.properties
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the ZooKeeper instance running while setting up and using Kafka.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Start Kafka brokers&lt;/em&gt;&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a separate terminal or command prompt window, start the Kafka brokers by executing the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bin/kafka-server-start.sh config/server.properties
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can start multiple brokers if you want to set up a Kafka cluster. In such cases, you need to configure unique properties such as broker.id, listeners, and log.dirs for each broker.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Create topics&lt;/em&gt;&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kafka uses topics to organize and categorize messages. You can create a topic using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bin/kafka-topics.sh &lt;span class="nt"&gt;--create&lt;/span&gt; &lt;span class="nt"&gt;--topic&lt;/span&gt; &amp;lt;topic_name&amp;gt; &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092 &lt;span class="nt"&gt;--partitions&lt;/span&gt; 1 &lt;span class="nt"&gt;--replication-factor&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adjust the &lt;code&gt;&amp;lt;topic_name&amp;gt;&lt;/code&gt; as desired, and specify the appropriate bootstrap-server (Kafka broker) address, partitions, and replication factor.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Verify the setup&lt;/em&gt;&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To ensure that Kafka is running and the setup is correct, you can use various Kafka command-line tools to produce and consume messages from topics. For example:&lt;/p&gt;

&lt;p&gt;Produce messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bin/kafka-console-producer.sh &lt;span class="nt"&gt;--topic&lt;/span&gt; &amp;lt;topic_name&amp;gt; &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consume messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bin/kafka-console-consumer.sh &lt;span class="nt"&gt;--topic&lt;/span&gt; &amp;lt;topic_name&amp;gt; &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092 &lt;span class="nt"&gt;--from-beginning&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These steps provide a basic setup of Kafka for local development and testing purposes. For production environments, additional configurations and considerations are necessary, such as securing the cluster, configuring replication, and setting up additional components like Kafka Connect or Kafka Streams.&lt;/p&gt;

&lt;p&gt;This gives you a basic understanding of the Kafka architecture and how to get started. They allow for high-throughput, real-time data streaming and processing across multiple applications and systems. Some of the practical use-cases include: messaging system, large volume log aggregation transport, stream processing, data pipelines, and IoT data processing.&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>eventdriven</category>
      <category>datascience</category>
      <category>database</category>
    </item>
    <item>
      <title>Git: Best Practices For Better Collaboration</title>
      <dc:creator>Sathyasarathi</dc:creator>
      <pubDate>Sat, 04 Dec 2021 11:03:00 +0000</pubDate>
      <link>https://dev.to/sathyasarathi90/git-best-practices-for-better-collaboration-34ff</link>
      <guid>https://dev.to/sathyasarathi90/git-best-practices-for-better-collaboration-34ff</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Always have individual branches for your environments. The developers can create branches out of the &lt;code&gt;dev&lt;/code&gt; environment and work on their respective branches👩‍💻👨‍💻.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;main
|
|------dev
        |--- helsinki/feature1
        |--- tokyo/feature2
                |--- nairobi/feature3 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Protect 🛡️ the &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;dev&lt;/code&gt; branches so that no one accidentally pushes or deletes the branches. Even if the branches are not protected, never 🛑 push directly to &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;dev&lt;/code&gt; branches.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Work on your own feature branch 🌳 that is branched out of dev branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git checkout dev
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; helsinki/feature-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Commit and push your changes 🟩 to the remote branch 🌲 before you end your day, every evening 🗓️.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Devices can be replaced but the lost code can never be.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Rebase your changes 🟩 with your source branch 🌲 before you begin the day 🌅, to avoid merge conflicts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Feature Branch ← Source Branch&lt;/code&gt; (Rebase)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git branch
dev
branch1
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git checkout branch1
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git rebase dev
Successfully rebased and updated refs/heads/branch1.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In case of conflicts, DO NOT PANIC! 🤯🙅🏻&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why do the conflicts occur?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Merge conflicts may occur if competing changes are made to the same line of a file or when a file is deleted that another person is attempting to edit.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;a. You clone from a Main branch&lt;br&gt;
b. Your colleague clones from the same branch&lt;br&gt;
c. He pushes his commit and merges the changes in his branch to the main branch&lt;br&gt;
d. You push your commit and when trying to merge your change with the main branch, 🟥 Merge conflict occurs.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Feature branch → Source Branch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Merge conflicts can occur while rebasing too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git rebase main
Auto-merging main.py
CONFLICT &lt;span class="o"&gt;(&lt;/span&gt;content&lt;span class="o"&gt;)&lt;/span&gt;: Merge conflict &lt;span class="k"&gt;in &lt;/span&gt;main.py
error: could not apply cce2b78... added another statement
Resolve all conflicts manually, mark them as resolved with
&lt;span class="s2"&gt;"git add/rm &amp;lt;conflicted_files&amp;gt;"&lt;/span&gt;, &lt;span class="k"&gt;then &lt;/span&gt;run &lt;span class="s2"&gt;"git rebase --continue"&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
You can instead skip this commit: run &lt;span class="s2"&gt;"git rebase --skip"&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
To abort and get back to the state before &lt;span class="s2"&gt;"git rebase"&lt;/span&gt;, run &lt;span class="s2"&gt;"git rebase --abort"&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Could not apply cce2b78... added another statement

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git status
interactive rebase &lt;span class="k"&gt;in &lt;/span&gt;progress&lt;span class="p"&gt;;&lt;/span&gt; onto bbf1e2e
Last &lt;span class="nb"&gt;command &lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;1 &lt;span class="nb"&gt;command &lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;:
   pick cce2b78 added another statement
No commands remaining.
You are currently rebasing branch &lt;span class="s1"&gt;'branch2'&lt;/span&gt; on &lt;span class="s1"&gt;'bbf1e2e'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;fix conflicts and &lt;span class="k"&gt;then &lt;/span&gt;run &lt;span class="s2"&gt;"git rebase --continue"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git rebase --skip"&lt;/span&gt; to skip this patch&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git rebase --abort"&lt;/span&gt; to check out the original branch&lt;span class="o"&gt;)&lt;/span&gt;

Unmerged paths:
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git restore --staged &amp;lt;file&amp;gt;..."&lt;/span&gt; to unstage&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add &amp;lt;file&amp;gt;..."&lt;/span&gt; to mark resolution&lt;span class="o"&gt;)&lt;/span&gt;
    both modified:   main.py

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; nano main.py

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'made changes'&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git status

interactive rebase &lt;span class="k"&gt;in &lt;/span&gt;progress&lt;span class="p"&gt;;&lt;/span&gt; onto bbf1e2e
Last &lt;span class="nb"&gt;command &lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;1 &lt;span class="nb"&gt;command &lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;:
   pick cce2b78 added another statement
No commands remaining.
You are currently editing a commit &lt;span class="k"&gt;while &lt;/span&gt;rebasing branch &lt;span class="s1"&gt;'branch2'&lt;/span&gt; on &lt;span class="s1"&gt;'bbf1e2e'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git commit --amend"&lt;/span&gt; to amend the current commit&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git rebase --continue"&lt;/span&gt; once you are satisfied with your changes&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git rebase
 &lt;span class="nt"&gt;--continue&lt;/span&gt;
Successfully rebased and updated refs/heads/branch2.

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git push origin branch2
Merge branch &lt;span class="s1"&gt;'branch2'&lt;/span&gt; of https://github.com/datawrangl3r/conflict into branch2
To https://github.com/datawrangl3r/conflict.git
 &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;rejected]        branch2 -&amp;gt; branch2 &lt;span class="o"&gt;(&lt;/span&gt;non-fast-forward&lt;span class="o"&gt;)&lt;/span&gt;
error: failed to push some refs to &lt;span class="s1"&gt;'https://github.com/datawrangl3r/conflict.git'&lt;/span&gt;
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes &lt;span class="o"&gt;(&lt;/span&gt;e.g.
hint: &lt;span class="s1"&gt;'git pull ...'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; before pushing again.
hint: See the &lt;span class="s1"&gt;'Note about fast-forwards'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s1"&gt;'git push --help'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;details.

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git pull origin branch2
hint: Pulling without specifying how to reconcile divergent branches is
hint: discouraged. You can squelch this message by running one of the following
hint: commands sometime before your next pull:
hint:
hint:   git config pull.rebase &lt;span class="nb"&gt;false&lt;/span&gt;  &lt;span class="c"&gt;# merge (the default strategy)&lt;/span&gt;
hint:   git config pull.rebase &lt;span class="nb"&gt;true&lt;/span&gt;   &lt;span class="c"&gt;# rebase&lt;/span&gt;
hint:   git config pull.ff only       &lt;span class="c"&gt;# fast-forward only&lt;/span&gt;
hint:
hint: You can replace &lt;span class="s2"&gt;"git config"&lt;/span&gt; with &lt;span class="s2"&gt;"git config --global"&lt;/span&gt; to &lt;span class="nb"&gt;set &lt;/span&gt;a default
hint: preference &lt;span class="k"&gt;for &lt;/span&gt;all repositories. You can also pass &lt;span class="nt"&gt;--rebase&lt;/span&gt;, &lt;span class="nt"&gt;--no-rebase&lt;/span&gt;,
hint: or &lt;span class="nt"&gt;--ff-only&lt;/span&gt; on the &lt;span class="nb"&gt;command &lt;/span&gt;line to override the configured default per
hint: invocation.
From https://github.com/datawrangl3r/conflict
 &lt;span class="k"&gt;*&lt;/span&gt; branch            branch2    -&amp;gt; FETCH_HEAD
Merge made by the &lt;span class="s1"&gt;'recursive'&lt;/span&gt; strategy.

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git push origin branch2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Always delete ❌ your branch upon completion of a feature request.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Follow my Blog @ &lt;a href="https://www.datawrangler.in"&gt;https://www.datawrangler.in&lt;/a&gt;&lt;br&gt;
Github @ &lt;a href="https://github.com/datawrangl3r"&gt;https://github.com/datawrangl3r&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>ETL &amp; Enterprise Level Practices</title>
      <dc:creator>Sathyasarathi</dc:creator>
      <pubDate>Thu, 03 Dec 2020 18:36:22 +0000</pubDate>
      <link>https://dev.to/sathyasarathi90/etl-enterprise-level-practices-4gn3</link>
      <guid>https://dev.to/sathyasarathi90/etl-enterprise-level-practices-4gn3</guid>
      <description>&lt;p&gt;ETL Strategies &amp;amp; Pipelines have now become inevitable for cloud business needs. There are several ETL tools in the market ranging from open-source ones such as Airflow, Luigi, Azkaban, Oozie to enterprise solutions such as Azure Data Factory, AWS Glue, Alteryx, Fivetran, etc. But what makes the data pipelines to be Industry-ready and robust? The practices and the industrial standards that are put into the architecture and design of the pipelines do. In this article, we touch upon these aspects and characteristics of Enterprise-level practices that can be followed to make a robust data pipeline. &lt;/p&gt;

&lt;h2&gt;
  
  
  ETL-Alphabets
&lt;/h2&gt;

&lt;p&gt;We will be explaining the ETL strategies, alphabetically as shown in the illustration below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Att_Oao--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lodl3adgr4kxstngpx05.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Att_Oao--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lodl3adgr4kxstngpx05.jpg" alt="Illustration: ETL-Alphabets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Archival Strategies
&lt;/h3&gt;

&lt;p&gt;Archive older unused data, to keep the data warehouses clean and performant. By performing such cleanups, unused indexes can be cleared, and unused space can be retrieved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be a responsible citizen
&lt;/h3&gt;

&lt;p&gt;Select only those columns that are required for the analysis - While performing the extraction, select only the required columns. This will help in increasing the performance of the data warehouse and also, speeds up the extraction process.&lt;br&gt;
Power down resources when not in use. If you are using clusters for processing or databases for staging; make sure to power down the resources that are not in use.&lt;/p&gt;
&lt;h3&gt;
  
  
  Cache Data
&lt;/h3&gt;

&lt;p&gt;Accessing a table more often? Why not cache that table for rapid usage? For example, Spark’s createOrReplaceTempView function creates just a mere reference to the table whereas the saveAsTable() stores the table to HDFS. This won’t make much of a difference for smaller datasets, yet could be a pivotal improvement while transforming larger datasets.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Security &amp;amp; Anonymity
&lt;/h3&gt;

&lt;p&gt;Mask the sensitive information or better not to bring those to the target Data warehouse. Always perform your ETL practices over VPNs or secured groups. Always use a key vault service (Vault, Azure Key Vault, AWS Secrets Manager), etc. in case if you don’t have a Universal Authentication Identity Service Provider protected by individual Service Principals.&lt;/p&gt;
&lt;h3&gt;
  
  
  Extract Only Necessary Fields
&lt;/h3&gt;

&lt;p&gt;You don’t always require a &lt;code&gt;select * from the table&lt;/code&gt;. Select only those fields that are required from the source database tables. If you are wondering if you needed any columns in the future, many of the ETL solutions such as Azure Data Factory, provide options to facilitate schema drift. This could be a major game-changer in terms of the performance and efficiency of the ETL processes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Find the Appropriate Business Date Column
&lt;/h3&gt;

&lt;p&gt;Identifying the fields is one, and identifying the business date columns is another. The business date columns are essential since the data lake timestamp columns are not always reliable. These columns are essential for performing incremental changes to your data warehouse.&lt;/p&gt;
&lt;h3&gt;
  
  
  Generalize the ETL solution
&lt;/h3&gt;

&lt;p&gt;The ETL solution that you create should be able to accommodate changes dynamically. Changes shouldn’t bring about havoc, rework, or major code changes. Make sure to bring in a lot of dynamic parameters and configurable placeholders such as File Location, File System Location, Logging Location, Name of Facts, Dimensions, Staging Tables, etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  High-Level Data flow
&lt;/h3&gt;

&lt;p&gt;Keep your ETL Pipelines and the corresponding data flows, as simple as possible. Plan before you start, draft a blueprint of what your pipeline is about to accomplish. This helps in figuring out those activities that are tricky and are prone to failures, such as processing at the staging layer and copy to the destination data warehouse.&lt;/p&gt;
&lt;h3&gt;
  
  
  Incremental Data Refreshes
&lt;/h3&gt;

&lt;p&gt;Incremental data refreshes are nothing but bringing in the data that has changed or newly inserted into the Data Lake. Business date stamps can be very helpful while performing incremental data refreshes. Incremental data refreshes can be performed wherever it's applicable since performing a complete refresh of the data for the whole year can be expensive if done frequently.&lt;/p&gt;
&lt;h3&gt;
  
  
  Joins in Queries
&lt;/h3&gt;

&lt;p&gt;Joins in queries are fine, as long as you know what you are doing and the query plan is under check. Make sure to check for the conditions used to join the query, filter the results even before you could join, if possible.&lt;/p&gt;
&lt;h3&gt;
  
  
  Keys-Surrogates &amp;amp; Composites
&lt;/h3&gt;

&lt;p&gt;Surrogate Keys are columns that are added to the data warehouse tables to ensure uniqueness in the destination tables. These keys are essential to perform an upsert operation (insert and update if the insert fails) on the destination tables. The choice of columns is based on the business context and usually, these keys are framed as an SHA encryption of multiple columns combined using a delimiter. &lt;/p&gt;

&lt;p&gt;E.g.: In a fact table representing details about the users purchasing products: Product_id, Order_timestamp, and Customer_id, Delivery_date uniqueness can be achieved for each entry by creating a surrogate key like SHA(Product_id, ‘|’, Order_timestamp, ‘|’, Customer_id). In case, there’s an update in the Delivery_date, the newer date can be updated based on the surrogate key in the Data warehouse.&lt;/p&gt;

&lt;p&gt;While querying the data warehouse, it’s a good practice to check the query plan, if the indexes are properly used. If not, the required indexes can be created. For queries utilizing multiple columns, these can be recognized and a composite key combining these columns can be created for easier access.&lt;/p&gt;
&lt;h3&gt;
  
  
  Logging
&lt;/h3&gt;

&lt;p&gt;Logging helps to track down the pesky ETL run failures. If the ETL application provides logging out of the box, no external logging is required. If not, it’s highly essential to have a custom script that does the logging.&lt;/p&gt;
&lt;h3&gt;
  
  
  Monitor
&lt;/h3&gt;

&lt;p&gt;Mechanisms to monitor the ETL processes need to be in place. For example, Azure Data Factory and Airflow has some really good interfaces to track the failures. In addition to this, mechanisms such as e-mail alerts and slack notifications can be really helpful. In short, a holistic view of the pipeline’s health needs to be available to monitor at all times.&lt;/p&gt;
&lt;h3&gt;
  
  
  Nested Loops-Avoid at all costs
&lt;/h3&gt;

&lt;p&gt;In most situations, the memory leaks observed in the ETL jobs are due to the Join Strategies. This can be found in the Query Plans. Depending on the database and processing engines, the strategy may vary. &lt;/p&gt;

&lt;p&gt;For example: In Spark, the join strategy can be rated from ‘worst’ to ‘best’ as follows:&lt;/p&gt;

&lt;p&gt;Broadcast nested loop join (worst) &amp;gt; Cartesian Product &amp;gt; sort-merge join &amp;gt; Hash Joins (best)&lt;/p&gt;

&lt;p&gt;As noticed above nested loop join is chosen to be the last resort. A nested loop join strategy looks 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;for each_row in relation_1:
 for each_row in relation_2:
 # join condition gets executed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An 'n' squared complexity is not something you would want to experience on a large dataset.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimize &amp;amp; Scale
&lt;/h3&gt;

&lt;p&gt;ETL Pipelines can be optimized by finding the right time window to execute the pipeline. For example, while scheduling a pipeline to extract the data from the production database, the production business hours need to be taken into consideration so that, the transactional queries of the business applications are not hindered. Choosing the right choice of tools, processing clusters, and strategies can help scale the pipeline. For example, the choice of the clusters for processing can be decided by calculating the query runtime statistics and volume of the rows extracted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parallelize wherever possible
&lt;/h3&gt;

&lt;p&gt;Parallel processing is always efficient than sequential processing. Big data storage solutions and non-columnar destinations work parallel in nature. Higher versions of relational databases such as Postgres has the ability to parallelize the queries too. The individual processes of ETL can also be parallelized if the tool provides a solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quality of Data
&lt;/h3&gt;

&lt;p&gt;The source can be in any form, i.e.) the data in data lakes can be in varied forms. However, the target data warehouses should always have clean data. The ETL scripts need to make sure that the data written to the destination needs to be of high quality. The quality parameters include precision in floats, prevent varchar overflows, split columns based on the present delimiters (‘|’, ‘,’, ‘\t’), use the appropriate compression formats, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recovery &amp;amp; Checkpoints
&lt;/h3&gt;

&lt;p&gt;The ETL Pipelines are to be designed in a pessimistic way, by asking the ‘what-if’ questions. Assume that there’s an outage in the source data lake/datastore; Will the pipeline be capable enough to pause and resume or perhaps, recover or restore from the failed checkpoint? By designing such fail-safe strategies, the pipelines can be robust. &lt;/p&gt;

&lt;h3&gt;
  
  
  Schemas &amp;amp; SCDs
&lt;/h3&gt;

&lt;p&gt;Warehouse and ETL designs are purely driven by the business requirements and the Engineers need to ask the right questions to design the pipeline and BI requirements that the business needs. Schema &amp;amp; Slowly Changing Dimensions are the major steering components for the warehouse design. The schemas can be Star schemas or Snow Flake schemas depending on how fast the schema evolves. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Star Schemas are constant and each dimension is represented only by a one-dimensional table.&lt;/li&gt;
&lt;li&gt;Snow Flake Schemas are a lot more granular compared to the Star Schemas where dimension tables are normalized further, split into multiple tables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition to this, depending on the necessity to store the historic information of the facts or dimensions, the choice needs to be made between SCD1 or SCD2. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SCD1 is the activity of updating the existing rows if the key matches.&lt;/li&gt;
&lt;li&gt;SCD2 is the activity where the older data is preserved/invalidated and inserts the newer rows, promoting them to be the latest. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Temp Tables-Use them Wisely
&lt;/h3&gt;

&lt;p&gt;As mentioned in the ‘Cache Data’, temporary tables are just a mere representation of the physical tables. They are accessible only to the executed cluster, available until the cluster runs, and are slow for operations since it is neither in memory nor persisted. True to its name, these temp tables are destroyed upon the termination of the cluster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Upserts
&lt;/h3&gt;

&lt;p&gt;As mentioned in the section ‘Schemas &amp;amp; SCDs’, SCD1 will depend on the unique key based on which the upsert operation is done. Upserts are nothing but Inserts and Updates on conflict. Here, the conflict refers to the inability to insert since the key already exists, which will in turn lead to an upsert operation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Views
&lt;/h3&gt;

&lt;p&gt;Creating views on top of complex queries can be very helpful at times when the results of the query needed to be computed and used only a minimal number of times. If it’s too expensive to store, views can come in quite handy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where Conditions
&lt;/h3&gt;

&lt;p&gt;While performing the transformations, selecting only the bucket of data that is required for the processing can save a large amount of computing time. The ‘where’ clauses can help in achieving this, especially during the incremental refreshes.&lt;/p&gt;

</description>
      <category>etl</category>
      <category>adf</category>
      <category>database</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Red Vs Blue Pill — Making the right decision on the choice of BI Server</title>
      <dc:creator>Sathyasarathi</dc:creator>
      <pubDate>Mon, 09 Mar 2020 21:20:00 +0000</pubDate>
      <link>https://dev.to/sathyasarathi90/red-vs-blue-pill-making-the-right-decision-on-the-choice-of-bi-server-5fpc</link>
      <guid>https://dev.to/sathyasarathi90/red-vs-blue-pill-making-the-right-decision-on-the-choice-of-bi-server-5fpc</guid>
      <description>&lt;h3&gt;
  
  
  Red Vs Blue Pill — Making the right decision on the choice of BI Server
&lt;/h3&gt;

&lt;p&gt;This universe is governed by a cosmic duality, sets of two opposing and complementing principles or cosmic energies that can be observed in nature. There’s Yin and there’s Yang…&lt;/p&gt;

&lt;p&gt;There’s relational and there are non-relational databases…&lt;/p&gt;

&lt;p&gt;And of course, the visualization tools; There’s &lt;strong&gt;Tableau Server&lt;/strong&gt; and there’s &lt;strong&gt;Power BI Embedded&lt;/strong&gt;.!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P9owduXS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/400/1%2Al9-vhqfT73n9MFiBxQKPUA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P9owduXS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/400/1%2Al9-vhqfT73n9MFiBxQKPUA.png" alt=""&gt;&lt;/a&gt;The Yin &amp;amp; Yang of the present BI universe&lt;/p&gt;

&lt;p&gt;There’s no such thing as a perfect BI server that solves everyone’s (the admin, the data-scientist, the analyst, the end-user) problems. Each of these tools outweighs each other in several aspects and we are about to settle the score once and for all on a one-on-one comparison between Tableau Server and Power BI Embedded.&lt;/p&gt;

&lt;p&gt;By the time when you are done reading these articles, you should be able to answer the following question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should you choose Tableau Server or Power BI Embedded?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZvbgwjP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/498/1%2ACswfnXP7zABBwuSkf0fhpg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZvbgwjP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/498/1%2ACswfnXP7zABBwuSkf0fhpg.gif" alt=""&gt;&lt;/a&gt;After this, there is no turning back.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choice of the Cloud &amp;amp; Databases:
&lt;/h3&gt;

&lt;p&gt;Are you using Microsoft SQL server or are your servers hosted on Microsoft Azure? well, why not use Power BI? Yes, you heard me right, you’ve got a good edge over the Tableau. Check if the data source that you are using, is developed or maintained by Microsoft or even better — Check if your database is compatible for not being required to have an on-premises data gateway from &lt;a href="https://docs.microsoft.com/en-us/power-bi/power-bi-data-sources"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Of course, this is not the case with Tableau; with a wide variety of connectors and drivers to establish the connectivity, Tableau seems to be much more friendly in terms of the databases. Also, with the support toward Tableau Server packages for Linux, Tableau servers have become much more efficient in managing the resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e26j8Ffr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/412/0%2AfRrTPHAEMQZYRzIx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e26j8Ffr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/412/0%2AfRrTPHAEMQZYRzIx.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Extracts &amp;amp; Refreshes:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How huge is your data? And are you using extracts or live connections?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Of course, you may follow all the good practices; if your extract still happens to be huge, Tableau seems to be a better choice. The ability to devise a multi-node architecture for the tableau server is a better fit to improve the performance of the data extracts and data refreshes.&lt;br&gt;&lt;br&gt;
 In the case of Power BI, the rate of refreshes depend on the size and configuration of the data gateway instance deployed in the same subnet as that of the databases (for Non-Microsoft databases).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bzDyOaHh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/480/0%2AvvvpkOXbDVHxxHNJ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bzDyOaHh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/480/0%2AvvvpkOXbDVHxxHNJ.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Visualization Renders:
&lt;/h3&gt;

&lt;p&gt;Visualization is the core of the BI exercise. And if those dashboards are not loading on time, that’s gonna hit you real bad. The rendering is all dependent on the hardware — especially the memory. In Tableau, you get to control your hardware — whether it’s a cluster setup or a single node setup. This is not the case with Power BI where you need to purchase a premium dedicated capacity for the rendering to happen; the lowest configuration — A1 has a capacity of performing about 300 renders per hour with a price of 1$ approx per hour.&lt;br&gt;&lt;br&gt;
Tableau is the winner here since you are not limited by the number of renders happening.&lt;/p&gt;

&lt;p&gt;Well, it doesn’t stop there. and when your audience grows and when you go up the ladder from (A1 to A6) configuration, you will know that you are shelling out a huge amount of money (could go all the way up to 36 times that of the cost of A1).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bmkWPgyU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/540/0%2AKzzsVDHqMbidfGk8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bmkWPgyU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/540/0%2AKzzsVDHqMbidfGk8.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scale:
&lt;/h3&gt;

&lt;p&gt;How many viewers are about to have a look at your dashboards? Is it going to be the dashboard with your visualizations on it or is it going to be just the PDF rendering of your dashes? For client-side renderings; Tableau has a cluster setup available to be configured with multiple nodes, each of which can be assigned with the specific processes and dozens of other tweak-able options in hand; scalability is at disposal for the Tableau admins.&lt;/p&gt;

&lt;p&gt;Does it mean that Power BI is up for no good? They do have a dedicated capacity that can be modified based on the peak hour refresh rates and the number of renders happening in an hour.&lt;/p&gt;

&lt;p&gt;We don’t have any winners for this round since both the services incur similar costs when it comes to the licensing aspect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sEJtZ-IQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/480/0%2AukWitRBPwyxClReZ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sEJtZ-IQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/480/0%2AukWitRBPwyxClReZ.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Licenses &amp;amp; Pricing:
&lt;/h3&gt;

&lt;p&gt;By this time, you might have figured out the right BI tool for the job. And that’s the reason why pricing comes at the end.&lt;/p&gt;

&lt;p&gt;This topic by itself requires a separate post to talk about as a whole. We will try to cover as crisp as we could in this section.&lt;/p&gt;

&lt;p&gt;Let’s look at a hypothetical scenario, Shall we? Consider an Organization with about 200 data scientists; let’s estimate the Pricing for both Tableau Server &amp;amp; Power BI Embedded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u8I39fmx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2A0AAY4I5VVbF2h5NT.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u8I39fmx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2A0AAY4I5VVbF2h5NT.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tableau Server — Requisite &amp;amp; Cost:&lt;/strong&gt;   &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;License for the users to use Tableau Desktop &amp;amp; publish to tableau server [70$ per user per month].
&lt;/li&gt;
&lt;li&gt;A tableau server hosted an a compute instance with at least 8 physical cores and 32 Gigabytes of RAM (if a cluster setup is required for better performance — add two more instances with at least 4 cores and 16 Gigabytes of RAM to it)
[Single node — 0.70$ per hour; Cluster 0.70$ + 0.38$ + 0.38$ = 1.46$ per hour].
&lt;/li&gt;
&lt;li&gt;A Server creator license with the required number of creators [70$ per user per month].&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Cost incurred: (200*70)+(1.46*730)+(200*70) = &lt;strong&gt;&lt;em&gt;29065.8$ /month&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
(For a cluster Setup)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Power BI Embedded — Requisite &amp;amp; Cost:&lt;/strong&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pro License for the individual users [9.99$ per user per month].
&lt;/li&gt;
&lt;li&gt;A Power BI Embedded dedicated capacity for performing the refreshes on a custom workspace — let’s consider A4 for the sake of the discussion [$8.06 per hour].
&lt;/li&gt;
&lt;li&gt;A data gateway inside the same subnet as that of the database (recommended configuration of 4 cores and 16 Gigabytes of RAM) [0.38$ per hour].&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Cost incurred: (200*9.99)+(8.06*730)+(730*0.38) = &lt;strong&gt;&lt;em&gt;8159.2$ per month&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we have the facts right., it’s time to pick our winner!! There isn’t…Both are good contenders and it all comes down to our requirement &amp;amp; usage.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Let’s build Visualisations; not wage wars!!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://www.datawrangler.in/2020/03/red-vs-blue-pill-making-right-decision.html"&gt;&lt;em&gt;https://www.datawrangler.in&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on March 9, 2020.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>powerbiembedded</category>
      <category>tableauserver</category>
      <category>tableau</category>
      <category>comparison</category>
    </item>
    <item>
      <title>Postgres: Optimization &amp; Beyond</title>
      <dc:creator>Sathyasarathi</dc:creator>
      <pubDate>Sat, 10 Aug 2019 14:37:00 +0000</pubDate>
      <link>https://dev.to/sathyasarathi90/postgres-optimization-beyond-5am9</link>
      <guid>https://dev.to/sathyasarathi90/postgres-optimization-beyond-5am9</guid>
      <description>&lt;p&gt;Postgres, one of the widely used Relational Database Management System; has been widely adopted due to its ability to handle different workloads such as web services, warehouses, etc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Fun Fact:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;The name Postgres comes from its predecessor originated from UC Berkley’s Ingres Database (_INteractive GRaphics iterchangE System; meaning it’s Post-INGRES&lt;/em&gt;)._&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are times when the performance is straight forward and in other cases when the expected performance is not met; the Database requires some tweaking in the form of structural modifications to the table, Query Tuning, Configuration improvements, etc.&lt;/p&gt;

&lt;p&gt;This article will provide some useful pointers and action plans to become a power-user in optimizing Postgres.&lt;/p&gt;

&lt;p&gt;What to do when a query is slow?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zNRpr4eO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2Audxpi-nT0n98jkcu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zNRpr4eO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2Audxpi-nT0n98jkcu.gif" alt=""&gt;&lt;/a&gt;What to do when a query is slow?&lt;/p&gt;

&lt;p&gt;In most cases, the occurrence of a slow query is due to the absence of indexes, for those fields that are being used in the where clause of the query.&lt;/p&gt;

&lt;p&gt;That should have solved the problem, right? RIGHT?&lt;/p&gt;

&lt;p&gt;You:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f83H7hDE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2Ajjb-Ad2kwbCn-yAx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f83H7hDE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2Ajjb-Ad2kwbCn-yAx.gif" alt=""&gt;&lt;/a&gt;Not helping at all.!!&lt;/p&gt;

&lt;p&gt;I hear you; Life ain’t Fair, or &lt;em&gt;Is it?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Not all Indexes for the fields in the WHERE clause can be helpful; It all depends on the appropriate query plan prepared by the optimizer: Prepend &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; to the query and run it to find the query plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; Use &lt;a href="https://explain.depesz.com/"&gt;https://explain.depesz.com/&lt;/a&gt; to visualize and analyze your query plan. The color formatting gives a straight forward output to debug the reason for the slowness.&lt;/p&gt;

&lt;p&gt;The query plan itself can provide a whole lot of information about where the resources are overflowing. Given below, are a few of those keywords that you can find in the query plan and what they mean to you and the query performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sequential Scan:&lt;/strong&gt; Yes, you read that right. The scan occurs sequentially; the filter runs for the whole table and returns back the rows that match the condition which can be very expensive and exhaustive. In the case of a single page / small table, Sequential scans are pretty fast.&lt;/p&gt;

&lt;p&gt;But for larger tables; In order to speed up the query, the sequential scan needs to be changed to an &lt;strong&gt;Index Scan&lt;/strong&gt;. This can be done by creating indexes on the &lt;strong&gt;columns that are present in the where clause&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Index Scans / Index Only Scans:&lt;/strong&gt; Index Scans denote that the indexes are being properly used. Just make sure that the analyzing &amp;amp; vacuuming happens once in a while. This keeps all the dead tuples out of the way and allows the optimizer to choose the right index for the scan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bitmap Index Scan:&lt;/strong&gt; And this right here is the bummer. Bitmap Index Scans are accompanied by Bitmap Heap Scans on top. These scans occur mostly when one tries to retrieve multiple rows but not all, based on multiple logical conditions in the where clause.&lt;/p&gt;

&lt;p&gt;It basically creates a bitmap out of the pages of the table, based on the condition provided (hence the Bitmap Heap Scan on top). The query can be sped up by creating a &lt;strong&gt;composite index A.K.A multicolumn index&lt;/strong&gt;; which changes this scan to an Index Scan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caution:&lt;/strong&gt; The order of the columns in the composite index needs to be maintained the same order as that of the where clause.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---UVj3GId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/500/1%2A9GzLaUAPbJKNGJ_2cBwMUg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---UVj3GId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/500/1%2A9GzLaUAPbJKNGJ_2cBwMUg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Summarizing:
&lt;/h4&gt;

&lt;p&gt;Indexes are good; Unused Indexes are Bad;&lt;br&gt;&lt;br&gt;
Having Too many Indexes is OK, as long as they are being used at some point.&lt;/p&gt;

&lt;p&gt;More RAM for the DB is Good. VACUUM &amp;amp; ANALYZE of tables is too good!!!&lt;br&gt;&lt;br&gt;
ARCHIVAL of Old Data → Being a good citizen and you are awesome!!&lt;/p&gt;

&lt;p&gt;For optimal performance, the following settings (requires a restart of the server) need to be made to the postgresql conf file present in: &lt;code&gt;**_/etc/postgresql/10/main/postgresl.conf_**&lt;/code&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Allowed Values&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;shared Buffer &lt;/td&gt;
&lt;td&gt; 75% of RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;work_mem &lt;/td&gt;
&lt;td&gt; 25% of RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;maintenance_mem &lt;/td&gt;
&lt;td&gt;Min: 256MB; Max:512MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Consider the scenario, where Postgres Server’s has 160Gigs of RAM:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Allowed Values&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;shared_buffer&lt;/td&gt;
&lt;td&gt;120GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;work_mem&lt;/td&gt;
&lt;td&gt;40GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;maintenance_mem&lt;/td&gt;
&lt;td&gt;256MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h4&gt;
  
  
  Steps to Optimize a query:
&lt;/h4&gt;

&lt;p&gt;1) Run Explain Analyze on your Query, and if it takes too long; Run Explain on your Query.&lt;/p&gt;

&lt;p&gt;2) Copy the output and paste it onto the dialogue box @ &lt;a href="https://explain.depesz.com/"&gt;https://explain.depesz.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) Check the Stats of your query:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Index Scans / Index Only Scans&lt;/strong&gt; are the best and &lt;strong&gt;no changes&lt;/strong&gt; need to be made.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sequential Scans,&lt;/strong&gt; can be &lt;strong&gt;converted into&lt;/strong&gt;  &lt;strong&gt;Index Scans&lt;/strong&gt; by &lt;strong&gt;creating the index for the particular column&lt;/strong&gt; in the where clause.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bitmap Heap Scans,&lt;/strong&gt; can be &lt;strong&gt;converted into Index Scans&lt;/strong&gt; by &lt;strong&gt;creating composite indexes&lt;/strong&gt; A.K.A multicolumn indexes, with the &lt;strong&gt;same order&lt;/strong&gt; as that of the where clause, as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;indexName&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;tableName&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;Field1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;Field2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note to Self: Index &amp;amp; Optimize.!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qgcrDAtF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/448/1%2AXs4J9Eyfxo_fvZSRp5HHFg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qgcrDAtF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/448/1%2AXs4J9Eyfxo_fvZSRp5HHFg.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://www.datawrangler.in/2019/08/postgres-optimization-beyond-level-up.html"&gt;&lt;em&gt;https://www.datawrangler.in&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on August 10, 2019.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>sql</category>
      <category>database</category>
      <category>index</category>
      <category>postgres</category>
    </item>
    <item>
      <title>CD-Stream:CDC Replicator Tool</title>
      <dc:creator>Sathyasarathi</dc:creator>
      <pubDate>Tue, 30 Oct 2018 21:12:00 +0000</pubDate>
      <link>https://dev.to/sathyasarathi90/cd-stream-cdc-replicator-tool-13hp</link>
      <guid>https://dev.to/sathyasarathi90/cd-stream-cdc-replicator-tool-13hp</guid>
      <description>&lt;h4&gt;
  
  
  ++ Cons on ETL pipelines
&lt;/h4&gt;

&lt;p&gt;Just another day at the workplace;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;5 minutes post the boot:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You hear everyone complain that the production database is slow. You quickly start to investigate; exploring all possible outcomes on the dashboards...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Could it have been the long-running slow query which you had raised a ticket for the production support to fix? Or Is it one of the queries run based on a non-indexed column?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BCZFJnIB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2A5b7aE4SKkbTm-jb8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BCZFJnIB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2A5b7aE4SKkbTm-jb8.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;6th Minute and 15 minutes later:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, you hear the fellow data-analysts lament over their failed reports.&lt;/p&gt;

&lt;p&gt;You now realize that your CPU had taken a humongous amount of query load and you understand that your relational database system has gone for a toss into an eternal slumber.&lt;/p&gt;

&lt;h3&gt;
  
  
  And all of this due to a slow running query of your ETL pipeline..!! Ding. Ding... Ding…!! We have a winner!!!
&lt;/h3&gt;

&lt;p&gt;Alright, let’s back it up a little bit.&lt;/p&gt;

&lt;p&gt;Probably you did/used one of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SELECT * from production_database.table where updated_at between x and y;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bulk exports and Dumps once in every few minutes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Long-running and forgotten Zombie Crontabs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dH1CZBKE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/311/0%2ANWQ-pURqbOWtGPdr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dH1CZBKE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/311/0%2ANWQ-pURqbOWtGPdr.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s put it this way... DB Size &amp;lt; 500 GB; it’s OK to do selects but if it exceeds &amp;gt;500GB, unless you have cuts in the budget, do not ever do a bulk select and transfer it over the wire to the destination database in the form of a pipeline.&lt;/p&gt;

&lt;h4&gt;
  
  
  Enter CDC:
&lt;/h4&gt;

&lt;p&gt;CDC A.K.A Change Data Capture is there to assist this data wrangling exercise and if your data is rapidly growing and if your BI/BA needs access to that sweet-sweet DWH (data warehouse); THIS right here, is the way to go.&lt;/p&gt;

&lt;h4&gt;
  
  
  You meant the replication? — I don’t wanna get stuck with my OLTP DB Engine:
&lt;/h4&gt;

&lt;p&gt;Well, you are not alone. For many reasons, data-wranglers generally don’t prefer a similar database engine as that of the OLTP. The main reasons include query performance, need for triggers and ease of re-running transformation jobs. But, doing so, requires setting up airflow clusters and setting up connectors to transform and load.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nvyGd-au--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2AS7iFWzeO5Ts9cYJ2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nvyGd-au--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2AS7iFWzeO5Ts9cYJ2.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wouldn’t it be great if you could do all this without doing a bulk selection from the production database? Of course, you can...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CD-Stream&lt;/strong&gt; is a cross-database CDC driven replicator tool that currently supports replication between &lt;strong&gt;&lt;em&gt;MySQL and Postgres&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The tool runs queues to process the information occurring in the binary logs of the source database and replicates it across to a destination database of an entirely different engine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ctdh6Uir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/0%2AzO-ZxOZB5LpJtGsY.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ctdh6Uir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/0%2AzO-ZxOZB5LpJtGsY.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Post the setup, as given in the project page: &lt;a href="https://github.com/datawrangl3r/cd-stream"&gt;CD-Stream&lt;/a&gt;; there’s a directory called ‘sample’ in the project which contains some of the intensive DDL and Data Insertion scripts, for you to evaluate and exercise.&lt;/p&gt;

&lt;p&gt;And that, &lt;em&gt;People&lt;/em&gt;; is how you wrangle production data!!!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://www.datawrangler.in/2018/10/cd-streamcdc-replicator-tool-cons-on.html"&gt;&lt;em&gt;https://www.datawrangler.in&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on October 30, 2018.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>postgres</category>
      <category>python</category>
      <category>cdc</category>
      <category>etl</category>
    </item>
    <item>
      <title>ES Index — S3 Snapshot &amp; Restoration:</title>
      <dc:creator>Sathyasarathi</dc:creator>
      <pubDate>Fri, 15 Dec 2017 16:26:00 +0000</pubDate>
      <link>https://dev.to/sathyasarathi90/es-index-s3-snapshot-restoration-73p</link>
      <guid>https://dev.to/sathyasarathi90/es-index-s3-snapshot-restoration-73p</guid>
      <description>&lt;h3&gt;
  
  
  ES Index — S3 Snapshot &amp;amp; Restoration:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f3LgfzRm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/484/0%2AtB85jys_DWuTYI7o.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f3LgfzRm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/484/0%2AtB85jys_DWuTYI7o.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The question is... What brings you here? Fed up with all the searches on how to back-up and restore specific indices?&lt;/p&gt;

&lt;p&gt;Fear not, for your search quest ends here.!&lt;/p&gt;

&lt;p&gt;After going through dozens of tiny gists and manual pages, here it is.. We’ve done all the heavy lifting for you.&lt;/p&gt;

&lt;p&gt;The following tutorial was tested on &lt;strong&gt;&lt;em&gt;elasticsearch V5.4.0&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And before we proceed, remember:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do’s:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make sure that the &lt;strong&gt;&lt;em&gt;elasticsearch version of the backed-up&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;cluster’s version &amp;lt;=(lesser than or equals) Restoring Cluster’s version.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dont’s:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unless it’s highly necessary;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;curl -XDELETE ‘&lt;a href="http://localhost:9200/nameOfTheIndex"&gt;http://localhost:9200/nameOfTheIndex&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;#deletes a specific index&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Especially not, when you are drunk!:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;curl -XDELETE ‘&lt;a href="http://localhost:9200/_all"&gt;http://localhost:9200/_all&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;#deletes all indexes&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;(This is where the drunk part comes in..!!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GEJcxrRo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2APaiwTUgOnjUipmrX.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GEJcxrRo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/500/0%2APaiwTUgOnjUipmrX.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step1: Install S3 plugin Support
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bin/elasticsearch-plugin &lt;span class="nb"&gt;install &lt;/span&gt;repository-s3  
&lt;span class="c"&gt;# (or)  &lt;/span&gt;
&lt;span class="nb"&gt;sudo&lt;/span&gt; /usr/share/elasticsearch/bin/elasticsearch-plugin &lt;span class="nb"&gt;install &lt;/span&gt;repository-s3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It depends on where your elasticsearch-plugin executable is installed. This enables the elasticsearch instance to communicate with the AWS S3 buckets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step2: Input the Snapshot registration settings
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;METHOD&lt;/strong&gt; : PUT&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="http://localhost:9200/_snapshot/logs_backup?verify=false&amp;amp;pretty"&gt;http://localhost:9200/_snapshot/logs_backup?verify=false&amp;amp;pretty&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PAYLOAD:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“type”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“s&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“settings”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“bucket”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“WWWWWW”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“region”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“us-east&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“access_key”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“XXXXXX”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“secret_key”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“YYYYYY”&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;In the URL:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;logs_backup&lt;/strong&gt;: Name of the snapshot file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In the payload JSON:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;bucket&lt;/strong&gt;: “WWWWW” is where you enter the name of the bucket.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;access_key &amp;amp; secret_key&lt;/strong&gt;: The values “XXXXXX” and “YYYYYY” is where we key in the access key and secret key for the buckets based on the &lt;em&gt;IAM&lt;/em&gt; policies. If you need any help to find it, here’s a link that should guide you through (&lt;a href="https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/"&gt;https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/&lt;/a&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;region&lt;/strong&gt;: region where the bucket is hosted (choose any from: &lt;a href="http://docs.aws.amazon.com/general/latest/gr/rande.html"&gt;http://docs.aws.amazon.com/general/latest/gr/rande.html&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should give a response as ‘&lt;strong&gt;{“acknowledged”: “true”}&lt;/strong&gt;’.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step3: Cloud-Sync — list all Snapshots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="http://localhost:9200/_cat/snapshots/logs_backup?v"&gt;http://localhost:9200/_cat/snapshots/logs_backup?v&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the URL&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;logs_backup&lt;/strong&gt;: Name of the snapshot file
Time to sync up all the list of snapshots. If all our settings have been synced up just fine; we should end up with a list of indices, close to that of what is shown below:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4CtFgRRg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/811/0%2AF29ShkFj4tm_F5VC.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4CtFgRRg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/811/0%2AF29ShkFj4tm_F5VC.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step4: Creating a Snapshot
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;METHOD&lt;/strong&gt; : PUT&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="http://localhost:9200/_snapshot/logs_backup/type_of_the_backup?wait_for_completion=true"&gt;http://localhost:9200/_snapshot/logs_backup/type_of_the_backup?wait_for_completion=true&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PAYLOAD:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“indices”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“logstash&lt;/span&gt;&lt;span class="mf"&gt;-2017.11&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“include_global_state”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“compress”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“encrypt”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;In the URL&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;logs_backup&lt;/strong&gt;: Name of the snapshot file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;type_of_the_backup&lt;/strong&gt;: Could be any string&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In the payload JSON&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;indices&lt;/strong&gt;: Correspond to the index which is to be backed-up to S3 bucket. In the case of multiple indices to back up under a single restoration point, the indices can be entered in the form of an array.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;include_global_state&lt;/strong&gt;: set to ‘false’ just to make sure there’s cross-version compatibility. &lt;strong&gt;&lt;em&gt;WARNING If set to ‘true’, the index can be restored only to the ES of the source version.&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;compress&lt;/strong&gt;: enables compression of the index meta files backed up to S3.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;encrypt&lt;/strong&gt;: In case if extra encryption on the indices is necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should give a response as ‘&lt;strong&gt;{“acknowledged”: “true”}&lt;/strong&gt;’&lt;/p&gt;

&lt;h3&gt;
  
  
  Step5: Restoring a Snapshot:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;METHOD&lt;/strong&gt; : PUT&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="http://localhost:9200/_snapshot/name_of_the_backup/index_to_be_restored/_restore"&gt;http://localhost:9200/_snapshot/name_of_the_backup/index_to_be_restored/_restore&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PAYLOAD:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“ignore_unavailable”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="err"&gt;“include_global_state”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;  
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the URL:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;logs_backup&lt;/strong&gt;  : Name of the snapshot file&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index_to_be_restored&lt;/strong&gt;: Any of the index from the id listed in Step:3&lt;/p&gt;

&lt;p&gt;In the payload JSON:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ignore_unavailable&lt;/strong&gt;: It’s safe to set this to true, to avoid unwanted checks.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;include_global_state&lt;/strong&gt;: set to ‘false’ just to make sure there’s cross-version compatibility. &lt;strong&gt;WARNING&lt;/strong&gt;  &lt;strong&gt;If set to ‘true’, the index can be restored only to the ES of the source version.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should give a response as ‘ &lt;strong&gt;{“acknowledged”: “true”}&lt;/strong&gt; ’&lt;/p&gt;

&lt;p&gt;Et Voila! The restoration is complete.&lt;/p&gt;

&lt;p&gt;And Don’t forget to recycle the space corresponding to the index by safely deleting it — Reuse, Reduce &amp;amp; Recycle :)&lt;/p&gt;

&lt;p&gt;Happy Wrangling!!!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://www.datawrangler.in/2017/12/es-index-s3-snapshot-restoration.html"&gt;&lt;em&gt;https://www.datawrangler.in&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on December 15, 2017.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>snapshot</category>
      <category>restore</category>
      <category>backup</category>
      <category>index</category>
    </item>
  </channel>
</rss>
