Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

30
Leveraging your Knowledge of ORM Knowledge of ORM Towards Performance- b d N SQL T h l based NoSQL T echnology By Robert Greene Versant Corporation U.S. Headquarters 255 Shoreline Dr Suite 450 Redwood City CA 94065 255 Shoreline Dr. Suite 450, Redwood City, CA 94065 www.versant.com | 650-232-2400 #NoSQLVersant

description

The popular open source benchmark Poleposition was introduced back in 2005 to demonstrate the performance advantages of using a NoSQL, pure object-based solution as compared to traditional relational mapping solutions (ORM) over RDBMS like MySQL, Postgres, etc. Recently, Poleposition has been expanded to introduce the elements of concurrency of execution and model complexity into Poleposition's core foundation circuits. The new circuits incorporate a number of NoSQL technologies which avoid the mapping overhead of breaking down the benchmark object model into relational tables and demonstrate substantial differences in performance and resource consumption. For the right kind of data models, the NoSQL technologies demonstrate order(s) of magnitude improvements in performance with demonstrateable reductions in CPU utilization and storage footprint for the RAW data. This presentation will review those findings and draw a point of reference for when model complexity and system concurrency should impact your technology selection process in favor of NoSQL solutions capable of dealing specifically with complex information models.

Transcript of Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Page 1: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Leveraging your Knowledge of ORMKnowledge of ORM Towards Performance-b d N SQL T h lbased NoSQL Technology

By Robert Greene

Versant Corporation U.S. Headquarters255 Shoreline Dr Suite 450 Redwood City CA 94065255 Shoreline Dr. Suite 450, Redwood City, CA 94065www.versant.com | 650-232-2400

#NoSQLVersant

Page 2: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

NoSQL at it’s CoreOverview SQ C

Pole-Position – Overview

About the Code

Overview

About the Code

Circuits Description

RDB JPA CodeRDB JPA Code

MongoDB Code

V t JPA C dVersant JPA Code

Results – Winners of the Race

Developer Challenge

#NoSQLVersant

Page 3: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

NoSQLNoSQLat its coreat its core

#NoSQLVersant

Page 4: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Traditional DBMS Scale ArchitectureINEFFICIENT

CPU destroyingMappingMapping

EXPENSIVERepetitive data

movement and JOINcalculation

#NoSQLVersant

Page 5: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

NoSQL at its CoreA Shift In Application Architecture

UNIFEDA li tiApplication 

driven schema

COMMODITY HWCOMMODITY HWHorizontal scale out, distribution and partitioning

• Google – Soft-Schema• IBM – Schema-Less

#NoSQLVersant

Page 6: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

A Shift is NeededA Shift is Needed► How Often do Relations Change?g

Blog : BlogEntry , Order : OrderItem , You : Friend

►R l ti R l Ch St R l l ti Th►Relations Rarely Change, Stop Recalculating Them

► Do you need ALL of your data in one place.► o you eed o you da a o e p ace

► You don’t. You can distribute it.

#NoSQLVersant

Page 7: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

M d V lMeasured ValueHow NoSQL performance

stacks up to Relational

#NoSQLVersant

Page 8: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

PolePositionPerformance Benchmark

► Established in 2003N SQL ORMNoSQL -vs- ORM

► Code Complexity CircuitsFl t Obj tFlat ObjectsGraphsInherited ObjectsCollectionsCollections

► Data OperationsCRUDCRUDConcurrency

► Scalability► Scalability

#NoSQLVersant

Page 9: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Contenders | Methodology► Contenders

ORMORMNoSQL

► MethodologyExternal RDB Experts, Internal NoSQL ExpertsOpen Source Benchmark Code for all contendersOpen Source Benchmark Code for all contenders

#NoSQLVersant

Page 10: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

About the CodeAbout the Code► ORMORM

Common Code Base

► Tested Database EnginesHibernate – MySQL / PostgresOpenJPA – MySQL / PostgresMongoDBVersant Object Database

#NoSQLVersant

Page 11: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Circuit StructureCircuit Structure► Simulate CRUD on embedded graph of different Classes.

Cl d l C l Ci it► Class model - Complex Circuit:

class Holder0 { String name;String _name; List <Holder0> _children;Holder0[] _array; } 

