SlideShare uma empresa Scribd logo
1 de 85
Baixar para ler offline
SQL, NoSQL, NewSQL?
What's a developer to do?
Chris Richardson

Author of POJOs in Action
Founder of the original CloudFoundry.com

chris.richardson@springsource.com
    @crichardson
Blog: http://plainoldobjects.com




                      Copyright (c) 2012 Chris Richardson. All rights reserved.
Overall presentation goal


 The joy and pain of
    building Java
 applications that use
 NoSQL and NewSQL
       2
About Chris




        3
(About Chris)




        4
About Chris()




        5
About Chris




        6
About Chris




        http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/




        7
About Chris


   Developer Advocate for
     CloudFoundry.com




                            8
Agenda
  Why NoSQL? NewSQL?
  Persisting entities
  Implementing queries




                          Slide 9
Food to Go

  Take-out food delivery
   service
  “Launched” in 2006
  Used a relational
   database (naturally)




         10
Success  Growth challenges
  Increasing traffic
  Increasing data volume
  Distribute across a few data centers
  Increasing domain model complexity
Limitations of relational databases

  Scaling
  Distribution
  Updating schema
  O/R impedance mismatch
  Handling semi-structured data




                                      12
Solution: Spend Money
                                                                              Buy SSD and RAM
                                                                              Buy Oracle
                                                                              Buy high-end servers
                                                                              …


                                                                          OR
http://upload.wikimedia.org/wikipedia/commons/e/e5/Rising_Sun_Yacht.JPG




     Hire more DevOps
     Use application-level sharding
     Build your own middleware
     …

                                  http://www.trekbikes.com/us/en/bikes/road/race_performance/madone_5_series/madone_5_2/#


                             13
Solution: Use NoSQL
 Benefits




                 Higher               Limited
                 performance          transactions
                 Higher scalability   Relaxed
                 Richer data-         consistency
                 model                Unconstrained
                                      data




                                                      Drawbacks
                 Schema-less




            14
MongoDB




          Slide 15
MongoDB is a document oriented DB
                                                       Server
                                  Database: Food To Go
                             Collection: Restaurants
    {
        "_id" : ObjectId("4bddc2f49d1505567c6220a0")
        "name": "Ajanta",
        "serviceArea": ["94619", "99999"],                      BSON =
        "openingHours": [
           {
                                                                binary
              "dayOfWeek": 1,                                   JSON
             "open": 1130,
             "close": 1430 },
           {                                                    Sequence
               "dayOfWeek": 2,
               "open": 1130,
                                                                of bytes on
               "close": 1430                                    disk  fast
            }, …
         ]
                                                                i/o
    }




                                                                     16
MongoDB – writes are fast

  Client                                   MongoDB


           Insert(collection, documents)


           Insert(collection, documents)
                                                     Async


           Insert(collection, documents)



           getLastError()                       Blocks until
                                                writes
                                                succeed

                                                     Slide 17
MongoDB is scalable
                         Shard 1                             Shard 2
          Mongod                              Mongod
          (replica)                           (replica)

    Mongod                              Mongod
   (master)           Mongod           (master)           Mongod
                      (replica)                           (replica)


Config
Server

mongod
                                                             A shard consists of a
                             mongos                          replica set =
                                                             generalization of
                                                             master slave
mongod


mongod                                                     Collections spread
                                                             over multiple
                              client                             shards



          4/11/12                                                        Slide 18
MongoDB use cases
  Use cases
    High volume writes
    Complex data
    Semi-structured data
  Used by: Shutterfly, Foursquare, Bit.ly, …




                                           Slide 19
Apache Cassandra




                   20
Cassandra is a column-oriented DB
           Column           Column
   Row                       Value
            Name                     Timestamp
   Key

                                                                    Keyspace
                                                            Column Family

     K1      N1        V1     TS1    N2   V2     TS2   N3    V3   TS3




     K2      N1        V1     TS1    N2   V2     TS2   N3    V3   TS3




Column name/value: number, string, Boolean, timestamp, and composite

                  21
Cassandra– inserting/updating data
                                                                   Column Family

        K1    N1   V1   TS1   N2   V2   TS2   N3   V3   TS3




    …



Idempotent= transaction                 CF.insert(key=K1, (N4, V4, TS4), …)


                                                                   Column Family

        K1    N1   V1   TS1   N2   V2   TS2   N3   V3   TS3   N4   V4   TS4




    …

                   22
Cassandra– retrieving data
                                                              Column Family

    K1   N1   V1   TS1   N2   V2   TS2   N3   V3   TS3   N4   V4   TS4




…


                    CF.slice(key=K1, startColumn=N2, endColumn=N4)



 K1                      N2   V2   TS2   N3   V3   TS3   N4   V4   TS4




              23
Tunable reads and writes
                           Higher availability
                           Lower response time
                           Less consistency
  Any node (for writes)
  One replica
  Quorum of replicas
  Local quorum
  Each quorum
  All replicas
                            Lower availability
                            Higher response time
                            More consistency

                                             Slide 24
Cassandra is scalable
           Application                    Application




             Node 1                         Node 1



  Node 4              Node 2     Node 4              Node 2



             Node 3                         Node 3

 Cassandra cluster              Cassandra cluster
Datacenter 1                   Datacenter 2

                                                        Slide 25
Cassandra use cases
  Use cases
    Big data
    Multiple Data Center distributed
     database
    (Write intensive) Logging
    High-availability (writes)
  Used by: Netflix, Facebook, Digg, etc.




                                        Slide 26
Other NoSQL databases
Type                                   Examples


Extensible columns/Column-             Hbase
oriented                               SimpleDB
                                       DynamoDB

Graph                                  Neo4j


Key-value                              Redis
                                       Membase

Document                               CouchDb


            http://nosql-database.org/ lists 122+ NoSQL databases

                  27
Solution: Use NewSQL
  Relational databases with SQL and
   ACID transactions
                   AND
  New and improved architecture
  Radically better scalability and
   performance

  NewSQL vendors: ScaleDB,
   NimbusDB, …, VoltDB
                                       Slide 28
Stonebraker’s motivations

                   “…Current databases are designed for
                           1970s hardware …”

                    Stonebraker: http://www.slideshare.net/VoltDB/sql-myths-webinar




  Significant overhead in “…logging, latching,
   locking, B-tree, and buffer management
                  operations…”
  SIGMOD 08: Though the looking glass: http://dl.acm.org/citation.cfm?id=1376713




                                                                                      29
About VoltDB
  Open-source
  In-memory relational database
  Durability thru replication; snapshots
   and logging
  Transparent partitioning
  Fast and scalable
     …VoltDB is very scalable; it should scale to 120
      partitions, 39 servers, and 1.6 million complex
     transactions per second at over 300 CPU cores…
      http://www.mysqlperformanceblog.com/2011/02/28/is-voltdb-really-as-scalable-as-they-claim/




                                                                                                   Slide 30
The future is polyglot persistence




                                                                           e.g. Netflix
                                                                           •  RDBMS
                                                                           •  SimpleDB
                                                                           •  Cassandra
                                                                           •  Hadoop/Hbase




   IEEE Software Sept/October 2010 - Debasish Ghosh / Twitter @debasishg


                           31
Spring Data is here to help




                                  For


                     NoSQL databases

http://www.springsource.org/spring-data



                32
Agenda
  Why NoSQL? NewSQL?
  Persisting entities
  Implementing queries




                          Slide 33
Food to Go – Place Order use case

1.  Customer enters delivery address and
    delivery time
2.  System displays available restaurants
3.  Customer picks restaurant
4.  System displays menu
5.  Customer selects menu items
6.  Customer places order



           34
Food to Go – Domain model (partial)


class Restaurant {               class TimeRange {
  long id;                         long id;
  String name;                     int dayOfWeek;
  Set<String> serviceArea;         int openingTime;
  Set<TimeRange> openingHours;
                                   int closingTime;
  List<MenuItem> menuItems;
                                 }
}


                                 class MenuItem {
                                   String name;
                                   double price;
                                 }




                35
Database schema
ID                   Name                  …
                                                         RESTAURANT
1                    Ajanta
                                                         table
2                    Montclair Eggshop

Restaurant_id            zipcode
                                                RESTAURANT_ZIPCODE
1                        94707
                                                table
1                        94619
2                        94611
2                        94619                 RESTAURANT_TIME_RANGE
                                               table

Restaurant_id   dayOfWeek           openTime     closeTime
1               Monday              1130         1430
1               Monday              1730         2130
2               Tuesday             1130         …


                36
Pick your JDBC-based framework
        interface AvailableRestaurantRepository {

            void add(Restaurant restaurant);
            Restaurant findDetailsById(int id);
            …
        }




  Spring JDBC            Hibernate/JPA              …



                              JDBC




              37
But with NoSQL?
                                 interface AvailableRestaurantRepository {
          Restaurant
                                     void add(Restaurant restaurant);
                                     Restaurant findDetailsById(int id);
                                     …
   TimeRange          MenuItem   }

Restaurant aggregate




             ?                                          ?
                 38
MongoDB




          Slide 39
