Wednesday, September 07, 2011

Why NoSQL is in fashion?

Couple of years back NoSQL was relatively unheard term. It has become a new buzzword in town, catching people's imagination. Almost all big daddies of Internet (Google, Facebook, Yahoo, Twitter, Amazon, Linked-in etc.) are using NoSQL at massive scale and many of them have their own NoSQL products. Every month there is a launch of new NoSQL product catering to some specific use cases / requirements. So what are the reasons behind NoSQL's rise to popularity?

Background

RDBMS and SQL has ruled the world for last 3 decades. They were (are) the defacto standard for storing business data. In fact there was no alternative to RDBMS and SQL combination. When RDBMS were developed the disk space was scarce, hence a lot of thought has gone around saving precious disk space. Development in hardware technologies have made available literally unlimited storage space at lower prices. Evolution of Internet in last decade has paved way for altogether different kind of applications and use cases, which were never thought earlier. Web2 applications (say social networking) have entirely different requirements than typical enterprise applications. Other than that Internet has changed the way application developers think about the data and its usage & storage.

Requirement

Nowadays enormous amount of data is being produced everyday and the rate at which data is produced is also increasing. Data size is so huge that organizations spread it across data center as it does not fit in a single rack or data center. Though data availability is also an equally important factor in using multiple data centers for storage. Applications have to available 24x7 no matter what. Data has to survive the data center failure as well, forget about failure of a disk. Instead of archiving data, Facebook type of applications keep it online forever.

Social networking sites are coming up with new features quite frequently and sometimes rolling back them. At times their new features were never thought about earlier. They don't want to be confined by the schema constraints of RDBMS which is quite difficult (though not impossible) to change. Support for evolving schema has become a necessity and NoSQL solutions are a right fit there instead of RDBMS.

Data size, flexible schema and availability are the 3 key factors where traditional RDBMS do not perform well after a certain limit.

Thought Process

Web2 applications has changed how people think about application architecture. It is an altogether different thought process then what it was few years back.

While designing an enterprise application we used to think about "how to store the data" but today the primary thought is "how we will use the data". This is a paradigm shift. Data storage is designed based on how that is going to be used, leading to optimized performance for a given requirement at times at the cost of flexibility.

"Referencing" entities was a wonderful feature in RDBMS but for large scale web 2 application that does not matter at all. For them instead of referencing "embedding" is the killer feature. Storing related data (say personal detail and address) together makes sense as they don't have any meaning independently. This is similar to denormalization in RDBMS.

For many features of web 2 applications ACID transactions are also not a primary requirement. Say if a tweet does not gets published many users won't mind to type that again and hit the enter button as long as that does not happen frequently. If avoiding ACID transactions increases the throughput many fold for not so critical features, what else you want :-). It is similar to old MySQL though with much larger data-set than what MySQL can support.

Conclusion

There are several use cases where NoSQL perform much better and it makes perfect sense to use NoSQL instead of trying to scale the RDBMS by using expensive methods. RDBMS’s are really good at doing what they do, which is storing flat, relational, tabular data in a consistent manner and getting wonderful reports out of that data. They still remain the best solution for storing relational data.While NoSQL databases are good at performance, availability, schema-less persistent etc., which has become a basic requirement for today's applications. Support for these features is the main reason for meteoric rise to fame of the NoSQL.

Thursday, April 21, 2011

Blessed with a baby girl

It has been an year since I blogged last time. last one year was very hectic for me both at workplace and home. There was tons of workload at office at times eating into weekends. We were expecting a baby, so I have to take additional responsibilities at home as well. In December we were blessed with a gorgeous baby girl. That was the most fulfilling moment of our life. It has become an everyday celebration for our son. For quite long time he was dreaming of having a brother or sister.



Next month I will be joining a new workplace, which is closer to my home. That will spare some precious time to spare with family.

Hopefully I will be back to blogging soon.

Monday, April 12, 2010

JAX-WS Web service with Maven

One of my earlier post Building JAX-WS Webservice was using Ant as build tool for developing web services. With each passing day Maven is gaining more popularity and became preferred build tool for many developers. I used to get emails from several readers about working JAX-WS examples with Maven as build tool. In this post I will try to demonstrate to publish and consume a JAX-WS web service using Maven.

