Leveraging your Knowledge of ORM Towards Performance-based NoSQL Technology
-
Upload
dataversity -
Category
Technology
-
view
399 -
download
2
description
Transcript of 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
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
NoSQLNoSQLat its coreat its core
#NoSQLVersant
Traditional DBMS Scale ArchitectureINEFFICIENT
CPU destroyingMappingMapping
EXPENSIVERepetitive data
movement and JOINcalculation
#NoSQLVersant
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
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
M d V lMeasured ValueHow NoSQL performance
stacks up to Relational
#NoSQLVersant
PolePositionPerformance Benchmark
► Established in 2003N SQL ORMNoSQL -vs- ORM
► Code Complexity CircuitsFl t Obj tFlat ObjectsGraphsInherited ObjectsCollectionsCollections
► Data OperationsCRUDCRUDConcurrency
► Scalability► Scalability
#NoSQLVersant
Contenders | Methodology► Contenders
ORMORMNoSQL
► MethodologyExternal RDB Experts, Internal NoSQL ExpertsOpen Source Benchmark Code for all contendersOpen Source Benchmark Code for all contenders
#NoSQLVersant
About the CodeAbout the Code► ORMORM
Common Code Base
► Tested Database EnginesHibernate – MySQL / PostgresOpenJPA – MySQL / PostgresMongoDBVersant Object Database
#NoSQLVersant
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
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
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
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
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
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
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
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
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
PolePositionBenchmark Summary Results
#NoSQLVersant
FlatObject - Single Thread
#NoSQLVersant
Results – ComplexConcurrency@mongo - no safe mode@mongo no safe mode
#NoSQLVersant
Results – QueryConcurrency@mongo – no safe mode@mongo no safe mode
#NoSQLVersant
Results – InsertConcurrent@mongo – no safe mode@mongo no safe mode
#NoSQLVersant
Results – ComplexConcurrency@mongo – safe mode@mongo safe mode
#NoSQLVersant
Results – QueryConcurrency@mongo – safe mode@mongo safe mode
#NoSQLVersant
Results – InsertConcurrent@mongo – safe mode@mongo safe mode
#NoSQLVersant
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
Q&AQ&A
#NoSQLVersant
ContactContact
Robert GreeneRobert GreeneVice President, Technology
SQ #NoSQL Now! – Booth #14
#NoSQLVersant