class Holder1 extends Holder0 { {int _i1; } 

class Holder2 extends Holder1 { int _i2 <indexed>; }     ...class HolderN

extends…..

#NoSQLVersant

Page 12: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Hibernate JPA CodeHibernate JPA Code► Write – Generates Holder’s to user spec depth

ComplexHolder cp = new ComplexHolder( );  em.makePersistent(cp);

► Read – Access root of graph and traversecp = em.find( ComplexHolder.class, id ); cp.getChildren().touch();

► QueryString query = "fromString query    from org.polepos.teams.hibernate.data.Holder2 where i2=" + currentInt;    Iterator it =  em.iterate(query); 

► Delete – Deletes Graph - cascading operationDelete Deletes Graph cascading operation

#NoSQLVersant

Page 13: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

ORM JPA Mapping

- <hibernate-mapping package="org.polepos.teams.hibernate.data" default-cascade="none" default-access="property" default-lazy="true" auto-import="true">- <class name="ComplexHolder0" table="tComplexHolderNew0" polymorphism="implicit" mutable="true" dynamic-update="false" dynamic-insert="false" select-before-update="false"

ti i ti l k " i ">

XML Mapping File for each Persistent Class ( 11ea Files )

optimistic-lock="version"><id name="id" column="fid" type="long" />

- <discriminator type="string" not-null="true" force="false" insert="true"><column name="DISCRIMINATOR" /> </discriminator><property name="name" column="fname" type="string" unique="false" optimistic-lock="true" lazy="false" generated="never" />

- <list name="children" access="field" cascade="all" inverse="false" mutable="true" optimistic-lock="true" embed-xml="true"><key column="parentId" on-delete="noaction" /> <i d l " l tI d " /><index column="elementIndex" /> <many-to-many class="ComplexHolder0" embed-xml="true" not-found="exception" unique="false" /> </list>

- <array name="array" access="field" cascade="all" inverse="false" mutable="true" optimistic-lock="true" embed-xml="true"><key column="parentId" on-delete="noaction" /> <index column="elementIndex" /> <many-to-many class="ComplexHolder0" embed-xml="true" not-found="exception" unique="false" /> </array><subclass name="ComplexHolder1" discriminator value="D" dynamic update="false" dynamic insert="false" select before update="false">- <subclass name="ComplexHolder1" discriminator-value="D" dynamic-update="false" dynamic-insert="false" select-before-update="false"><property name="i1" column="i1" type="int" unique="false" optimistic-lock="true" lazy="false" generated="never" />

- <subclass name="ComplexHolder2" discriminator-value="E" dynamic-update="false" dynamic-insert="false" select-before-update="false"><property name="i2" column="i2" type="int" index="i2_idx" unique="false" optimistic-lock="true" lazy="false" generated="never" />

- <subclass name="ComplexHolder3" discriminator-value="F" dynamic-update="false" dynamic-insert="false" select-before-update="false"><property name="i3" column="i3" type="int" unique="false" optimistic-lock="true" lazy="false" generated="never" />

- <subclass name="ComplexHolder4" discriminator-value="G" dynamic-update="false" dynamic-insert="false" select-before-update="false"><property name="i4" column="i4" type="int" unique="false" optimistic-lock="true" lazy="false" generated="never" /> </subclass></subclass></subclass></subclass></subclass></class></hibernate-mapping>

#NoSQLVersant

Page 14: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

MongoDB Codeprivate void storeData(Mongo mongo) {

collection(mongo).insert(new BasicDBObject("test", "object"));}}