The source code used in this post is available here, which will be referred at several places in this post.

The jaxws-maven-plugin has two goals wsgen and wsimport.

  • wsgen - This reads a service endpoint implementation class and generates all of the portable artifacts for a JAX-WS web service. With newer versions (tested with 2.2) of JAX-WS, execution of this task is not required for publishing webservice
  • wsimport - This tool reads WSDL and generates client side artifacts. We will be using this goal for generating client and consuming a web service.

Publish Web service

For publishing a web service we need to write an interface and its implementation then annotate them with relevant annotations. The JAX-WS libraries should be added as dependency in pom.xml. A sample (partial) build script is shown below-

<dependencies>
    <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <scope>compile</scope>
        <version>2.2</version>
    </dependency>
</dependencies>
. . .
<build>
    <plugins>
        <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>maven-jetty-plugin</artifactId>
            <configuration>
                <scanIntervalSeconds>10</scanIntervalSeconds>
                <connectors>
                    <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                        <port>8080</port>
                        <maxIdleTime>60000</maxIdleTime>
                    </connector>
                </connectors>
            </configuration>
        </plugin>
    </plugins>
</build>

We can see in the above Maven script that the wsgen is not required. The JAX-WS implementation will take care of that at runtime. To make testing easier I have used Jetty plugin, which will publish the web service for further consumption by the client in next step. To publish the web service invoke following command in 'webservice' directory of the source code of this post-
mvn -e clean compile jetty:run

Create Client

For creating web service client the wsimport goal of jaxws-maven-plugin will be used. The wsimport goal creates portable client artifacts by parsing a WSDL. In this example the WSDL URL is the one which was published by starting the web service at previous step. The pom.xml of client side application will look like below-

<dependencies>
    <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <scope>compile</scope>
        <version>2.2</version>
    </dependency>
</dependencies>
. . .
<build>
    <plugins>
        <!-- Generate client using WSDL -->
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxws-maven-plugin</artifactId>
            <configuration>
                <packageName>wsclient</packageName>
                <wsdlUrls>
                    <wsdlUrl>http://localhost:8080/webservice/myService?wsdl</wsdlUrl>
                </wsdlUrls>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>java</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>client.WsClient</mainClass>
            </configuration>
        </plugin>
    </plubins>
</build>

For the sake of simplicity I have used exec-maven-plugin here, which will run the test class to invoke the web service from build script itself. To generate client and run the test class, trigger the build from 'webservice-client' directorty using following command-
mvn -e clean compile exec:java


The examples shown above were tested with following configuration-
  • Java 1.6.18
  • JAX-WS 2.
  • Maven 2.2.1
  • Windows XP

Note:- If JAX-WS 2.2 is used with older versions of Java 6 (e.g. Java 1.6.03) then you may encounter errors like shown below-
SEVERE: WSSERVLET11: failed to parse runtime descriptor: java.lang.LinkageError: JAXB 2.1 API is being loaded from the bootstrap classloader, but this RI (from jar:file:/C:/Documents%20and%20Settings/Vinod%20Singh/.m2/repository/com/sun/xml/bind/jaxb-impl/2.2/jaxb-impl-2.2.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.2 API. Use the endorsed directory mechanism to place jaxb-api.jar in the bootstrap classloader. (See http://java.sun.com/j2se/1.6.0/docs/guide/standards/)
java.lang.LinkageError: JAXB 2.1 API is being loaded from the bootstrap classloader, but this RI (from jar:file:/C:/Documents%20and%20Settings/Vinod%20Singh/.m2/repository/com/sun/xml/bind/jaxb-impl/2.2/jaxb-impl-2.2.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.2 API. Use the endorsed directory mechanism to place jaxb-api.jar in the bootstrap classloader. (See http://java.sun.com/j2se/1.6.0/docs/guide/standards/) at com.sun.xml.bind.v2.model.impl.ModelBuilder.(ModelBuilder.java:173)

The reason of these errors is that the earlier versions of Java 6 are using lower versions of JAX-WS while we are trying to use higher version of JAX-WS. To overcome these errors either we need to downgrade the JAX-WS version in our runtime environment or use endorsed directory mechanism.

Hope this will be useful to some of the readers.