<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  <subtitle></subtitle>
  <id>https://www.endpointdev.com/blog/tags/big-data/</id>
  <link href="https://www.endpointdev.com/blog/tags/big-data/"/>
  <link href="https://www.endpointdev.com/blog/tags/big-data/" rel="self"/>
  <updated>2020-04-21T00:00:00+00:00</updated>
  <author>
    <name>End Point Dev</name>
  </author>
  
    <entry>
      <title>Migrating large PostgreSQL databases</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2020/04/migrating-large-postgresql-databases/"/>
      <id>https://www.endpointdev.com/blog/2020/04/migrating-large-postgresql-databases/</id>
      <published>2020-04-21T00:00:00+00:00</published>
      <author>
        <name>Árpád Lajos</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2020/04/migrating-large-postgresql-databases/migration.jpg&#34; alt=&#34;Migration&#34;&gt;&lt;/p&gt;
&lt;p&gt;Photo by &lt;a href=&#34;https://unsplash.com/@hgudka97&#34;&gt;Harshil Gudka&lt;/a&gt; on &lt;a href=&#34;https://unsplash.com/&#34;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;the-challenge&#34;&gt;The challenge&lt;/h3&gt;
&lt;p&gt;One of our clients has a large and important health-related application. It’s built on an end-of-life Ruby on Rails-based open source framework, heavily customized over the years. They wanted to upgrade to a newer, supported, Java-based open source application a partner organization had developed as a replacement. Both organizations used the old system previously. To do that we would need to migrate all their existing PostgreSQL data from the old system to the new one, retaining important customizations while adapting to the new database schema.&lt;/p&gt;
&lt;p&gt;Although there were many similarities between the old system and the new, the differences were significant enough to require careful study of the database schemas and the migration scripts designed to move the data:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There were schema-level differences between our old database and the partner organization’s old database.&lt;/li&gt;
&lt;li&gt;Even where the two old databases were similar there were differences on the data level, such as different standards, different values in table records, different representation, etc.&lt;/li&gt;
&lt;li&gt;We had different content, so if a script was working well for their data, it was not necessarily correct for us.&lt;/li&gt;
&lt;li&gt;There were dynamically generated tables for both old databases and we had to find out how we can convert our current schema elements along with its records to the planned schema elements along with its records.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We had to understand the differences between our and their old databases. Due to the number of tables and average number of columns, manual comparison between databases was not really an option. We knew that the algorithm of handling the scripts would look like below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;For each S in Scripts
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Analyze S and understand the intent behind it
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Compute a read-only version of S to avoid write operations
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Execute the read-only version of S
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Analyze the results and find out whether they are different from the expected results
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Convert our read-only version of S to S′, where S′ is compatible with our expectations
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    While there are technical issues do
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        Fix it
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    While end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Execute S′
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;For end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Understanding these differences was easier said than done. The main problem is that we found it difficult to define our exact expectations. For that purpose we needed a deeper understanding about the databases.&lt;/p&gt;
&lt;h3 id=&#34;entity-relationship-diagram&#34;&gt;Entity Relationship Diagram&lt;/h3&gt;
&lt;p&gt;We first needed to see an Entity Relationship Diagram (ER diagram or ERD). We used &lt;a href=&#34;https://www.dbvis.com/&#34;&gt;DbVisualizer&lt;/a&gt; for this.&lt;/p&gt;
&lt;p&gt;We imported the database into our local RDBMS and then created a database connection by right-clicking Connections in the left menu tree&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/04/migrating-large-postgresql-databases/dbvisualizer-connections.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;then clicking on Create Database Connection and selecting No Wizard&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/04/migrating-large-postgresql-databases/dbvisualizer-connection-wizard.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;and filling in the data.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/04/migrating-large-postgresql-databases/dbvisualizer-connection-form.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;After that, we double-clicked on the schema we wanted to generate an ER diagram for and clicked on Open Object.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/04/migrating-large-postgresql-databases/dbvisualizer-open-object.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Finally, we clicked on the References tab and a bird’s-eye view of the ER diagram was generated.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/04/migrating-large-postgresql-databases/dbvizualizer-references.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/04/migrating-large-postgresql-databases/dbvisualizer-schema-birdview.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then we right-clicked on the diagram and clicked on Export.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/04/migrating-large-postgresql-databases/dbvisualizer-schema-export.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;We chose SVG and saved it. After opening the SVG diagram, we saw that the schema was too big to easily analyze, so we dropped the tables we were not specifically interested in in our local copy and generated a new ER diagram. It was super easy and cool. Finally, we were able to see which parts of the other team’s database was old and which was new. We were also able to compare our old database with the new database we were implementing.&lt;/p&gt;
&lt;h3 id=&#34;comparing-our-databases-against-their-counterparts&#34;&gt;Comparing our databases against their counterparts&lt;/h3&gt;
&lt;p&gt;Next we needed to understand what the schema differences were between their old database and our old database to determine what selections in the scripts will not work properly and to determine how we needed to modify it to fit our technical nuances.&lt;/p&gt;
&lt;p&gt;We used Liquibase for this purpose. See &lt;a href=&#34;/blog/2020/02/compare-postgresql-schema-versions/&#34;&gt;Selva’s article on comparing PostgreSQL database schema versions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The actual command we used was &lt;a href=&#34;https://docs.liquibase.com/commands/community/diff.html&#34;&gt;&lt;code&gt;diff&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, we needed to make sure we had a proper setup and then we could run the command. The example output the documentation gives is this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Diff Results:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Reference Database: MYSCHEMA2 @ jdbc:oracle:thin:@localhost:1521:ORCL (Default Schema: MYSCHEMA2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Comparison Database: MYSCHEMA @ jdbc:oracle:thin:@localhost:1521:ORCL (Default Schema: MYSCHEMA)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Compared Schemas: MYSCHEMA2 -&amp;gt; MYSCHEMA
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Product Name: EQUAL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Product Version: EQUAL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Catalog(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Catalog(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Catalog(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Check Constraint(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Check Constraint(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Check Constraint(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Column(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Column(s):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DEPARTMENT.ACTIVE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.SERVICETECH.ACTIVE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.SERVICETECH2.ACTIVE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.SERVICETECH3.ACTIVE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.VIEW1.ACTIVE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.AUTHOR
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.COMMENTS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.CONTEXTS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.DATEEXECUTED
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.DEPLOYMENT_ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.DESCRIPTION
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.EXECTYPE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.FILENAME
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOGLOCK.ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DEPARTMENT.ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.SERVICETECH.ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.SERVICETECH2.ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.SERVICETECH3.ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.VIEW1.ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.LABELS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.LIQUIBASE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOGLOCK.LOCKED
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOGLOCK.LOCKEDBY
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOGLOCK.LOCKGRANTED
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.MD5SUM
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DEPARTMENT.NAME
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.SERVICETECH.NAME
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.SERVICETECH2.NAME
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.SERVICETECH3.NAME
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.VIEW1.NAME
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.ORDEREXECUTED
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     MYSCHEMA.DATABASECHANGELOG.TAG
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Column(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Database Package(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Database Package(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Database Package(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Database Package Body(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Database Package Body(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Database Package Body(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Foreign Key(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Foreign Key(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Foreign Key(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Function(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Function(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Function(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Index(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Index(s):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_DATABASECHANGELOGLOCK UNIQUE  ON MYSCHEMA.DATABASECHANGELOGLOCK(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_DEPARTMENT UNIQUE  ON MYSCHEMA.DEPARTMENT(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_SERVICETECH UNIQUE  ON MYSCHEMA.SERVICETECH(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_SERVICETECH2 UNIQUE  ON MYSCHEMA.SERVICETECH2(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_SERVICETECH3 UNIQUE  ON MYSCHEMA.SERVICETECH3(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Index(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Java Class(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Java Class(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Java Class(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Java Source(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Java Source(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Java Source(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Primary Key(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Primary Key(s):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_DATABASECHANGELOGLOCK on MYSCHEMA.DATABASECHANGELOGLOCK(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_DEPARTMENT on MYSCHEMA.DEPARTMENT(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_SERVICETECH on MYSCHEMA.SERVICETECH(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_SERVICETECH2 on MYSCHEMA.SERVICETECH2(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     PK_SERVICETECH3 on MYSCHEMA.SERVICETECH3(ID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Primary Key(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Sequence(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Sequence(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Sequence(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Stored Procedure(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Stored Procedure(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Stored Procedure(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Synonym(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Synonym(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Synonym(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Table(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Table(s):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     DATABASECHANGELOG
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     DATABASECHANGELOGLOCK
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     DEPARTMENT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     SERVICETECH
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     SERVICETECH2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     SERVICETECH3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Table(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Trigger(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Trigger(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Trigger(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing Unique Constraint(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected Unique Constraint(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed Unique Constraint(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Missing View(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unexpected View(s):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     VIEW1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Changed View(s): NONE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Liquibase command &amp;#39;diff&amp;#39; was executed successfully.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Of course, we could do this job manually by listing all the tables with psql’s &lt;code&gt;\dt&lt;/code&gt; and then checking each of them individually with &lt;code&gt;\d tablename&lt;/code&gt;, but if there are many tables, this would take forever.&lt;/p&gt;
&lt;p&gt;Yes, we can write software for this purpose, implementing an algorithm along the lines of&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tables = &amp;lt;execute \dt&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;For each (tables as table) do
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Differences[table] = difference(&amp;lt;execute \d table at db1&amp;gt;, &amp;lt;execute \d table at db2&amp;gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;End For&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;however, the algorithm above won’t handle special cases, like tables existing in db1 and not in db2 or vice versa. The algorithm above graciously outsources the arduous task of splitting the rows in both cases by identifying whether a row is a column name, an index, a foreign key, etc. and by identifying the subject of the line (e.g. column name) and finding the matches between the two to a function called difference.&lt;/p&gt;
&lt;p&gt;It is of course implementable, but it would add a considerable amount of work. We should also mention that such a newly developed piece of code would not be well tested yet and we would have to watch out for possible bugs, create unit tests, create a nice UI or file export to ensure that we can analyse the results, and so on. All this work is unnecessary due to the availability of Liquibase and we are only talking about a single command compared to the many here.&lt;/p&gt;
&lt;h3 id=&#34;dynamically-generated-tables&#34;&gt;Dynamically generated tables&lt;/h3&gt;
&lt;p&gt;In practical terms this means the data our software must manage does not fit a pre-established schema; users create and update new data collection forms regularly. These forms consist of sets of uniquely named questions and text-based answers to those questions. The &lt;a href=&#34;https://www.postgresql.org/docs/current/datatype-json.html&#34;&gt;PostgreSQL JSON data type&lt;/a&gt; may seem like a natural fit for such data. However, the original version of the software predates PostgreSQL’s now extensive JSON support. The software version from which we were upgrading stored these data in an &lt;a href=&#34;https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model&#34;&gt;Entity-Attribute-Value schema&lt;/a&gt;, a database pattern often maligned (justly) by database designers.&lt;/p&gt;
&lt;p&gt;In this version, a single table stored all the answers given for every user-defined question for every case in the system, along with a pointer to the associated question and case. As one might expect, this table grew fairly large, though its principal drawbacks were not its size but rather the large number of joins necessary to process data it contained, and the lack of sufficient data validation. It is possible that the &lt;a href=&#34;https://www.postgresql.org/docs/current/hstore.html&#34;&gt;hstore data type&lt;/a&gt; would have been a better fit, however, neither programming language support for hstore data nor developer familiarity with it made it an obvious choice at the time. We did use hstore widely in the backend for data manipulation functions that could be contained entirely in SQL.&lt;/p&gt;
&lt;p&gt;Fast forward to newer versions, where this schema has been redesigned. We weren’t involved in the design process and can’t comment on the justification behind this design decision, but the new version creates new tables within the database as needed for each data entry form, and text fields for each question on the form. This reduces the number of joins or aggregations necessary to compile all the data for one form for a single case, but it means creating SQL queries dynamically to create, and later to find, the tables and columns containing data of interest.&lt;/p&gt;
&lt;p&gt;We’ve run our fingers through the data several times, both during and after the migration, and found neither schema variant satisfies our every wish. Both versions store users’ data as text fields, whatever data type they may represent. Some form of data validation at the database level would be very nice, and in the new version where each field has its own column in the database, this is entirely possible, though of course, it would have required more work in the development process. In particular, many questions expect answers taken from a predefined set, for which &lt;a href=&#34;https://www.postgresql.org/docs/current/datatype-enum.html&#34;&gt;enumerated types&lt;/a&gt; could be a good fit. Of course, stored procedures could conceivably ensure valid data no matter its data type in the schema, but this doesn’t seem like a plausible option in practice. As a further drawback to the new approach, column and table names derive from user-defined data, meaning we need to sanitize user input to create valid PostgreSQL identifiers. This is a tricky process, and difficult to separate entirely into its own module to avoid reimplementing the same intricate logic multiple times.&lt;/p&gt;
&lt;p&gt;JSON data types provide one possible schema alternative, with all entries for one data entry form for a single case stored in a single JSON field, and indeed the &lt;a href=&#34;https://www.postgresql.org/docs/current/datatype-json.html#JSON-DOC-DESIGN&#34;&gt;PostgreSQL documentation&lt;/a&gt; proposes its use in such situations. It’s not entirely clear, though, that this would be a win. We could define new keys within the JSON structure without needing to modify the database schema itself, and with JSON we’d always know exactly what table and field we needed, to find the data we were after, but we’d still need to write queries dynamically in order to pull the desired fields. We could avoid some of the data sanitization necessary to create field names, as the rules for JSON key names are far more permissive than for column names in a proper database table. But, again barring extensive stored procedures, we would still have very limited ability to validate data within the database itself, as JSON supports only a small set of primitive types.&lt;/p&gt;
&lt;h3 id=&#34;putting-it-all-together&#34;&gt;Putting it all together&lt;/h3&gt;
&lt;p&gt;After we acquired the understanding that we needed we were able to work out the migration script according to the algorithm that we outlined at the start of this article.&lt;/p&gt;
&lt;p&gt;This was still a long, labor-intensive task which was done by repeated pair-programming sessions but we were able to reach high enough accuracy. So high that to our great surprise we were able to start the application after the migration process was done.&lt;/p&gt;
&lt;h3 id=&#34;release&#34;&gt;Release&lt;/h3&gt;
&lt;p&gt;We were able to do the release on a weekend and the three of us moved on to solving problems submitted by beta testers. We called this process “dragon hunting”.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/04/migrating-large-postgresql-databases/dragpon.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;(Written with help from &lt;a href=&#34;/team/selvakumar-arumugam/&#34;&gt;Selvakumar Arumugam&lt;/a&gt; and &lt;a href=&#34;/team/josh-tolley/&#34;&gt;Joshua Tolley&lt;/a&gt;.)&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Updated NoSQL benchmark: Cassandra, MongoDB, HBase, Couchbase</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2015/06/updated-nosql-benchmark-cassandra/"/>
      <id>https://www.endpointdev.com/blog/2015/06/updated-nosql-benchmark-cassandra/</id>
      <published>2015-06-04T00:00:00+00:00</published>
      <author>
        <name>Josh Williams</name>
      </author>
      <content type="html">
        &lt;p&gt;Back in April, we published a benchmark report on a number of NoSQL databases including Cassandra MongoDB, HBase, and Couchbase.  We endeavored to keep things fair and configured as identically as possible between the database engines.  But a short while later, DataStax caught two incorrect configuration items, in Cassandra and HBase, and contacted us to verify the problem.  Even with the effort we put in to keeping everything even, a couple erroneous parameters slipped through the cracks! I’ll save the interesting technical details for another post coming soon, but once that was confirmed we jumped back in and started work on getting corrected results.&lt;/p&gt;
&lt;p&gt;With the configuration fixed we re-ran a full suite of tests for both Cassandra and HBase.  The updated results have published a revised report that you can &lt;a href=&#34;http://www.datastax.com/wp-content/themes/datastax-2014-08/files/NoSQL_Benchmarks_EndPoint.pdf&#34;&gt;download in PDF format from the DataStax website&lt;/a&gt; (or see the &lt;a href=&#34;http://www.datastax.com/apache-cassandra-leads-nosql-benchmark&#34;&gt;overview link&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The revised results still show Cassandra leading MongoDB, HBase, and Couchbase in the various YCSB tests.&lt;/p&gt;
&lt;p&gt;For clarity the paper also includes a few additional configuration details that weren’t in the original report. We regret any confusion caused by the prior report, and worked as quickly as possible to correct the data. Feel free to get in contact if you have any questions.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>New NoSQL benchmark: Cassandra, MongoDB, HBase, Couchbase</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2015/04/new-nosql-benchmark-cassandra-mongodb/"/>
      <id>https://www.endpointdev.com/blog/2015/04/new-nosql-benchmark-cassandra-mongodb/</id>
      <published>2015-04-13T00:00:00+00:00</published>
      <author>
        <name>Jon Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;Today we are pleased to announce the results of a new NoSQL benchmark we did to compare scale-out performance of Apache Cassandra, MongoDB, Apache HBase, and Couchbase. This represents work done over 8 months by &lt;a href=&#34;/team/josh-williams/&#34;&gt;Josh Williams&lt;/a&gt;, and was commissioned by &lt;a href=&#34;http://www.datastax.com/&#34;&gt;DataStax&lt;/a&gt; as an update to a similar &lt;a href=&#34;/blog/2013/03/nosql-benchmark-of-cassandra-hbase/&#34;&gt;3-way NoSQL benchmark we did two years ago&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The database versions we used were Cassandra 2.1.0, Couchbase 3.0, MongoDB 3.0 (with the Wired Tiger storage engine), and HBase 0.98. We used YCSB (the &lt;a href=&#34;https://github.com/brianfrankcooper/YCSB&#34;&gt;Yahoo! Cloud Serving Benchmark&lt;/a&gt;) to generate the client traffic and measure throughput and latency as we scaled each database server cluster from 1 to 32 nodes. We ran a variety of benchmark tests that included load, insert heavy, read intensive, analytic, and other typical transactional workloads.&lt;/p&gt;
&lt;p&gt;We avoided using small datasets that fit in RAM, and included single-node deployments only for the sake of comparison, since those scenarios do not exercise the scalability features expected from NoSQL databases. We performed the benchmark on Amazon Web Services (AWS) EC2 instances, with each test being performed three separate times on three different days to avoid unreproduceably anomalies. We used new EC2 instances for each test run to further reduce the impact of any “lame instance” or “noisy neighbor” effect on any one test.&lt;/p&gt;
&lt;p&gt;Which database won? It was pretty overwhelmingly Cassandra. One graph serves well as an example. This is the throughput comparison in the Balanced Read/Write Mix:&lt;/p&gt;
&lt;img height=&#34;398&#34; src=&#34;/blog/2015/04/new-nosql-benchmark-cassandra-mongodb/image-0.png&#34; width=&#34;732&#34;/&gt;
&lt;p&gt;Our full report, &lt;a href=&#34;http://www.datastax.com/wp-content/themes/datastax-2014-08/files/NoSQL_Benchmarks_EndPoint.pdf&#34;&gt;Benchmarking Top NoSQL Databases&lt;/a&gt;, contains full details about the configurations, and provides this and other graphs of performance at various node counts. It also provides everything needed for others to perform the same tests and verify in their own environments. But beware: Your AWS bill will grow pretty quickly when testing large numbers of server nodes using EC2 i2.xlarge instances as we did!&lt;/p&gt;
&lt;p&gt;Earlier this morning we also sent out a &lt;a href=&#34;http://www.prnewswire.com/news-releases/apache-cassandra-leads-all-others-in-latest-nosql-benchmark-300064570.html&#34;&gt;press release to announce our results&lt;/a&gt; and the availability of the report.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; See our &lt;a href=&#34;/blog/2015/06/updated-nosql-benchmark-cassandra/&#34;&gt;note about updated test runs and revised report&lt;/a&gt; as of June 4, 2015.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>MongoDB and OpenStack — OSI Days 2014, India</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2014/11/mongodb-and-openstack-osi-days-2014/"/>
      <id>https://www.endpointdev.com/blog/2014/11/mongodb-and-openstack-osi-days-2014/</id>
      <published>2014-11-19T00:00:00+00:00</published>
      <author>
        <name>Selvakumar Arumugam</name>
      </author>
      <content type="html">
        &lt;p&gt;The 11th edition of Open Source India, 2014 was held at Bengaluru, India. The two day conference was filled with three parallel tech talks and workshops which was spread across various Open Source technologies.&lt;/p&gt;
&lt;img alt=&#34;IMG_20141110_223543.jpg&#34; height=&#34;440px;&#34; src=&#34;/blog/2014/11/mongodb-and-openstack-osi-days-2014/image-0.jpeg&#34; style=&#34;-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);&#34; width=&#34;624px;&#34;/&gt;
&lt;h3 id=&#34;in-depth-look-at-architecting-and-building-solutions-using-mongodb&#34;&gt;In-depth look at Architecting and Building solutions using MongoDB&lt;/h3&gt;
&lt;p&gt;Aveekshith Bushan &amp;amp; Ranga Sarvabhouman from MongoDB started off the session with a comparison of the hardware cost involved with storage systems in earlier and recent days. In earlier days, the cost of storage hardware was very expensive, so the approach was to filter the data to reduce the size before storing into the database. So we were able to generate results from filtered data and we didn’t have option to process the source data. After the storage became cheap, we can now store the raw data and then we do all our filter/processing and then distribute it.&lt;/p&gt;
&lt;p&gt;Earlier,&lt;/p&gt;
&lt;p&gt;        Filter -&amp;gt; Store -&amp;gt; Distribute&lt;/p&gt;
&lt;p&gt;Present,&lt;/p&gt;
&lt;p&gt;        Store -&amp;gt; Filter -&amp;gt; Distribute&lt;/p&gt;
&lt;p&gt;Here we are storing huge amount of data, so we need a processing system to handle and analyse the data in efficient manner. In current world, the data is growing like anything and 3Vs are phenomenal of growing (Big)Data. We need to handle the huge Volume of Variety of data in a Velocity. MongoDB follows certain things to satisfy the current requirement.&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;
  &lt;a href=&#34;/blog/2014/11/mongodb-and-openstack-osi-days-2014/image-1.png&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;
    &lt;img border=&#34;0&#34; height=&#34;152&#34; src=&#34;/blog/2014/11/mongodb-and-openstack-osi-days-2014/image-1.png&#34; width=&#34;400&#34; /&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;MongoDB simply stores the data as a document without any data type constraints which helps to store huge amount of data quickly. It leaves the constraints checks to the application level to increase the storage speed in database end. But it does recognises the data type after the data is stored as document. In simple words, the philosophy is: Why do we need to check the same things (datatype or other constraints) in two places (application and database)?&lt;/p&gt;
&lt;p&gt;MongoDB stores all relations as single document and fetches the data in single disk seek. By avoiding multiple disk seeks, this results in the fastest retrieval of data. Whereas in relational database the relations stored in different tables which leads to multiple disk seek to retrieve the complete data of an entity. And MongoDB doesn’t support joins but it have Reference option to refer another collection(Table) without imposing foreign key constraints.&lt;/p&gt;
&lt;p&gt;As per &lt;a href=&#34;https://db-engines.com/en/ranking&#34;&gt;db-engines&lt;/a&gt; rankings, MongoDB stays in the top of NoSQL database world. Also it provides certain key features which I have remembered from the session:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sub-documents duplicates the data but it helps to gain the performance(since the storage is cheap, the duplication doesn’t affect much)&lt;/li&gt;
&lt;li&gt;Auto-sharding (Scalability)&lt;/li&gt;
&lt;li&gt;Sharding helps parallel access to the system&lt;/li&gt;
&lt;li&gt;Range Based Sharding &lt;/li&gt;
&lt;li&gt;Replica Sets (High availability)&lt;/li&gt;
&lt;li&gt;Secondary indexes available&lt;/li&gt;
&lt;li&gt;Indexes are single tunable part of the MongoDB system &lt;/li&gt;
&lt;li&gt;Partition across systems &lt;/li&gt;
&lt;li&gt;Rolling upgrades&lt;/li&gt;
&lt;li&gt;Schema free&lt;/li&gt;
&lt;li&gt;Rich document based queries&lt;/li&gt;
&lt;li&gt;Read from secondary&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When do you need MongoDB?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The data grows beyond the system capacity in relational database&lt;/li&gt;
&lt;li&gt;In a need of performance in online requests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, speakers emphasized to understand use case clearly and choose right features of MongoDB to get effective performance.&lt;/p&gt;
&lt;h3 id=&#34;openstack-mini-conf&#34;&gt;OpenStack Mini Conf&lt;/h3&gt;
&lt;p&gt;A special half day OpenStack mini conference was organised at second half of first day. The talks were spread across basics to in depth of OpenStack project. I have summarised all the talks here to give an idea of OpenStack software platform.&lt;/p&gt;
&lt;p&gt;OpenStack is a Open Source cloud computing platform to provision the Infrastructure as a Service(IaaS). There is a wonderful project &lt;a href=&#34;https://docs.openstack.org/developer/devstack/&#34;&gt;DevStack&lt;/a&gt; out there to set up the OpenStack on development environment in easiest and fastest way. A well written &lt;a href=&#34;https://docs.openstack.org/&#34;&gt;documentation&lt;/a&gt; of the OpenStack project clearly explains everything. In addition, anyone can contribute to OpenStack with help of &lt;a href=&#34;https://wiki.openstack.org/wiki/How_To_Contribute&#34;&gt;How to contribute&lt;/a&gt; guide, also project uses Gerrit review system and Launchpad bug tracking system.&lt;/p&gt;
&lt;p&gt;OpenStack have multiple components to provide various features in Infrastructure as a Service. Here is the list of OpenStack components and the purpose of each one.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nova (Compute) — manages the pool of computer resources&lt;/li&gt;
&lt;li&gt;Cinder (Block Storage) — provides the storage volume to machines&lt;/li&gt;
&lt;li&gt;Neutron (Network) — manages the networks and IP addresses&lt;/li&gt;
&lt;li&gt;Swift (Object Storage) — provides distributed high availability(replication) on storage system.&lt;/li&gt;
&lt;li&gt;Glance (Image) — provides a repository to store disk and server images&lt;/li&gt;
&lt;li&gt;KeyStone (Identity) — enables the common authentication system across all components&lt;/li&gt;
&lt;li&gt;Horizon (Dashboard) — provides GUI for users to interact with OpenStack components&lt;/li&gt;
&lt;li&gt;Ceilometer (Telemetry) — provides the services usage and billing reports&lt;/li&gt;
&lt;li&gt;Ironic (Bare Metal) — provisions bare metal instead of virtual machines&lt;/li&gt;
&lt;li&gt;Sahara (Map Reduce) — provisions hadoop cluster for big data processing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OpenStack services are usually mapped to AWS services to better understand the purpose of the components. The following table depicts the mapping of similar services in OpenStack and AWS:&lt;/p&gt;
&lt;table style=&#34;border-collapse: collapse; border: none; width: 624px;&#34;&gt;&lt;colgroup&gt;&lt;col width=&#34;*&#34;/&gt;&lt;col width=&#34;*&#34;/&gt;&lt;/colgroup&gt;&lt;tbody&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 25px 7px 25px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt; text-align: center;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;OpenStack&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt; text-align: center;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;AWS&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Nova&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;EC2&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Cinder&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;EBS&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Neutron&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;VPC&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Swift&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;S3&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Glance&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;AMI&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;KeyStone&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;IAM&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Horizon&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;AWS Console&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Ceilometer&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Cloudwatch&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&#34;height: 0px;&#34;&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Sahara&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;td style=&#34;border-bottom: solid #ffffff 1px; border-left: solid #ffffff 1px; border-right: solid #ffffff 1px; border-top: solid #ffffff 1px; padding: 7px 7px 7px 7px; vertical-align: top;&#34;&gt;&lt;div dir=&#34;ltr&#34; style=&#34;line-height: 1; margin-bottom: 0pt; margin-top: 0pt;&#34;&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
&lt;span style=&#34;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&#34;&gt;Elastic Mapreduce&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Along with the overview of OpenStack architecture, there were couple of in-depth talks which are listed below with slides.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Neependra Khare from RedHat gave a presentation on using &lt;a href=&#34;https://github.com/nkhare/presetations/blob/master/osidays/osi_openstack_nova_docker.md&#34;&gt;Docker in OpenStack Nova&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Pushpesh Sharma presented a &lt;a href=&#34;http://pushpeshsharma.blogspot.in/2014/11/openstack-swift-vs-ceph-rgw-read.html&#34;&gt;comparison between storage component OpenStack Swift and Ceph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sridhar Rao presented about OpenStack and its role in Network Function Virtualisation (NFV) — &lt;a href=&#34;https://web.archive.org/web/20160527104510/https://dl.dropboxusercontent.com/u/1527696/OpenStack-NfV.pptx&#34;&gt;Slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That was a wonderful Day One of OSI 2014 which helped me to get better understanding of MongoDB and OpenStack.&lt;/p&gt;

      </content>
    </entry>
  
</feed>