public ComplexHolder0 convertFromDocument(DBObject data, DeserializationOptionsdeserializationOption) {

ComplexHolder0 instance = createInstance(getAsString(data, TYPE_ATTRIBUTE));instance.setName(getAsString(data, NAME_ATTRIBUTE));if ( ll ! d t t(CHILDREN)) {if (null != data.get(CHILDREN)) {

instance.setChildren(fromMongoObjectToList(getAsList(data, CHILDREN), deserializationOption));

}if (null != data.get(ARRAY)) {

final List<ComplexHolder0> arrayContent = fromMongoObjectToList(getAsList(data, p y g j (g ( ,ARRAY), deserializationOption);

instance.setArray(arrayContent.toArray(new ComplexHolder0[arrayContent.size()]));}readAttributes(data, instance);return instance;

}} 

#NoSQLVersant

Page 15: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

MongoDB Mappingprivate static void writeSubTypeAttributes(ComplexHolder0 holder, 

BasicDBObject dataStorage) {if (h ld i t f l ld ) {if (holder instanceof ComplexHolder1) {

dataStorage.put(FIELD_I1, ((ComplexHolder1) holder)._i1);}if (holder instanceof ComplexHolder2) {

d t St t(FIELD I2 ((C l H ld 2) h ld ) i2)dataStorage.put(FIELD_I2, ((ComplexHolder2) holder)._i2);}

private static void readAttributes(DBObject dataStorage, ComplexHolder0 holder) {holder) {

if (holder instanceof ComplexHolder1) {((ComplexHolder1) holder)._i1 = (Integer) 

dataStorage.get(FIELD_I1);}}if (holder instanceof ComplexHolder2) {

((ComplexHolder2) holder)._i2 = (Integer) dataStorage.get(FIELD_I2);

}}

#NoSQLVersant

Page 16: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

g _Holder0.class.getPackage().getName();nal String NAME_ATTRIBUTE = "name";nal String CHILDREN = "children";nal String ARRAY = "array";nal String REFERENCE_TO_ORIGINAL_DOCUMENT = "_refToOriginal";nal String FIELD_I1 = "_i1";nal String FIELD_I2 = "_i2";nal String FIELD_I3 = "_i3"; MongoDB Mappingnal String FIELD_I4 = "_i4";

inal OneArgFunction<BasicDBObject, DBRef> refCreator;

tion(OneArgFunction<BasicDBObject, DBRef> refCreator) {refCreator = refCreator;

MongoDB Mapping

atic Serialisation create(OneArgFunction<BasicDBObject, DBRef> tor) {ull == refCreator) {hrow new ArgumentNullException("requires a reference creator");

n new Serialisation(refCreator);

atic OneArgFunction<BasicDBObject, DBRef> eferenceCreator(final DBCollection collection) {ull == collection) {hrow new ArgumentNullException("requires a collection");

n new OneArgFunction<BasicDBObject, DBRef>() {OverrideOverrideublic DBRef invoke(BasicDBObject basicDBObject) {

final DB db = collection.getDB();final Object id = basicDBObject.get("_id");if (null == id) {

throw new IllegalStateException("Expected an '_id' on the );

}return new DBRef(db, collection.getName(), id);( , g (), );

#NoSQLVersant

Page 17: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Versant JPA Code

► Write – Generates Holder’s to user spec depthp pComplexHolder cp = new ComplexHolder( );  em.makePersistent(cp);

► Read – Access root of graph and traverse► Read – Access root of graph and traversecp = em.find( ComplexHolder.class, id );   cp.getChildren().touch();

Q► QueryString query = "from org.polepos.teams.versant.data.Holder2 where i2=" + currentInt;    Iterator it = 

i i ( )session.iterate(query); 

► Delete – Deletes Graph – Cascading Operation

#NoSQLVersant

Page 18: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Versant JPA MappingSingle XML File with primitive declaration entries

<class name="ComplexHolder0"><field name="name" /><field name name  /><field name="array" />

<field name="children"><collection element‐

type="ComplexHolder0"/> </field></class>

#NoSQLVersant

Page 19: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Sh@t’s and Grins

► JDBC Code

JDBC StringBuilder sb = new StringBuilder(); sb.append("select " + HOLDER_TABLE0 + ".id from " + HOLDER_TABLE0); sb.append(" INNER JOIN " + HOLDER_TABLES[0]); sb.append(" on " + HOLDER_TABLE0 + ".id = " + HOLDER TABLES[0] + ".id "); sb.append(" INNER JOIN ".id     + HOLDER_TABLES[0] +  .id  ); sb.append(  INNER JOIN   + HOLDER_TABLES[1]); sb.append(" on " + HOLDER_TABLE0 + ".id = " + HOLDER_TABLES[1] + ".id "); sb.append(" LEFT OUTER JOIN " + HOLDER_TABLES[2]); sb.append(" on " + HOLDER_TABLE0 + ".id = " + HOLDER_TABLES[2] + ".id "); sb.append(" LEFT OUTER JOIN " + HOLDER TABLES[3]); sb.append(" on " + HOLDER TABLE0 + ".id = " +HOLDER_TABLES[3]); sb.append(  on   + HOLDER_TABLE0 +  .id     + HOLDER_TABLES[3] + ".id "); sb.append(" where " + HOLDER_TABLES[1] + ".i2 = ?"); PreparedStatement stat = prepareStatement(sb.toString()); ResultSet resultSetstat.executeQuery(); 

#NoSQLVersant

Page 20: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

PolePositionBenchmark Summary Results

#NoSQLVersant

Page 21: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

FlatObject - Single Thread

#NoSQLVersant

Page 22: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Results – ComplexConcurrency@mongo - no safe mode@mongo no safe mode

#NoSQLVersant

Page 23: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Results – QueryConcurrency@mongo – no safe mode@mongo no safe mode

#NoSQLVersant

Page 24: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Results – InsertConcurrent@mongo – no safe mode@mongo no safe mode

#NoSQLVersant

Page 25: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Results – ComplexConcurrency@mongo – safe mode@mongo safe mode

#NoSQLVersant

Page 26: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Results – QueryConcurrency@mongo – safe mode@mongo safe mode

#NoSQLVersant

Page 27: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Results – InsertConcurrent@mongo – safe mode@mongo safe mode

#NoSQLVersant

Page 28: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

ConclusionsConclusions► Wake-up, smell the coffeep,

JOINs are not needed - unless adhoc analytics► Take care of business, dump a load of code

Serialization is bad, data useful once structuredMapping is Mapping, even when it’s not an ORM

Get on your Bad Motor Scooter and Ride► Get on your Bad Motor Scooter and RideNoSQL without Mapping rules the road

Get the Code: http://www.polepos.org

#NoSQLVersant

Page 29: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

Q&AQ&A

#NoSQLVersant

Page 30: Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology

ContactContact

Robert GreeneRobert GreeneVice President, Technology

@ [email protected]

SQ #NoSQL Now! – Booth #14

#NoSQLVersant