MongoDB: persisting restaurants is easy


      {
          "_id" : ObjectId("4bddc2f49d1505567c6220a0")
          "name": "Ajanta",
          "serviceArea": ["94619", "99999"],
          "openingHours": [
             {
                "dayOfWeek": 1,
               "open": 1130,
               "close": 1430 },
             {
                 "dayOfWeek": 2,
                 "open": 1130,
                 "close": 1430
              }, …
           ]
      }




             40
Spring Data for Mongo code
@Repository
public class AvailableRestaurantRepositoryMongoDbImpl
          implements AvailableRestaurantRepository {

 public static String AVAILABLE_RESTAURANTS_COLLECTION = "availableRestaurants";

 @Autowired
 private MongoTemplate mongoTemplate;

 @Override
 public void add(Restaurant restaurant) {
   mongoTemplate.insert(restaurant, AVAILABLE_RESTAURANTS_COLLECTION);
 }

 @Override
  public Restaurant findDetailsById(int id) {
     return mongoTemplate.findOne(new Query(where("_id").is(id)),
                                   Restaurant.class,
                                   AVAILABLE_RESTAURANTS_COLLECTION);
  }
}

                     41
Spring Configuration
@Configuration
public class MongoConfig extends AbstractDatabaseConfig {

 @Value("#{mongoDbProperties.databaseName}")
 private String mongoDbDatabase;

@Bean
public Mongo mongo() throws UnknownHostException, MongoException {
  return new Mongo(databaseHostName);
}

 @Bean
 public MongoTemplate mongoTemplate(Mongo mongo) throws Exception {
    MongoTemplate mongoTemplate = new MongoTemplate(mongo, mongoDbDatabase);
    …
    return mongoTemplate;
  }
}




                      42
Apache Cassandra




                   43
Option #1: Use a column per attribute

       Column Name = path/expression to access property value

                                                         Column Family: RestaurantDetails

                                                              openingHours[0].dayOfWeek     Monday
       name   Ajanta           serviceArea[0]    94619

1                                                                openingHours[0].open      1130
               type    indian        serviceArea[1]   94707

                                                                 openingHours[0].close     1430




              Egg                                             openingHours[0].dayOfWeek    Monday
       name                     serviceArea[0]   94611
              shop

2                      Break                                     openingHours[0].open      0830
               type                  serviceArea[1]   94619
                        Fast

                                                               openingHours[0].close      1430
Option #2: Use a single column
         Column value = serialized object graph, e.g. JSON


                                                     Column Family: RestaurantDetails
            2          attributes: { name: “Montclair Eggshop”, … }
     1          attributes     { name: “Ajanta”, …}




     2          attributes     { name: “Eggshop”, …}




Can’t use secondary indexes but they aren’t
        helpful for these use cases                                   ✔
                  45
Cassandra code: wrapper around Hector

public class AvailableRestaurantRepositoryCassandraKeyImpl
          implements AvailableRestaurantRepository {

@Autowired                                                    Home grown
private final CassandraTemplate cassandraTemplate;
                                                              wrapper class
public void add(Restaurant restaurant) {
  cassandraTemplate.insertEntity(keyspace,
                                 RESTAURANT_DETAILS_CF,
                                 restaurant);
}

public Restaurant findDetailsById(int id) {
  String key = Integer.toString(id);
  return cassandraTemplate.findEntity(Restaurant.class,
         keyspace, key, RESTAURANT_DETAILS_CF);
  …
}

…                                                            http://en.wikipedia.org/wiki/Hector

                  46
Slide 47
Using VoltDB
  Use the original schema
  Standard SQL statements

             BUT YOU MUST


  Write stored procedures and invoke
   them using proprietary interface
  Partition your data


                                    Slide 48
About VoltDB stored procedures
  Key part of VoltDB
  Replication = executing stored
   procedure on replica
  Logging = log stored procedure
   invocation
  Stored procedure invocation =
   transaction



                                    Slide 49
About partitioning
 Partition column

                                           RESTAURANT table

 ID                              Name                        …
 1                               Ajanta
 2                               Eggshop
 …



      Partition 1
                                              Partition 2


        ID          Name     …                  ID          Name      …
        1           Ajanta                      2           Eggshop
        …                                       …




                                                                          Slide 50
Example VoltDB cluster
    (3 servers) x (2 partitions per server)
                       ÷                                         3 partitions
           (2 replicas per partition)

 Partition 1a                      Partition 2a                                 Partition 3a



   ID           Name     …           ID           Name       …                    ID           Name     …
   1            Ajanta               2            Eggshop                         …            ..
   …                                 …                                            …



 Partition 3b                      Partition 1b                                 Partition 2b



   ID           Name     …          ID        Name       …                       ID        Name          …
   …            ..                  1         Ajanta                             2         Eggshop
   …                                …                                            …



VoltDB Server A                  VoltDB Server B                            VoltDB Server C


                                                                                                    Slide 51
Single partition procedure: FAST
     SELECT * FROM RESTAURANT WHERE ID = 1


High-performance lock free code                             Stored
                                         Partition
                                                            procedure
                                         column
                                                            parameter


     ID   Name     …         ID   Name      …          ID     Name         …
     1    Ajanta             1    Eggshop              …      ..
     …                       …                         …




           …                       …                               …


  VoltDB Server A         VoltDB Server B            VoltDB Server C

                                                                       Slide 52
Multi-partition procedure: SLOWER
   SELECT * FROM RESTAURANT WHERE NAME = ‘Ajanta’


                    Communication/Coordination overhead


  ID   Name     …              ID   Name      …       ID   Name         …
  1    Ajanta                  1    Eggshop           …    ..
  …                            …                      …




        …                            …                          …



VoltDB Server A             VoltDB Server B        VoltDB Server C


                                                                    Slide 53
Chosen partitioning scheme

<partitions>
   <partition   table="restaurant" column="id"/>
   <partition   table="service_area" column="restaurant_id"/>
   <partition   table="menu_item" column="restaurant_id"/>
   <partition   table="time_range" column="restaurant_id"/>
   <partition   table="available_time_range" column="restaurant_id"/>
</partitions>




  Performance is excellent: much
  faster than MySQL

                   54
Stored procedure – AddRestaurant
@ProcInfo( singlePartition = true, partitionInfo = "Restaurant.id: 0”)
public class AddRestaurant extends VoltProcedure {
    public final SQLStmt insertRestaurant =
              new SQLStmt("INSERT INTO Restaurant VALUES (?,?);");
    public final SQLStmt insertServiceArea =
              new SQLStmt("INSERT INTO service_area VALUES (?,?);");
    public final SQLStmt insertOpeningTimes =
              new SQLStmt("INSERT INTO time_range VALUES (?,?,?,?);");
    public final SQLStmt insertMenuItem =
              new SQLStmt("INSERT INTO menu_item VALUES (?,?,?);");
public long run(int id, String name, String[] serviceArea, long[] daysOfWeek, long[] openingTimes,
                                 long[] closingTimes, String[] names, double[] prices) {
    voltQueueSQL(insertRestaurant, id, name);
    for (String zipCode : serviceArea)
      voltQueueSQL(insertServiceArea, id, zipCode);
    for (int i = 0; i < daysOfWeek.length ; i++)
      voltQueueSQL(insertOpeningTimes, id, daysOfWeek[i], openingTimes[i], closingTimes[i]);
    for (int i = 0; i < names.length ; i++)
      voltQueueSQL(insertMenuItem, id, names[i], prices[i]);
    voltExecuteSQL(true);
     return 0;
    }
}
                            55
VoltDb repository – add()
@Repository
public class AvailableRestaurantRepositoryVoltdbImpl
           implements AvailableRestaurantRepository {

    @Autowired
    private VoltDbTemplate voltDbTemplate;

    @Override
    public void add(Restaurant restaurant) {
      invokeRestaurantProcedure("AddRestaurant", restaurant);
    }

    private void invokeRestaurantProcedure(String procedureName, Restaurant restaurant) {
     Object[] serviceArea = restaurant.getServiceArea().toArray();
     long[][] openingHours = toArray(restaurant.getOpeningHours());            Flatten
     Object[][] menuItems = toArray(restaurant.getMenuItems());
                                                                             Restaurant
     voltDbTemplate.update(procedureName, restaurant.getId(), restaurant.getName(),
                              serviceArea, openingHours[0], openingHours[1],
                              openingHours[2], menuItems[0], menuItems[1]);
}



                       56
VoltDbTemplate wrapper class
public class VoltDbTemplate {

   private Client client;         VoltDB client API

   public VoltDbTemplate(Client client) {
     this.client = client;
   }

   public void update(String procedureName, Object... params) {
     try {
       ClientResponse x =
               client.callProcedure(procedureName, params);
       …
   } catch (Exception e) {
       throw new RuntimeException(e);
     }
   }

                57
VoltDb server configuration
<?xml version="1.0"?>                      <deployment>
<project>                                    <cluster hostcount="1"
  <info>
     <name>Food To Go</name>                      sitesperhost="5" kfactor="0" />
     ...
  </info>                                  </deployment>
  <database>
     <schemas>
         <schema path='schema.sql' />
     </schemas>
     <partitions>
           <partition table="restaurant" column="id"/>
            ...
     </partitions>
     <procedures>
        <procedure class='net.chrisrichardson.foodToGo.newsql.voltdb.procs.AddRestaurant' />
        ...
     </procedures>
  </database>
</project>


voltcompiler target/classes 
   src/main/resources/sql/voltdb-project.xml foodtogo.jar


bin/voltdb leader localhost catalog foodtogo.jar deployment deployment.xml
                    58
Agenda
  Why NoSQL? NewSQL?
  Persisting entities
  Implementing queries




                          Slide 59
Finding available restaurants
Available restaurants =
      Serve the zip code of the delivery address
AND
      Are open at the delivery time

public interface AvailableRestaurantRepository {

    List<AvailableRestaurant>
          findAvailableRestaurants(Address deliveryAddress,
                                   Date deliveryTime); …
}




                    60
Finding available restaurants on Monday,
6.15pm for 94619 zip

select r.*             Straightforward
from restaurant r      three-way join
 inner join restaurant_time_range tr
   on r.id =tr.restaurant_id
 inner join restaurant_zipcode sa
   on r.id = sa.restaurant_id
Where ’94619’ = sa.zip_code
and tr.day_of_week=’monday’
and tr.openingtime <= 1815
and 1815 <= tr.closingtime


          61
MongoDB




          Slide 62
MongoDB = easy to query
{
    serviceArea:"94619",                        Find a
    openingHours: {
      $elemMatch : {                            restaurant
           "dayOfWeek" : "Monday",
            "open": {$lte: 1815},               that serves
       }
            "close": {$gte: 1815}
                                                the 94619 zip
}
    }                                           code and is
                                                open at
DBCursor cursor = collection.find(qbeObject);
while (cursor.hasNext()) {                      6.15pm on a
   DBObject o = cursor.next();
   …                                            Monday
 }


db.availableRestaurants.ensureIndex({serviceArea: 1})

                  63
MongoTemplate-based code
@Repository
public class AvailableRestaurantRepositoryMongoDbImpl
                               implements AvailableRestaurantRepository {

@Autowired private final MongoTemplate mongoTemplate;

@Override
public List<AvailableRestaurant> findAvailableRestaurants(Address deliveryAddress,
                                                          Date deliveryTime) {
 int timeOfDay = DateTimeUtil.timeOfDay(deliveryTime);
 int dayOfWeek = DateTimeUtil.dayOfWeek(deliveryTime);

    Query query = new Query(where("serviceArea").is(deliveryAddress.getZip())
         .and("openingHours”).elemMatch(where("dayOfWeek").is(dayOfWeek)
                .and("openingTime").lte(timeOfDay)
                .and("closingTime").gte(timeOfDay)));

    return mongoTemplate.find(AVAILABLE_RESTAURANTS_COLLECTION, query,
                            AvailableRestaurant.class);
}

              mongoTemplate.ensureIndex(“availableRestaurants”,
                 new Index().on("serviceArea", Order.ASCENDING));
                       64
But how do this with
Apache Cassandra??!




                       65
Slice is equivalent to a simple SELECT

keyVal   colName       colValue             select key, colName, colValue
X        Y             Z                    from columnFamily
…                                           where key = keyVal
                                              and colName >= startVal
                                              and colName <= endVal




                                  Column Family
                                                  columnFamily.slice(key=keyVal,
                                                   startColumn=startVal,
                                                   endColumn=endVal)
    X              Y         Z
We need to implement an index
that can be queried using a slice



       Queries instead of data
       model drives NoSQL
       database design


                                 Slide 67
Simplification #1: Denormalization
Restaurant_id   Day_of_week   Open_time   Close_time   Zip_code

1               Monday        1130        1430         94707
1               Monday        1130        1430         94619
1               Monday        1730        2130         94707
1               Monday        1730        2130         94619
2               Monday        0700        1430         94619
…



       SELECT restaurant_id
        FROM time_range_zip_code
        WHERE day_of_week = ‘Monday’              Simpler query:
          AND zip_code = 94619                      No joins
                                                    Two = and two <
          AND 1815 < close_time
          AND open_time < 1815

                   68
Simplification #2: Application filtering


SELECT restaurant_id, open_time
 FROM time_range_zip_code
 WHERE day_of_week = ‘Monday’     Even simpler query
   AND zip_code = 94619           •  No joins
   AND 1815 < close_time          •  Two = and one <
   AND open_time < 1815




            69
Simplification #3: Eliminate multiple =’s with
concatenation

  Restaurant_id   Zip_dow        Open_time   Close_time

  1               94707:Monday   1130        1430
  1               94619:Monday   1130        1430
  1               94707:Monday   1730        2130
  1               94619:Monday   1730        2130
  2               94619:Monday   0700        1430
  …


 SELECT restaurant_id, open_time
  FROM time_range_zip_code
  WHERE zip_code_day_of_week = ‘94619:Monday’
    AND 1815 < close_time
                                                          Row
                                                          key
                                 range

                  70
Column family as an index
      Restaurant_id     Zip_dow              Open_time            Close_time

      1                 94707:Monday         1130                 1430
      1                 94619:Monday         1130                 1430
      1                 94707:Monday         1730                 2130
      1                 94619:Monday         1730                 2130
      2                 94619:Monday         0700                 1430
      …




                                                     Column Family: AvailableRestaurants



                                JSON FOR                                     JSON FOR
                (1430,0700,2)                                (2130,1730,1)
94619:Monday                       EGG                                         AJANTA

                                                      JSON FOR
                                     (1430,1130,1)
                                                        AJANTA
Querying with a slice
                                                         Column Family: AvailableRestaurants


                                    JSON FOR                                         JSON FOR
                    (1430,0700,2)                                (2130,1730,1)
                                       EGG                                             AJANTA
94619:Monday

                                                          JSON FOR
                                         (1430,1130,1)
                                                            AJANTA




 slice(key= 94619:Monday, sliceStart = (1815, *, *), sliceEnd = (2359, *, *))



                                                                                     JSON FOR
                                                                     (2130,1730,1)
94619:Monday                                                                           AJANTA




                                       18:15 is after 17:30  {Ajanta}
                      72
Needs a few pages of code
         private void insertAvailability(Restaurant restaurant) {
                for (String zipCode : (Set<String>) restaurant.getServiceArea()) {
@Override         for (TimeRange tr : (Set<TimeRange>) restaurant.getOpeningHours()) {
 public List<AvailableRestaurant> findAvailableRestaurants(Address deliveryAddress, Date deliveryTime) {
                    String dayOfWeek = format2(tr.getDayOfWeek());
  int dayOfWeek = DateTimeUtil.dayOfWeek(deliveryTime);
                    String openingTime = format4(tr.getOpeningTime());
  int timeOfDay = DateTimeUtil.timeOfDay(deliveryTime);
                    String closingTime = format4(tr.getClosingTime());
  String zipCode = deliveryAddress.getZip();
  String key = formatKey(zipCode, format2(dayOfWeek));
                    String restaurantId = format8(restaurant.getId());
     HSlicePredicate<Composite> predicate = new HSlicePredicate<Composite>(new CompositeSerializer());
                        String key = formatKey(zipCode, dayOfWeek);
     Composite start = new Composite();
     Composite finish = new Composite();
                        String columnValue = toJson(restaurant);
     start.addComponent(0, format4(timeOfDay), ComponentEquality.GREATER_THAN_EQUAL);
     finish.addComponent(0, format4(2359), ComponentEquality.GREATER_THAN_EQUAL);
                   Composite columnName = new Composite();
     predicate.setRange(start, finish, false, 100);
                   columnName.add(0, closingTime);
     final List<AvailableRestaurantIndexEntry> closingAfter = new ArrayList<AvailableRestaurantIndexEntry>();
                   columnName.add(1, openingTime);
                   columnName.add(2, restaurantId);
     ColumnFamilyRowMapper<String, Composite, Object> mapper = new ColumnFamilyRowMapper<String, Composite, Object>() {

      @Override
                        ColumnFamilyUpdater<String, Composite> updater
      public Object mapRow(ColumnFamilyResult<String, Composite> results) {
                                      = compositeCloseTemplate.createUpdater(key);
        for (Composite columnName : results.getColumnNames()) {
          String openTime = columnName.get(1, new StringSerializer());
          String restaurantId = columnName.get(2, new StringSerializer());
                        updater.setString(columnName, columnValue);
          closingAfter.add(new AvailableRestaurantIndexEntry(openTime, restaurantId, results.getString(columnName)));
        }
        return null;
      }
     };
                        compositeCloseTemplate.update(updater);
                    }
     compositeCloseTemplate.queryColumns(key, predicate, mapper);
                }
     List<AvailableRestaurant> result = new LinkedList<AvailableRestaurant>();
            }
     for (AvailableRestaurantIndexEntry trIdAndAvailableRestaurant : closingAfter) {
       if (trIdAndAvailableRestaurant.isOpenBefore(timeOfDay))
         result.add(trIdAndAvailableRestaurant.getAvailableRestaurant());
     }

     return result;
 }                                         73
What did I just do to query the data?
  Wrote code to maintain an index
  Reduced performance due to extra
   writes




        74
But what would you rather implement?

      “Complex” query logic


               OR

     Multi-datacenter, multi-
       master database
          infrastructure

                                Slide 75
Slide 76
VoltDB - attempt #0
@ProcInfo( singlePartition = false)
public class FindAvailableRestaurants extends VoltProcedure { ... }




SELECT r.*
FROM restaurant r,time_range tr, service_area sa
WHERE ? = sa.zip_code and sa.restaurant_id= tr.restaurant_id
 AND r.restaurant_id = sa.restaurant_id and tr.day_of_week=?
 AND tr.open_time <= ?
 AND ? <= tr.close_time




                                    Slow 
                                                                 Slide 77
VoltDB - attempt #1
@ProcInfo( singlePartition = false)
public class FindAvailableRestaurants extends VoltProcedure { ... }

create index idx_service_area_zip_code on service_area(zip_code);
..

ERROR 10:12:03,251 [main] COMPILER: Failed to plan for statement
type(findAvailableRestaurants_with_join) select r.* from restaurant
r,time_range tr, service_area sa Where ? = sa.zip_code and
sa.restaurant_id= tr.restaurant_id and r.restaurant_id =
sa.restaurant_id and tr.day_of_week=? and tr.open_time <= ? and ?
<= tr.close_time Error: "Unable to plan for statement. Possibly joining
partitioned tables in a multi-partition procedure using a column that is
not the partitioning attribute or a non-equality operator. This is
statement not supported at this time."
2012-03-19 08:19:31,743 ERROR [main] COMPILER: Catalog
compilation failed.

                                        #fail
                                                                  Slide 78
VoltDB - attempt #2
@ProcInfo( singlePartition = true, partitionInfo = "Restaurant.id: 0”)
public class AddRestaurant extends VoltProcedure {

 public final SQLStmt insertAvailable=
             new SQLStmt("INSERT INTO available_time_range VALUES (?,?,?, ?, ?, ?);");

  public long run(....) {
               ...
    for (int i = 0; i < daysOfWeek.length ; i++) {
      voltQueueSQL(insertOpeningTimes, id, daysOfWeek[i], openingTimes[i], closingTimes[i]);
      for (String zipCode : serviceArea) {
       voltQueueSQL(insertAvailable, id, daysOfWeek[i], openingTimes[i],
                          closingTimes[i], zipCode, name);
      }
    }
               ...                    public final SQLStmt findAvailableRestaurants_denorm = new SQLStmt(
    voltExecuteSQL(true);                 "select restaurant_id, name from available_time_range tr " +
    return 0;                             "where ? = tr.zip_code " +
  }                                       "and tr.day_of_week=? " +
}                                         "and tr.open_time <= ? " +
                                          " and ? <= tr.close_time ");

                   Works but queries are only slightly
                         faster than MySQL! 
                                                                                               Slide 79
VoltDB - attempt #3
<partitions>
   ...
   <partition table="available_time_range" column="zip_code"/>
</partitions>

@ProcInfo( singlePartition = false, ...)
public class AddRestaurant extends VoltProcedure { ... }

@ProcInfo( singlePartition = true,
             partitionInfo = "available_time_range.zip_code: 0")
public class FindAvailableRestaurants extends VoltProcedure { ... }


             Queries are really fast 
             But inserts are not 

                 80
VoltDB – key lesson


A given partitioning scheme
 can be good for some use
  cases but bad for others




                        Slide 81
Summary



  Different databases
           =
  Different tradeoffs



                        82
… Summary…
         Benefits        Drawbacks
RDBMS    • SQL           • Lack of performance and scalability
         • ACID          • Difficult to distribute
         • Familiar      • Schema updates
                         • Handling semi-structured data
NoSQL    • Scalability   • Lack of ACID
         • Performance   • Limited querying (some)
         • Schema-less
NewSQL   • ACID          • Proprietary API
         • SQL           • Schema updates
         • Familiar      • Handling semi-structured data
         • Scalability   • Not all use cases are performant
         • Performance




                                                      Slide 83
… Summary
  Very carefully pick the NewSQL/
   NoSQL DB for your application
  Consider a polyglot persistence
   architecture
  Encapsulate your data access code so
   you can switch
  Startups = avoid NewSQL/NoSQL for
   shorter time to market?


                                    Slide 84
Thank you!




         My contact info:
         chris.richardson@springsource.com
             @crichardson
         Blog: http://plainoldobjects.com

Mais conteúdo relacionado

Mais procurados

Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014odnoklassniki.ru
 
Cassandra by example - the path of read and write requests
Cassandra by example - the path of read and write requestsCassandra by example - the path of read and write requests
Cassandra by example - the path of read and write requestsgrro
 
Elastic 101 tutorial - Percona Europe 2018
Elastic 101 tutorial - Percona Europe 2018 Elastic 101 tutorial - Percona Europe 2018
Elastic 101 tutorial - Percona Europe 2018 Antonios Giannopoulos
 
Introduction to Tokyo Products
Introduction to Tokyo ProductsIntroduction to Tokyo Products
Introduction to Tokyo ProductsMikio Hirabayashi
 
What's New in the PHP Driver
What's New in the PHP DriverWhat's New in the PHP Driver
What's New in the PHP DriverMongoDB
 
Memory efficient applications. FRANCESC ALTED at Big Data Spain 2012
Memory efficient applications. FRANCESC ALTED at Big Data Spain 2012Memory efficient applications. FRANCESC ALTED at Big Data Spain 2012
Memory efficient applications. FRANCESC ALTED at Big Data Spain 2012Big Data Spain
 
Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2won min jang
 
Intro to the Hadoop Stack @ April 2011 JavaMUG
Intro to the Hadoop Stack @ April 2011 JavaMUGIntro to the Hadoop Stack @ April 2011 JavaMUG
Intro to the Hadoop Stack @ April 2011 JavaMUGDavid Engfer
 
Column Stride Fields aka. DocValues
Column Stride Fields aka. DocValues Column Stride Fields aka. DocValues
Column Stride Fields aka. DocValues Lucidworks (Archived)
 
NoSQL and JavaScript: a love story
NoSQL and JavaScript: a love storyNoSQL and JavaScript: a love story
NoSQL and JavaScript: a love storyAlexandre Morgaut
 
NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010Ben Scofield
 
Varnish in action phpuk11
Varnish in action phpuk11Varnish in action phpuk11
Varnish in action phpuk11Combell NV
 
Scalable XQuery Processing with Zorba on top of MongoDB
Scalable XQuery Processing with Zorba on top of MongoDBScalable XQuery Processing with Zorba on top of MongoDB
Scalable XQuery Processing with Zorba on top of MongoDBWilliam Candillon
 
Elastic Search Training#1 (brief tutorial)-ESCC#1
Elastic Search Training#1 (brief tutorial)-ESCC#1Elastic Search Training#1 (brief tutorial)-ESCC#1
Elastic Search Training#1 (brief tutorial)-ESCC#1medcl
 
Java Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVMJava Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVModnoklassniki.ru
 

Mais procurados (20)

PyData Paris 2015 - Closing keynote Francesc Alted
PyData Paris 2015 - Closing keynote Francesc AltedPyData Paris 2015 - Closing keynote Francesc Alted
PyData Paris 2015 - Closing keynote Francesc Alted
 
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
 
Kyotoproducts
KyotoproductsKyotoproducts
Kyotoproducts
 
Cassandra by example - the path of read and write requests
Cassandra by example - the path of read and write requestsCassandra by example - the path of read and write requests
Cassandra by example - the path of read and write requests
 
Elastic 101 tutorial - Percona Europe 2018
Elastic 101 tutorial - Percona Europe 2018 Elastic 101 tutorial - Percona Europe 2018
Elastic 101 tutorial - Percona Europe 2018
 
Introduction to Tokyo Products
Introduction to Tokyo ProductsIntroduction to Tokyo Products
Introduction to Tokyo Products
 
What's New in the PHP Driver
What's New in the PHP DriverWhat's New in the PHP Driver
What's New in the PHP Driver
 
MongoTokyo
MongoTokyoMongoTokyo
MongoTokyo
 
Memory efficient applications. FRANCESC ALTED at Big Data Spain 2012
Memory efficient applications. FRANCESC ALTED at Big Data Spain 2012Memory efficient applications. FRANCESC ALTED at Big Data Spain 2012
Memory efficient applications. FRANCESC ALTED at Big Data Spain 2012
 
Mongo db roma replication and sharding
Mongo db roma replication and shardingMongo db roma replication and sharding
Mongo db roma replication and sharding
 
Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2
 
Intro to the Hadoop Stack @ April 2011 JavaMUG
Intro to the Hadoop Stack @ April 2011 JavaMUGIntro to the Hadoop Stack @ April 2011 JavaMUG
Intro to the Hadoop Stack @ April 2011 JavaMUG
 
Column Stride Fields aka. DocValues
Column Stride Fields aka. DocValues Column Stride Fields aka. DocValues
Column Stride Fields aka. DocValues
 
NoSQL and JavaScript: a love story
NoSQL and JavaScript: a love storyNoSQL and JavaScript: a love story
NoSQL and JavaScript: a love story
 
NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010
 
Groovy.pptx
Groovy.pptxGroovy.pptx
Groovy.pptx
 
Varnish in action phpuk11
Varnish in action phpuk11Varnish in action phpuk11
Varnish in action phpuk11
 
Scalable XQuery Processing with Zorba on top of MongoDB
Scalable XQuery Processing with Zorba on top of MongoDBScalable XQuery Processing with Zorba on top of MongoDB
Scalable XQuery Processing with Zorba on top of MongoDB
 
Elastic Search Training#1 (brief tutorial)-ESCC#1
Elastic Search Training#1 (brief tutorial)-ESCC#1Elastic Search Training#1 (brief tutorial)-ESCC#1
Elastic Search Training#1 (brief tutorial)-ESCC#1
 
Java Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVMJava Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVM
 

Semelhante a SQL? NoSQL? NewSQL?!? What's a Java developer to do? - PhillyETE 2012

MongoDB Live Hacking
MongoDB Live HackingMongoDB Live Hacking
MongoDB Live HackingTobias Trelle
 
FrozenRails Training
FrozenRails TrainingFrozenRails Training
FrozenRails TrainingMike Dirolf
 
BedCon 2013 - Java Persistenz-Frameworks für MongoDB
BedCon 2013 - Java Persistenz-Frameworks für MongoDBBedCon 2013 - Java Persistenz-Frameworks für MongoDB
BedCon 2013 - Java Persistenz-Frameworks für MongoDBTobias Trelle
 
MongoDB: Optimising for Performance, Scale & Analytics
MongoDB: Optimising for Performance, Scale & AnalyticsMongoDB: Optimising for Performance, Scale & Analytics
MongoDB: Optimising for Performance, Scale & AnalyticsServer Density
 
MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012Steven Francia
 
Squeak DBX
Squeak DBXSqueak DBX
Squeak DBXESUG
 
20140614 introduction to spark-ben white
20140614 introduction to spark-ben white20140614 introduction to spark-ben white
20140614 introduction to spark-ben whiteData Con LA
 
2016 feb-23 pyugre-py_mongo
2016 feb-23 pyugre-py_mongo2016 feb-23 pyugre-py_mongo
2016 feb-23 pyugre-py_mongoMichael Bright
 
Using MongoDB and Python
Using MongoDB and PythonUsing MongoDB and Python
Using MongoDB and PythonMike Bright
 
KVSの性能、RDBMSのインデックス、更にMapReduceを併せ持つAll-in-One NoSQL: MongoDB
KVSの性能、RDBMSのインデックス、更にMapReduceを併せ持つAll-in-One NoSQL: MongoDB KVSの性能、RDBMSのインデックス、更にMapReduceを併せ持つAll-in-One NoSQL: MongoDB
KVSの性能、RDBMSのインデックス、更にMapReduceを併せ持つAll-in-One NoSQL: MongoDB Rakuten Group, Inc.
 
Optimizing MongoDB: Lessons Learned at Localytics
Optimizing MongoDB: Lessons Learned at LocalyticsOptimizing MongoDB: Lessons Learned at Localytics
Optimizing MongoDB: Lessons Learned at Localyticsandrew311
 
Protect your app from Outages
Protect your app from OutagesProtect your app from Outages
Protect your app from OutagesRon Zavner
 
19th February 2013, AWS User Group UK, Meetup #3, Managing your apps on AWS: ...
19th February 2013, AWS User Group UK, Meetup #3, Managing your apps on AWS: ...19th February 2013, AWS User Group UK, Meetup #3, Managing your apps on AWS: ...
19th February 2013, AWS User Group UK, Meetup #3, Managing your apps on AWS: ...AWS User Group UK
 
Building a Scalable Distributed Stats Infrastructure with Storm and KairosDB
Building a Scalable Distributed Stats Infrastructure with Storm and KairosDBBuilding a Scalable Distributed Stats Infrastructure with Storm and KairosDB
Building a Scalable Distributed Stats Infrastructure with Storm and KairosDBCody Ray
 
Apache Spark II (SparkSQL)
Apache Spark II (SparkSQL)Apache Spark II (SparkSQL)
Apache Spark II (SparkSQL)Datio Big Data
 
Using Spring with NoSQL databases (SpringOne China 2012)
Using Spring with NoSQL databases (SpringOne China 2012)Using Spring with NoSQL databases (SpringOne China 2012)
Using Spring with NoSQL databases (SpringOne China 2012)Chris Richardson
 
Spark Summit EU talk by Ross Lawley
Spark Summit EU talk by Ross LawleySpark Summit EU talk by Ross Lawley
Spark Summit EU talk by Ross LawleySpark Summit
 
How To Connect Spark To Your Own Datasource
How To Connect Spark To Your Own DatasourceHow To Connect Spark To Your Own Datasource
How To Connect Spark To Your Own DatasourceMongoDB
 

Semelhante a SQL? NoSQL? NewSQL?!? What's a Java developer to do? - PhillyETE 2012 (20)

MongoDB Live Hacking
MongoDB Live HackingMongoDB Live Hacking
MongoDB Live Hacking
 
FrozenRails Training
FrozenRails TrainingFrozenRails Training
FrozenRails Training
 
BedCon 2013 - Java Persistenz-Frameworks für MongoDB
BedCon 2013 - Java Persistenz-Frameworks für MongoDBBedCon 2013 - Java Persistenz-Frameworks für MongoDB
BedCon 2013 - Java Persistenz-Frameworks für MongoDB
 
MongoDB: Optimising for Performance, Scale & Analytics
MongoDB: Optimising for Performance, Scale & AnalyticsMongoDB: Optimising for Performance, Scale & Analytics
MongoDB: Optimising for Performance, Scale & Analytics
 
MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012
 
Squeak DBX
Squeak DBXSqueak DBX
Squeak DBX
 
20140614 introduction to spark-ben white
20140614 introduction to spark-ben white20140614 introduction to spark-ben white
20140614 introduction to spark-ben white
 
2016 feb-23 pyugre-py_mongo
2016 feb-23 pyugre-py_mongo2016 feb-23 pyugre-py_mongo
2016 feb-23 pyugre-py_mongo
 
Using MongoDB and Python
Using MongoDB and PythonUsing MongoDB and Python
Using MongoDB and Python
 
KVSの性能、RDBMSのインデックス、更にMapReduceを併せ持つAll-in-One NoSQL: MongoDB
KVSの性能、RDBMSのインデックス、更にMapReduceを併せ持つAll-in-One NoSQL: MongoDB KVSの性能、RDBMSのインデックス、更にMapReduceを併せ持つAll-in-One NoSQL: MongoDB
KVSの性能、RDBMSのインデックス、更にMapReduceを併せ持つAll-in-One NoSQL: MongoDB
 
Optimizing MongoDB: Lessons Learned at Localytics
Optimizing MongoDB: Lessons Learned at LocalyticsOptimizing MongoDB: Lessons Learned at Localytics
Optimizing MongoDB: Lessons Learned at Localytics
 
NoSQL with MySQL
NoSQL with MySQLNoSQL with MySQL
NoSQL with MySQL
 
Protect your app from Outages
Protect your app from OutagesProtect your app from Outages
Protect your app from Outages
 
19th February 2013, AWS User Group UK, Meetup #3, Managing your apps on AWS: ...
19th February 2013, AWS User Group UK, Meetup #3, Managing your apps on AWS: ...19th February 2013, AWS User Group UK, Meetup #3, Managing your apps on AWS: ...
19th February 2013, AWS User Group UK, Meetup #3, Managing your apps on AWS: ...
 
Building a Scalable Distributed Stats Infrastructure with Storm and KairosDB
Building a Scalable Distributed Stats Infrastructure with Storm and KairosDBBuilding a Scalable Distributed Stats Infrastructure with Storm and KairosDB
Building a Scalable Distributed Stats Infrastructure with Storm and KairosDB
 
Scala+data
Scala+dataScala+data
Scala+data
 
Apache Spark II (SparkSQL)
Apache Spark II (SparkSQL)Apache Spark II (SparkSQL)
Apache Spark II (SparkSQL)
 
Using Spring with NoSQL databases (SpringOne China 2012)
Using Spring with NoSQL databases (SpringOne China 2012)Using Spring with NoSQL databases (SpringOne China 2012)
Using Spring with NoSQL databases (SpringOne China 2012)
 
Spark Summit EU talk by Ross Lawley
Spark Summit EU talk by Ross LawleySpark Summit EU talk by Ross Lawley
Spark Summit EU talk by Ross Lawley
 
How To Connect Spark To Your Own Datasource
How To Connect Spark To Your Own DatasourceHow To Connect Spark To Your Own Datasource
How To Connect Spark To Your Own Datasource
 

Mais de Chris Richardson

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?Chris Richardson
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternChris Richardson
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...Chris Richardson
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Chris Richardson
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsChris Richardson
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfChris Richardson
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Chris Richardson
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...Chris Richardson
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Chris Richardson
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 Chris Richardson
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureChris Richardson
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Chris Richardson
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled servicesChris Richardson
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Chris Richardson
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...Chris Richardson
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Chris Richardson
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...Chris Richardson
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationChris Richardson
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate PlatformChris Richardson
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolithChris Richardson
 

Mais de Chris Richardson (20)

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-pattern
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patterns
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled services
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders application
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate Platform
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith
 

Último

How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 

Último (20)

How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 

SQL? NoSQL? NewSQL?!? What's a Java developer to do? - PhillyETE 2012

  • 1. SQL, NoSQL, NewSQL? What's a developer to do? Chris Richardson Author of POJOs in Action Founder of the original CloudFoundry.com chris.richardson@springsource.com @crichardson Blog: http://plainoldobjects.com Copyright (c) 2012 Chris Richardson. All rights reserved.
  • 2. Overall presentation goal The joy and pain of building Java applications that use NoSQL and NewSQL 2
  • 7. About Chris http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/ 7
  • 8. About Chris Developer Advocate for CloudFoundry.com 8
  • 9. Agenda   Why NoSQL? NewSQL?   Persisting entities   Implementing queries Slide 9
  • 10. Food to Go   Take-out food delivery service   “Launched” in 2006   Used a relational database (naturally) 10
  • 11. Success  Growth challenges   Increasing traffic   Increasing data volume   Distribute across a few data centers   Increasing domain model complexity
  • 12. Limitations of relational databases   Scaling   Distribution   Updating schema   O/R impedance mismatch   Handling semi-structured data 12
  • 13. Solution: Spend Money   Buy SSD and RAM   Buy Oracle   Buy high-end servers   … OR http://upload.wikimedia.org/wikipedia/commons/e/e5/Rising_Sun_Yacht.JPG   Hire more DevOps   Use application-level sharding   Build your own middleware   … http://www.trekbikes.com/us/en/bikes/road/race_performance/madone_5_series/madone_5_2/# 13
  • 14. Solution: Use NoSQL Benefits Higher Limited performance transactions Higher scalability Relaxed Richer data- consistency model Unconstrained data Drawbacks Schema-less 14
  • 15. MongoDB Slide 15
  • 16. MongoDB is a document oriented DB Server Database: Food To Go Collection: Restaurants { "_id" : ObjectId("4bddc2f49d1505567c6220a0") "name": "Ajanta", "serviceArea": ["94619", "99999"], BSON = "openingHours": [ { binary "dayOfWeek": 1, JSON "open": 1130, "close": 1430 }, { Sequence "dayOfWeek": 2, "open": 1130, of bytes on "close": 1430 disk  fast }, … ] i/o } 16
  • 17. MongoDB – writes are fast Client MongoDB Insert(collection, documents) Insert(collection, documents) Async Insert(collection, documents) getLastError() Blocks until writes succeed Slide 17
  • 18. MongoDB is scalable Shard 1 Shard 2 Mongod Mongod (replica) (replica) Mongod Mongod (master) Mongod (master) Mongod (replica) (replica) Config Server mongod A shard consists of a mongos replica set = generalization of master slave mongod mongod Collections spread over multiple client shards 4/11/12 Slide 18
  • 19. MongoDB use cases   Use cases   High volume writes   Complex data   Semi-structured data   Used by: Shutterfly, Foursquare, Bit.ly, … Slide 19
  • 21. Cassandra is a column-oriented DB Column Column Row Value Name Timestamp Key Keyspace Column Family K1 N1 V1 TS1 N2 V2 TS2 N3 V3 TS3 K2 N1 V1 TS1 N2 V2 TS2 N3 V3 TS3 Column name/value: number, string, Boolean, timestamp, and composite 21
  • 22. Cassandra– inserting/updating data Column Family K1 N1 V1 TS1 N2 V2 TS2 N3 V3 TS3 … Idempotent= transaction CF.insert(key=K1, (N4, V4, TS4), …) Column Family K1 N1 V1 TS1 N2 V2 TS2 N3 V3 TS3 N4 V4 TS4 … 22
  • 23. Cassandra– retrieving data Column Family K1 N1 V1 TS1 N2 V2 TS2 N3 V3 TS3 N4 V4 TS4 … CF.slice(key=K1, startColumn=N2, endColumn=N4) K1 N2 V2 TS2 N3 V3 TS3 N4 V4 TS4 23
  • 24. Tunable reads and writes Higher availability Lower response time Less consistency   Any node (for writes)   One replica   Quorum of replicas   Local quorum   Each quorum   All replicas Lower availability Higher response time More consistency Slide 24
  • 25. Cassandra is scalable Application Application Node 1 Node 1 Node 4 Node 2 Node 4 Node 2 Node 3 Node 3 Cassandra cluster Cassandra cluster Datacenter 1 Datacenter 2 Slide 25
  • 26. Cassandra use cases   Use cases   Big data   Multiple Data Center distributed database   (Write intensive) Logging   High-availability (writes)   Used by: Netflix, Facebook, Digg, etc. Slide 26
  • 27. Other NoSQL databases Type Examples Extensible columns/Column- Hbase oriented SimpleDB DynamoDB Graph Neo4j Key-value Redis Membase Document CouchDb http://nosql-database.org/ lists 122+ NoSQL databases 27
  • 28. Solution: Use NewSQL   Relational databases with SQL and ACID transactions AND   New and improved architecture   Radically better scalability and performance   NewSQL vendors: ScaleDB, NimbusDB, …, VoltDB Slide 28
  • 29. Stonebraker’s motivations “…Current databases are designed for 1970s hardware …” Stonebraker: http://www.slideshare.net/VoltDB/sql-myths-webinar Significant overhead in “…logging, latching, locking, B-tree, and buffer management operations…” SIGMOD 08: Though the looking glass: http://dl.acm.org/citation.cfm?id=1376713 29
  • 30. About VoltDB   Open-source   In-memory relational database   Durability thru replication; snapshots and logging   Transparent partitioning   Fast and scalable …VoltDB is very scalable; it should scale to 120 partitions, 39 servers, and 1.6 million complex transactions per second at over 300 CPU cores… http://www.mysqlperformanceblog.com/2011/02/28/is-voltdb-really-as-scalable-as-they-claim/ Slide 30
  • 31. The future is polyglot persistence e.g. Netflix •  RDBMS •  SimpleDB •  Cassandra •  Hadoop/Hbase IEEE Software Sept/October 2010 - Debasish Ghosh / Twitter @debasishg 31
  • 32. Spring Data is here to help For NoSQL databases http://www.springsource.org/spring-data 32
  • 33. Agenda   Why NoSQL? NewSQL?   Persisting entities   Implementing queries Slide 33
  • 34. Food to Go – Place Order use case 1.  Customer enters delivery address and delivery time 2.  System displays available restaurants 3.  Customer picks restaurant 4.  System displays menu 5.  Customer selects menu items 6.  Customer places order 34
  • 35. Food to Go – Domain model (partial) class Restaurant { class TimeRange { long id; long id; String name; int dayOfWeek; Set<String> serviceArea; int openingTime; Set<TimeRange> openingHours; int closingTime; List<MenuItem> menuItems; } } class MenuItem { String name; double price; } 35
  • 36. Database schema ID Name … RESTAURANT 1 Ajanta table 2 Montclair Eggshop Restaurant_id zipcode RESTAURANT_ZIPCODE 1 94707 table 1 94619 2 94611 2 94619 RESTAURANT_TIME_RANGE table Restaurant_id dayOfWeek openTime closeTime 1 Monday 1130 1430 1 Monday 1730 2130 2 Tuesday 1130 … 36
  • 37. Pick your JDBC-based framework interface AvailableRestaurantRepository { void add(Restaurant restaurant); Restaurant findDetailsById(int id); … } Spring JDBC Hibernate/JPA … JDBC 37
  • 38. But with NoSQL? interface AvailableRestaurantRepository { Restaurant void add(Restaurant restaurant); Restaurant findDetailsById(int id); … TimeRange MenuItem } Restaurant aggregate ? ? 38
  • 39. MongoDB Slide 39
  • 40. MongoDB: persisting restaurants is easy { "_id" : ObjectId("4bddc2f49d1505567c6220a0") "name": "Ajanta", "serviceArea": ["94619", "99999"], "openingHours": [ { "dayOfWeek": 1, "open": 1130, "close": 1430 }, { "dayOfWeek": 2, "open": 1130, "close": 1430 }, … ] } 40
  • 41. Spring Data for Mongo code @Repository public class AvailableRestaurantRepositoryMongoDbImpl implements AvailableRestaurantRepository { public static String AVAILABLE_RESTAURANTS_COLLECTION = "availableRestaurants"; @Autowired private MongoTemplate mongoTemplate; @Override public void add(Restaurant restaurant) { mongoTemplate.insert(restaurant, AVAILABLE_RESTAURANTS_COLLECTION); } @Override public Restaurant findDetailsById(int id) { return mongoTemplate.findOne(new Query(where("_id").is(id)), Restaurant.class, AVAILABLE_RESTAURANTS_COLLECTION); } } 41
  • 42. Spring Configuration @Configuration public class MongoConfig extends AbstractDatabaseConfig { @Value("#{mongoDbProperties.databaseName}") private String mongoDbDatabase; @Bean public Mongo mongo() throws UnknownHostException, MongoException { return new Mongo(databaseHostName); } @Bean public MongoTemplate mongoTemplate(Mongo mongo) throws Exception { MongoTemplate mongoTemplate = new MongoTemplate(mongo, mongoDbDatabase); … return mongoTemplate; } } 42
  • 44. Option #1: Use a column per attribute Column Name = path/expression to access property value Column Family: RestaurantDetails openingHours[0].dayOfWeek Monday name Ajanta serviceArea[0] 94619 1 openingHours[0].open 1130 type indian serviceArea[1] 94707 openingHours[0].close 1430 Egg openingHours[0].dayOfWeek Monday name serviceArea[0] 94611 shop 2 Break openingHours[0].open 0830 type serviceArea[1] 94619 Fast openingHours[0].close 1430
  • 45. Option #2: Use a single column Column value = serialized object graph, e.g. JSON Column Family: RestaurantDetails 2 attributes: { name: “Montclair Eggshop”, … } 1 attributes { name: “Ajanta”, …} 2 attributes { name: “Eggshop”, …} Can’t use secondary indexes but they aren’t helpful for these use cases ✔ 45
  • 46. Cassandra code: wrapper around Hector public class AvailableRestaurantRepositoryCassandraKeyImpl implements AvailableRestaurantRepository { @Autowired Home grown private final CassandraTemplate cassandraTemplate; wrapper class public void add(Restaurant restaurant) { cassandraTemplate.insertEntity(keyspace, RESTAURANT_DETAILS_CF, restaurant); } public Restaurant findDetailsById(int id) { String key = Integer.toString(id); return cassandraTemplate.findEntity(Restaurant.class, keyspace, key, RESTAURANT_DETAILS_CF); … } … http://en.wikipedia.org/wiki/Hector 46
  • 48. Using VoltDB   Use the original schema   Standard SQL statements BUT YOU MUST   Write stored procedures and invoke them using proprietary interface   Partition your data Slide 48
  • 49. About VoltDB stored procedures   Key part of VoltDB   Replication = executing stored procedure on replica   Logging = log stored procedure invocation   Stored procedure invocation = transaction Slide 49
  • 50. About partitioning Partition column RESTAURANT table ID Name … 1 Ajanta 2 Eggshop … Partition 1 Partition 2 ID Name … ID Name … 1 Ajanta 2 Eggshop … … Slide 50
  • 51. Example VoltDB cluster (3 servers) x (2 partitions per server) ÷ 3 partitions (2 replicas per partition) Partition 1a Partition 2a Partition 3a ID Name … ID Name … ID Name … 1 Ajanta 2 Eggshop … .. … … … Partition 3b Partition 1b Partition 2b ID Name … ID Name … ID Name … … .. 1 Ajanta 2 Eggshop … … … VoltDB Server A VoltDB Server B VoltDB Server C Slide 51
  • 52. Single partition procedure: FAST SELECT * FROM RESTAURANT WHERE ID = 1 High-performance lock free code Stored Partition procedure column parameter ID Name … ID Name … ID Name … 1 Ajanta 1 Eggshop … .. … … … … … … VoltDB Server A VoltDB Server B VoltDB Server C Slide 52
  • 53. Multi-partition procedure: SLOWER SELECT * FROM RESTAURANT WHERE NAME = ‘Ajanta’ Communication/Coordination overhead ID Name … ID Name … ID Name … 1 Ajanta 1 Eggshop … .. … … … … … … VoltDB Server A VoltDB Server B VoltDB Server C Slide 53
  • 54. Chosen partitioning scheme <partitions> <partition table="restaurant" column="id"/> <partition table="service_area" column="restaurant_id"/> <partition table="menu_item" column="restaurant_id"/> <partition table="time_range" column="restaurant_id"/> <partition table="available_time_range" column="restaurant_id"/> </partitions> Performance is excellent: much faster than MySQL 54
  • 55. Stored procedure – AddRestaurant @ProcInfo( singlePartition = true, partitionInfo = "Restaurant.id: 0”) public class AddRestaurant extends VoltProcedure { public final SQLStmt insertRestaurant = new SQLStmt("INSERT INTO Restaurant VALUES (?,?);"); public final SQLStmt insertServiceArea = new SQLStmt("INSERT INTO service_area VALUES (?,?);"); public final SQLStmt insertOpeningTimes = new SQLStmt("INSERT INTO time_range VALUES (?,?,?,?);"); public final SQLStmt insertMenuItem = new SQLStmt("INSERT INTO menu_item VALUES (?,?,?);"); public long run(int id, String name, String[] serviceArea, long[] daysOfWeek, long[] openingTimes, long[] closingTimes, String[] names, double[] prices) { voltQueueSQL(insertRestaurant, id, name); for (String zipCode : serviceArea) voltQueueSQL(insertServiceArea, id, zipCode); for (int i = 0; i < daysOfWeek.length ; i++) voltQueueSQL(insertOpeningTimes, id, daysOfWeek[i], openingTimes[i], closingTimes[i]); for (int i = 0; i < names.length ; i++) voltQueueSQL(insertMenuItem, id, names[i], prices[i]); voltExecuteSQL(true); return 0; } } 55
  • 56. VoltDb repository – add() @Repository public class AvailableRestaurantRepositoryVoltdbImpl implements AvailableRestaurantRepository { @Autowired private VoltDbTemplate voltDbTemplate; @Override public void add(Restaurant restaurant) { invokeRestaurantProcedure("AddRestaurant", restaurant); } private void invokeRestaurantProcedure(String procedureName, Restaurant restaurant) { Object[] serviceArea = restaurant.getServiceArea().toArray(); long[][] openingHours = toArray(restaurant.getOpeningHours()); Flatten Object[][] menuItems = toArray(restaurant.getMenuItems()); Restaurant voltDbTemplate.update(procedureName, restaurant.getId(), restaurant.getName(), serviceArea, openingHours[0], openingHours[1], openingHours[2], menuItems[0], menuItems[1]); } 56
  • 57. VoltDbTemplate wrapper class public class VoltDbTemplate { private Client client; VoltDB client API public VoltDbTemplate(Client client) { this.client = client; } public void update(String procedureName, Object... params) { try { ClientResponse x = client.callProcedure(procedureName, params); … } catch (Exception e) { throw new RuntimeException(e); } } 57
  • 58. VoltDb server configuration <?xml version="1.0"?> <deployment> <project> <cluster hostcount="1" <info> <name>Food To Go</name> sitesperhost="5" kfactor="0" /> ... </info> </deployment> <database> <schemas> <schema path='schema.sql' /> </schemas> <partitions> <partition table="restaurant" column="id"/> ... </partitions> <procedures> <procedure class='net.chrisrichardson.foodToGo.newsql.voltdb.procs.AddRestaurant' /> ... </procedures> </database> </project> voltcompiler target/classes src/main/resources/sql/voltdb-project.xml foodtogo.jar bin/voltdb leader localhost catalog foodtogo.jar deployment deployment.xml 58
  • 59. Agenda   Why NoSQL? NewSQL?   Persisting entities   Implementing queries Slide 59
  • 60. Finding available restaurants Available restaurants = Serve the zip code of the delivery address AND Are open at the delivery time public interface AvailableRestaurantRepository { List<AvailableRestaurant> findAvailableRestaurants(Address deliveryAddress, Date deliveryTime); … } 60
  • 61. Finding available restaurants on Monday, 6.15pm for 94619 zip select r.* Straightforward from restaurant r three-way join inner join restaurant_time_range tr on r.id =tr.restaurant_id inner join restaurant_zipcode sa on r.id = sa.restaurant_id Where ’94619’ = sa.zip_code and tr.day_of_week=’monday’ and tr.openingtime <= 1815 and 1815 <= tr.closingtime 61
  • 62. MongoDB Slide 62
  • 63. MongoDB = easy to query { serviceArea:"94619", Find a openingHours: { $elemMatch : { restaurant "dayOfWeek" : "Monday", "open": {$lte: 1815}, that serves } "close": {$gte: 1815} the 94619 zip } } code and is open at DBCursor cursor = collection.find(qbeObject); while (cursor.hasNext()) { 6.15pm on a DBObject o = cursor.next(); … Monday } db.availableRestaurants.ensureIndex({serviceArea: 1}) 63
  • 64. MongoTemplate-based code @Repository public class AvailableRestaurantRepositoryMongoDbImpl implements AvailableRestaurantRepository { @Autowired private final MongoTemplate mongoTemplate; @Override public List<AvailableRestaurant> findAvailableRestaurants(Address deliveryAddress, Date deliveryTime) { int timeOfDay = DateTimeUtil.timeOfDay(deliveryTime); int dayOfWeek = DateTimeUtil.dayOfWeek(deliveryTime); Query query = new Query(where("serviceArea").is(deliveryAddress.getZip()) .and("openingHours”).elemMatch(where("dayOfWeek").is(dayOfWeek) .and("openingTime").lte(timeOfDay) .and("closingTime").gte(timeOfDay))); return mongoTemplate.find(AVAILABLE_RESTAURANTS_COLLECTION, query, AvailableRestaurant.class); } mongoTemplate.ensureIndex(“availableRestaurants”, new Index().on("serviceArea", Order.ASCENDING)); 64
  • 65. But how do this with Apache Cassandra??! 65
  • 66. Slice is equivalent to a simple SELECT keyVal colName colValue select key, colName, colValue X Y Z from columnFamily … where key = keyVal and colName >= startVal and colName <= endVal Column Family columnFamily.slice(key=keyVal, startColumn=startVal, endColumn=endVal) X Y Z
  • 67. We need to implement an index that can be queried using a slice Queries instead of data model drives NoSQL database design Slide 67
  • 68. Simplification #1: Denormalization Restaurant_id Day_of_week Open_time Close_time Zip_code 1 Monday 1130 1430 94707 1 Monday 1130 1430 94619 1 Monday 1730 2130 94707 1 Monday 1730 2130 94619 2 Monday 0700 1430 94619 … SELECT restaurant_id FROM time_range_zip_code WHERE day_of_week = ‘Monday’ Simpler query: AND zip_code = 94619   No joins   Two = and two < AND 1815 < close_time AND open_time < 1815 68
  • 69. Simplification #2: Application filtering SELECT restaurant_id, open_time FROM time_range_zip_code WHERE day_of_week = ‘Monday’ Even simpler query AND zip_code = 94619 •  No joins AND 1815 < close_time •  Two = and one < AND open_time < 1815 69
  • 70. Simplification #3: Eliminate multiple =’s with concatenation Restaurant_id Zip_dow Open_time Close_time 1 94707:Monday 1130 1430 1 94619:Monday 1130 1430 1 94707:Monday 1730 2130 1 94619:Monday 1730 2130 2 94619:Monday 0700 1430 … SELECT restaurant_id, open_time FROM time_range_zip_code WHERE zip_code_day_of_week = ‘94619:Monday’ AND 1815 < close_time Row key range 70
  • 71. Column family as an index Restaurant_id Zip_dow Open_time Close_time 1 94707:Monday 1130 1430 1 94619:Monday 1130 1430 1 94707:Monday 1730 2130 1 94619:Monday 1730 2130 2 94619:Monday 0700 1430 … Column Family: AvailableRestaurants JSON FOR JSON FOR (1430,0700,2) (2130,1730,1) 94619:Monday EGG AJANTA JSON FOR (1430,1130,1) AJANTA
  • 72. Querying with a slice Column Family: AvailableRestaurants JSON FOR JSON FOR (1430,0700,2) (2130,1730,1) EGG AJANTA 94619:Monday JSON FOR (1430,1130,1) AJANTA slice(key= 94619:Monday, sliceStart = (1815, *, *), sliceEnd = (2359, *, *)) JSON FOR (2130,1730,1) 94619:Monday AJANTA 18:15 is after 17:30  {Ajanta} 72
  • 73. Needs a few pages of code private void insertAvailability(Restaurant restaurant) { for (String zipCode : (Set<String>) restaurant.getServiceArea()) { @Override for (TimeRange tr : (Set<TimeRange>) restaurant.getOpeningHours()) { public List<AvailableRestaurant> findAvailableRestaurants(Address deliveryAddress, Date deliveryTime) { String dayOfWeek = format2(tr.getDayOfWeek()); int dayOfWeek = DateTimeUtil.dayOfWeek(deliveryTime); String openingTime = format4(tr.getOpeningTime()); int timeOfDay = DateTimeUtil.timeOfDay(deliveryTime); String closingTime = format4(tr.getClosingTime()); String zipCode = deliveryAddress.getZip(); String key = formatKey(zipCode, format2(dayOfWeek)); String restaurantId = format8(restaurant.getId()); HSlicePredicate<Composite> predicate = new HSlicePredicate<Composite>(new CompositeSerializer()); String key = formatKey(zipCode, dayOfWeek); Composite start = new Composite(); Composite finish = new Composite(); String columnValue = toJson(restaurant); start.addComponent(0, format4(timeOfDay), ComponentEquality.GREATER_THAN_EQUAL); finish.addComponent(0, format4(2359), ComponentEquality.GREATER_THAN_EQUAL); Composite columnName = new Composite(); predicate.setRange(start, finish, false, 100); columnName.add(0, closingTime); final List<AvailableRestaurantIndexEntry> closingAfter = new ArrayList<AvailableRestaurantIndexEntry>(); columnName.add(1, openingTime); columnName.add(2, restaurantId); ColumnFamilyRowMapper<String, Composite, Object> mapper = new ColumnFamilyRowMapper<String, Composite, Object>() { @Override ColumnFamilyUpdater<String, Composite> updater public Object mapRow(ColumnFamilyResult<String, Composite> results) { = compositeCloseTemplate.createUpdater(key); for (Composite columnName : results.getColumnNames()) { String openTime = columnName.get(1, new StringSerializer()); String restaurantId = columnName.get(2, new StringSerializer()); updater.setString(columnName, columnValue); closingAfter.add(new AvailableRestaurantIndexEntry(openTime, restaurantId, results.getString(columnName))); } return null; } }; compositeCloseTemplate.update(updater); } compositeCloseTemplate.queryColumns(key, predicate, mapper); } List<AvailableRestaurant> result = new LinkedList<AvailableRestaurant>(); } for (AvailableRestaurantIndexEntry trIdAndAvailableRestaurant : closingAfter) { if (trIdAndAvailableRestaurant.isOpenBefore(timeOfDay)) result.add(trIdAndAvailableRestaurant.getAvailableRestaurant()); } return result; } 73
  • 74. What did I just do to query the data?   Wrote code to maintain an index   Reduced performance due to extra writes 74
  • 75. But what would you rather implement? “Complex” query logic OR Multi-datacenter, multi- master database infrastructure Slide 75
  • 77. VoltDB - attempt #0 @ProcInfo( singlePartition = false) public class FindAvailableRestaurants extends VoltProcedure { ... } SELECT r.* FROM restaurant r,time_range tr, service_area sa WHERE ? = sa.zip_code and sa.restaurant_id= tr.restaurant_id AND r.restaurant_id = sa.restaurant_id and tr.day_of_week=? AND tr.open_time <= ? AND ? <= tr.close_time Slow  Slide 77
  • 78. VoltDB - attempt #1 @ProcInfo( singlePartition = false) public class FindAvailableRestaurants extends VoltProcedure { ... } create index idx_service_area_zip_code on service_area(zip_code); .. ERROR 10:12:03,251 [main] COMPILER: Failed to plan for statement type(findAvailableRestaurants_with_join) select r.* from restaurant r,time_range tr, service_area sa Where ? = sa.zip_code and sa.restaurant_id= tr.restaurant_id and r.restaurant_id = sa.restaurant_id and tr.day_of_week=? and tr.open_time <= ? and ? <= tr.close_time Error: "Unable to plan for statement. Possibly joining partitioned tables in a multi-partition procedure using a column that is not the partitioning attribute or a non-equality operator. This is statement not supported at this time." 2012-03-19 08:19:31,743 ERROR [main] COMPILER: Catalog compilation failed. #fail Slide 78
  • 79. VoltDB - attempt #2 @ProcInfo( singlePartition = true, partitionInfo = "Restaurant.id: 0”) public class AddRestaurant extends VoltProcedure { public final SQLStmt insertAvailable= new SQLStmt("INSERT INTO available_time_range VALUES (?,?,?, ?, ?, ?);"); public long run(....) { ... for (int i = 0; i < daysOfWeek.length ; i++) { voltQueueSQL(insertOpeningTimes, id, daysOfWeek[i], openingTimes[i], closingTimes[i]); for (String zipCode : serviceArea) { voltQueueSQL(insertAvailable, id, daysOfWeek[i], openingTimes[i], closingTimes[i], zipCode, name); } } ... public final SQLStmt findAvailableRestaurants_denorm = new SQLStmt( voltExecuteSQL(true); "select restaurant_id, name from available_time_range tr " + return 0; "where ? = tr.zip_code " + } "and tr.day_of_week=? " + } "and tr.open_time <= ? " + " and ? <= tr.close_time "); Works but queries are only slightly faster than MySQL!  Slide 79
  • 80. VoltDB - attempt #3 <partitions> ... <partition table="available_time_range" column="zip_code"/> </partitions> @ProcInfo( singlePartition = false, ...) public class AddRestaurant extends VoltProcedure { ... } @ProcInfo( singlePartition = true, partitionInfo = "available_time_range.zip_code: 0") public class FindAvailableRestaurants extends VoltProcedure { ... } Queries are really fast  But inserts are not  80
  • 81. VoltDB – key lesson A given partitioning scheme can be good for some use cases but bad for others Slide 81
  • 82. Summary Different databases = Different tradeoffs 82
  • 83. … Summary… Benefits Drawbacks RDBMS • SQL • Lack of performance and scalability • ACID • Difficult to distribute • Familiar • Schema updates • Handling semi-structured data NoSQL • Scalability • Lack of ACID • Performance • Limited querying (some) • Schema-less NewSQL • ACID • Proprietary API • SQL • Schema updates • Familiar • Handling semi-structured data • Scalability • Not all use cases are performant • Performance Slide 83
  • 84. … Summary   Very carefully pick the NewSQL/ NoSQL DB for your application   Consider a polyglot persistence architecture   Encapsulate your data access code so you can switch   Startups = avoid NewSQL/NoSQL for shorter time to market? Slide 84
  • 85. Thank you! My contact info: chris.richardson@springsource.com @crichardson Blog: http://plainoldobjects.com