SlideShare una empresa de Scribd logo
1 de 84
Descargar para leer sin conexión
Thursday, May 26, 2011
Hands on with the App
       Engine Datastore

       Ikai Lan
       May 9th, 2011




         2


Thursday, May 26, 2011
About the speaker
       • Ikai Lan - Developer Programs Engineer, Developer Relations
       • Twitter: @ikai
       • Google Profile: http://profiles.google.com/ikai.lan




         3


Thursday, May 26, 2011
Lab prerequisites
       • JDK 1.5+
       • Apache Ant
       • Codelab package: http://code.google.com/p/2011-datastore-
         bootcamp-codelab/downloads/detail?name=2011-datastore-
         bootcamp-codelab.zip

          Shortlink: http://tinyurl.com/datastore-bootcamp




         4


Thursday, May 26, 2011
Goals of this talk
       • Understand a bit of how the datastore works underneath the
         hood
       • Have a conceptual background for the persistence codelab




         5


Thursday, May 26, 2011
Understanding the datastore
       • The underlying Bigtable
       • Indexing and queries
       • Complex queries
       • Entity groups
       • Underlying infrastructure




         6


Thursday, May 26, 2011
Datastore layers




                                     Complex   Entity Group Queries on   Key range   Get and set
                                     queries   Transactions properties   scan        by key
                         Datastore
                                     ✓         ✓            ✓            ✓           ✓
                         Megastore
                                               ✓            ✓            ✓           ✓
                         Bigtable
                                                                         ✓           ✓



         7


Thursday, May 26, 2011
Datastore layers




                                                                                     Get and set
                                         Complex Entity Group Group on Key on
                                     Complex            Entity Queries Queries range byGet and set
                                                                                        key, key
                                         queries Transactions properties
                                     queries            Transactions   properties
                                                                           scan      range scans
                                                                                       by key
                         Datastore
                                     ✓✓          ✓ ✓ ✓                 ✓✓            ✓✓
                         Megastore
                                                 ✓ ✓ ✓                 ✓✓            ✓✓
                         Bigtable
                                                                           ✓         ✓✓



         8


Thursday, May 26, 2011
What does a Bigtable row look like?




                  Source: http://static.googleusercontent.com/external_content/untrusted_dlcp/labs.google.com/en/us/papers/bigtable-osdi06.pdf




         9


Thursday, May 26, 2011
Bigtable API
       • “Give me the column ‘name’ at key 123”
       • “Set the column ‘name’ at key 123 to ‘ikai’”
       • “Give me all columns where the key is greater than 100 and less
         than 200”




         10


Thursday, May 26, 2011
Datastore layers




                                                                                     Get and set
                                         Complex Entity Group Group on Key on
                                     Complex            Entity Queries Queries range byGet and set
                                                                                        key, key
                                         queries Transactions properties
                                     queries            Transactions   properties
                                                                           scan      range scans
                                                                                       by key
                         Datastore
                                     ✓✓          ✓ ✓ ✓                 ✓✓            ✓✓
                         Megastore
                                                 ✓ ✓ ✓                 ✓✓            ✓✓
                         Bigtable
                                                                           ✓         ✓✓



         11


Thursday, May 26, 2011
Megastore API
       • “Give me all rows where the column ‘name’ equals ‘ikai’”
       • “Transactionally write an update to this group of entities”
       • “Do a cross datacenter write of this data such that reads will be
         strongly consistent” (High Replication Datastore)
       • Megastore paper: http://www.cidrdb.org/cidr2011/Papers/
         CIDR11_Paper32.pdf




         12


Thursday, May 26, 2011
Datastore layers




                                                                                     Get and set
                                         Complex Entity Group Group on Key on
                                     Complex            Entity Queries Queries range byGet and set
                                                                                        key, key
                                         queries Transactions properties
                                     queries            Transactions   properties
                                                                           scan      range scans
                                                                                       by key
                         Datastore
                                     ✓✓          ✓ ✓ ✓                 ✓✓            ✓✓
                         Megastore
                                                 ✓ ✓ ✓                 ✓✓            ✓✓
                         Bigtable
                                                                           ✓         ✓✓



         13


Thursday, May 26, 2011
App Engine Datastore API
       • “Give me all Users for my app where the name equals ‘ikai’,
         company equals ‘Google’, and sort them by the ‘awesome’
         column, descending”




         14


Thursday, May 26, 2011
Thursday, May 26, 2011
Queries




Thursday, May 26, 2011
Let’s save an Entity with the low-level Java API
        	 DatastoreService datastore = DatastoreServiceFactory
      	 	 .getDatastoreService();

      	 Entity ikai = new Entity("User", "ikai@google.com");

      	 ikai.setProperty("firstName", "ikai");
      	 ikai.setProperty("company", "google");

      	 ikai.setUnindexedProperty("biography",
      	 	 "Ikai is a great man, a great, great man.");
      	
      	 datastore.put(ikai);




         16


Thursday, May 26, 2011
Get an instance of the DatastoreService
        DatastoreService datastore = DatastoreServiceFactory
      	 	 .getDatastoreService();

          Fetch a client instance
      	 Entity ikai = new Entity("User", "ikai@google.com");

      	 ikai.setProperty("firstName", "ikai");
      	 ikai.setProperty("company", "google");

      	 ikai.setUnindexedProperty("biography",
      	 	 "Ikai is a great man, a great, great man.");
      	
      	 datastore.put(ikai);




         17


Thursday, May 26, 2011
Instantiate a new Entity
        DatastoreService datastore = DatastoreServiceFactory
      	 	 .getDatastoreService();

      	 Entity ikai = new Entity("User", "ikai@google.com");

                  Set the Entity Kind
      	 ikai.setProperty("firstName", "ikai");
      	 ikai.setProperty("company", "google");

      	 ikai.setUnindexedProperty("biography",
      	 	 "Ikai is a great man, a great, great man.");
      	
      	 datastore.put(ikai);




         18


Thursday, May 26, 2011
Instantiate a new Entity
        DatastoreService datastore = DatastoreServiceFactory
      	 	 .getDatastoreService();

      	 Entity ikai = new Entity("User", "ikai@google.com");

      	 ikai.setProperty("firstName", "ikai"); a
                                          Set      unique key
      	 ikai.setProperty("company", "google");

      	 ikai.setUnindexedProperty("biography",
      	 	 "Ikai is a great man, a great, great man.");
      	
      	 datastore.put(ikai);




         19


Thursday, May 26, 2011
Set indexed properties
        DatastoreService datastore = DatastoreServiceFactory
      	 	 .getDatastoreService();

      	
               First argument is the
              Entity ikai = new Entity("User",   "ikai@google.com");
               property name
      	 ikai.setProperty("firstName", "ikai");
      	 ikai.setProperty("company", "google");

      	 ikai.setUnindexedProperty("biography", argument
                                       Second                     is the
                                       property value
      	 	 "Ikai is a great man, a great, great man.");
      	
      	 datastore.put(ikai);




         20


Thursday, May 26, 2011
Set unindexed properties
        DatastoreService datastore = DatastoreServiceFactory
      	 	 .getDatastoreService();

      	 Entity ikai = new Entity("User", "ikai@google.com");

           This property will be saved, but we
      	 ikai.setProperty("firstName", "ikai");
      	 ikai.setProperty("company", "google");
           will not run queries against it
      	 ikai.setUnindexedProperty("biography",
      	 	 "Ikai is a great man, a great, great man.");
      	
      	 datastore.put(ikai);




         21


Thursday, May 26, 2011
Commit the entity to the datastore
        DatastoreService datastore = DatastoreServiceFactory
      	 	 .getDatastoreService();

      	 Entity ikai = new Entity("User", "ikai@google.com");

      	 ikai.setProperty("firstName", "ikai");
      	 ikai.setProperty("company", "google");

      	 ikai.setUnindexedProperty("biography",
      	 	 "Ikai is a thing! man, a great, great man.");
           Save the great
      	
      	 datastore.put(ikai);




         22


Thursday, May 26, 2011
What happens when we save?




                          Write the entity
              Make the                       Success!
              write RPC
                          Write the
                          indexes




         23


Thursday, May 26, 2011
What actually gets written?

              Entities table

              Bigtable key                                                                Value
               AppId:User:ikai@google.com                                                 ( Protobuf serialized entity - includes
                                                                                          firstName, company and biography
                                                                                          values )




              Indexes table

              Bigtable key                                                                Value
              AppId:User:firstName:ikai:ikai@google.com                                   ( Empty )

              AppId:User:company:google:ikai@google.com                                   ( Empty )



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         24


Thursday, May 26, 2011
Now let’s run a query
       • If we have the key, we can fetch it right away by key
       • What if we don’t? We need indexes.




         25


Thursday, May 26, 2011
Let’s run a query
        DatastoreService datastore = DatastoreServiceFactory
      	 	 .getDatastoreService();

      	 Query queryByName = new Query("User");

      	 queryByName.addFilter("firstName",
           FilterOperator.EQUAL, "ikai");

      	 List<Entity> results = datastore.prepare(
           queryByName).asList(
      	 	      FetchOptions.Builder.withDefaults());

              // Roughly equivalent to:
              // SELECT * from User WHERE firstname = ‘ikai’;




         26


Thursday, May 26, 2011
Step 1: Query the indexes table

              Entities table

              Bigtable key                                                                Value
               AppId:User:ikai@google.com                                                 ( Protobuf serialized entity - includes
                                                                                          firstName, company and biography
                                                                                          values )

                          Scan the indexes table for values >=
                          AppId:User:firstName:
              Indexes table

              Bigtable key                                                                Value
              AppId:User:firstName:ikai:ikai@google.com                                   ( Empty )

              AppId:User:company:google:ikai@google.com                                   ( Empty )



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         27


Thursday, May 26, 2011
Step 2: Start extracting keys

              Entities table

              Bigtable key                                                                Value
               AppId:User:ikai@google.com                                                 ( Protobuf serialized entity - includes
                                                                                          firstName, company and biography
                                                                                          values )




              Indexes table

              Bigtable key                                                                Value
              AppId:User:firstName:ikai:ikai@google.com                                   ( Empty )

              AppId:User:company:google:ikai@google.com                                   ( Empty )


                                          That gets us this row - extract the key
                                          ikai@google.com
                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         28


Thursday, May 26, 2011
Step 3: Batch get the entities themselves

              Entities table

              Bigtable key                                                                Value
               AppId:User:ikai@google.com                                                 ( Protobuf serialized entity - includes
                                                                                          firstName, company and biography
                                                                                          values )




                    Now
              Indexes table  let’s go back to the entities table and
                        fetch that key. Success! Value
              Bigtable key
              AppId:User:firstName:ikai:ikai@google.com                                   ( Empty )

              AppId:User:company:google:ikai@google.com                                   ( Empty )



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         29


Thursday, May 26, 2011
Key takeaways
       • This isn’t a relational database
              – There are no full table scans
              – Indexes MUST exist for every property we want to query
              – Natively, we can only query on matches or startsWith queries
              – Don’t index what we never need to query on
       • Get by key = one step. Query on property value = 2 steps




         30


Thursday, May 26, 2011
Let’s run a more complex query!
        DatastoreService datastore = DatastoreServiceFactory
      	 	 .getDatastoreService();

      	 Query queryByName = new Query("User");

      	 queryByName.addFilter("firstName",
           FilterOperator.EQUAL, "ikai");

      	 queryByName.addFilter("company",
           FilterOperator.EQUAL, "google");

      	 List<Entity> results = datastore.prepare(
           queryByName).asList(
      	 	      FetchOptions.Builder.withDefaults());

              // Roughly equivalent to:
              // SELECT * from User WHERE firstname = ‘ikai’
              //   AND company = ‘google’;

         31


Thursday, May 26, 2011
Query resolution strategies
       • This query can be resolved using built in indexes
              – Zig zag merge join - we’ll cover this example

       • Can be optimized using composite indexes




         32


Thursday, May 26, 2011
Zig zag across multiple indexes
                                     Begin by scanning indexes >=
        Bigtable key
                                     AppId:User:company:google
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com


                                                                                        Bigtable key
                                                                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         33


Thursday, May 26, 2011
Zig zag across multiple indexes

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com

                                                                                There’s at least a partial match,
                                                                                   Bigtable key
                                                                                so we “jump” to the next index
                                                                                   AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         34


Thursday, May 26, 2011
Zig zag across multiple indexes

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com

      Move to the next index. Start a scan for keys >=
      AppId:User:company:megacorp:zed@megacorp.com

      AppId:User:firstName:ikai:david@google.com   Bigtable key
                                                                                         AppId:User:firstName:alfred:alfred@acme.com
                                                                                         AppId:User:firstName:ikai:ikai@acme.com
                                                                                         AppId:User:firstName:ikai:ikai@google.com
                                                                                         AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                         AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         35


Thursday, May 26, 2011
Zig zag across multiple indexes

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
      Okay, so that’s a twist. The first value that
       AppId:User:company:megacorp:zed@megacorp.com
      matches has key ikai@google.com! Does this
                                                    Bigtable key
      value exist in the first index?               AppId:User:firstName:alfred:alfred@acme.com
                                                                                         AppId:User:firstName:ikai:ikai@acme.com
                                                                                         AppId:User:firstName:ikai:ikai@google.com
                                                                                         AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                         AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         36


Thursday, May 26, 2011
Zig zag across multiple indexes
                                        Let’s advance the original cursor to >=
        Bigtable key
                                        AppId:User:company:google:ikai@google.com
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com


                                                                                        Bigtable key
                                                                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         37


Thursday, May 26, 2011
Zig zag across multiple indexes

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com

                                                                                        Bigtable key
                                                                                         AppId:User:firstName:alfred:alfred@acme.com
   Alright! We found a match. Let’s                                                      AppId:User:firstName:ikai:ikai@acme.com
   add the key to our in memory list                                                     AppId:User:firstName:ikai:ikai@google.com
   and go back to the first index                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                         AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         38


Thursday, May 26, 2011
Zig zag across multiple indexes

        Bigtable key      Let’s move on to see if there are any more
        AppId:User:company:acme:alfred@acme.com
                          matches. Let’s start at max@google.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com

                                                                                        Bigtable key
                                                                                        Bigtable key
                                                                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         39


Thursday, May 26, 2011
Zig zag across multiple indexes

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com

      Are there any keys >=
      AppId:User:company:megacorp:zed@megacorp.com

      AppId:User:firstName:ikai:max@google.com?    Bigtable key
                                                                                          AppId:User:firstName:alfred:alfred@acme.com
                                                                                          AppId:User:firstName:ikai:ikai@acme.com
                                                                                          AppId:User:firstName:ikai:ikai@google.com
                                                                                          AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                          AppId:User:firstName:zed:zed@megacorp.com


                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         40


Thursday, May 26, 2011
Zig zag across multiple indexes

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com

         No. We’re at the end of our                                                    Bigtable key
         index scans. Let’s do a batch                                                   AppId:User:firstName:alfred:alfred@acme.com

         key of our list of keys:                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                         AppId:User:firstName:ikai:ikai@google.com
         [ ‘ikai@google.com’ ]
                                                                                         AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                         AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         41


Thursday, May 26, 2011
Batch get the entities themselves

              Entities table

              Bigtable key                                                                Value
               AppId:User:ikai@google.com                                                 ( Protobuf serialized entity - includes
                                                                                          firstName, company and biography
                                                                                          values )




                          Now let’s go back to the entities table and
                          fetch that key. Success!



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         42


Thursday, May 26, 2011
Let’s change the shape of the data
       • Zig zag performance is HIGHLY dependent on the shape of the
         data
       • Let’s go ahead and muck with the data a bit




         43


Thursday, May 26, 2011
Same query, sparsely distributed matches

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com


                                                                                        Bigtable key
                                                                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:igor:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         44


Thursday, May 26, 2011
Same query, sparsely distributed matches
                                     Begin by scanning indexes >=
        Bigtable key
                                     AppId:User:company:google
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com


                                                                                        Bigtable key
                                                                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:igor:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         45


Thursday, May 26, 2011
Same query, sparsely distributed matches

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com

      Move to the next index. Start a scan for keys >=
                                        Bigtable key
      AppId:User:firstName:ikai:david@google.com
                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:igor:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         46


Thursday, May 26, 2011
Same query, sparsely distributed matches

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com


                                                                                        Bigtable key

          Oh ... no matches. Let’s                                                      AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
          move back to the first                                                        AppId:User:firstName:igor:ikai@google.com
          index and move the                                                            AppId:User:firstName:ikai:ikai@megacorp.com
          cursor down                                                                   AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         47


Thursday, May 26, 2011
Same query, sparsely distributed matches

        Bigtable key

                                     Okay, we’ve got another Googler
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com


                                                                                        Bigtable key
                                                                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:igor:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         48


Thursday, May 26, 2011
Same query, sparsely distributed matches

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
        AppId:User:company:google:ikai@google.com
        AppId:User:company:google:max@google.com
        AppId:User:company:megacorp:zed@megacorp.com

      Move to the next index. Start a scan for keys >=
                                        Bigtable key
      AppId:User:firstName:ikai:ikai@google.com
                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:igor:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         49


Thursday, May 26, 2011
Same query, sparsely distributed matches

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
                                                                                             Oh ... no matches here
        AppId:User:company:google:ikai@google.com                                            either. Let’s go back to
        AppId:User:company:google:max@google.com                                             the first index.
        AppId:User:company:megacorp:zed@megacorp.com


                                                                                        Bigtable key
                                                                                        AppId:User:firstName:alfred:alfred@acme.com
                                                                                        AppId:User:firstName:ikai:ikai@acme.com
                                                                                        AppId:User:firstName:igor:ikai@google.com
                                                                                        AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         50


Thursday, May 26, 2011
Same query, sparsely distributed matches

        Bigtable key
        AppId:User:company:acme:alfred@acme.com
        AppId:User:company:google:david@google.com
                                                                                             Oh ... no matches here
        AppId:User:company:google:ikai@google.com                                            either. Let’s go back to
        AppId:User:company:google:max@google.com                                             the first index.
        AppId:User:company:megacorp:zed@megacorp.com


                                                                                        Bigtable key
                                                                                        AppId:User:firstName:alfred:alfred@acme.com
               ... if these indexes were                                                AppId:User:firstName:ikai:ikai@acme.com
               huge, we could be here                                                   AppId:User:firstName:igor:ikai@google.com
               for a while!                                                             AppId:User:firstName:ikai:ikai@megacorp.com
                                                                                        AppId:User:firstName:zed:zed@megacorp.com



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         51


Thursday, May 26, 2011
What happens in this case?
       • If we traverse too many indexes, the datastore throws a
         NeedIndexException
       • We’ll want to build a composite index




         52


Thursday, May 26, 2011
Composite index

        Bigtable key
        AppId:User:company:acme:firstName:alfred:alfred@acme.com
        AppId:User:company:google:firstName:david:david@google.com
        AppId:User:company:google:firstName:ikai:ikai@google.com
        AppId:User:company:google:firstName:max:max@google.com
        AppId:User:company:megacorp:firstName:zed:zed@megacorp.com




                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         53


Thursday, May 26, 2011
Composite index

        Bigtable key
        AppId:User:company:acme:firstName:alfred:alfred@acme.com
        AppId:User:company:google:firstName:david:david@google.com
        AppId:User:company:google:firstName:ikai:ikai@google.com
        AppId:User:company:google:firstName:max:max@google.com
        AppId:User:company:megacorp:firstName:zed:zed@megacorp.com



                 Search for all keys >=
                 AppId:User:company:google:firstName:ikai



                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         54


Thursday, May 26, 2011
Composite index

        Bigtable key
        AppId:User:company:acme:firstName:alfred:alfred@acme.com
        AppId:User:company:google:firstName:david:david@google.com
        AppId:User:company:google:firstName:ikai:ikai@google.com
        AppId:User:company:google:firstName:max:max@google.com
        AppId:User:company:megacorp:firstName:zed:zed@megacorp.com




                 Well, that was much faster, wasn’t it?




                     Read more: http://code.google.com/appengine/articles/storage_breakdown.html




         55


Thursday, May 26, 2011
Composite index tradeoffs
       • Created at entity save time - incurs additional datastore CPU
         and storage quota
       • You can only create 200 composite index
       • You need to know the possible queries ahead of time!




         56


Thursday, May 26, 2011
Complex Queries takeaways
       • This isn’t a relational database
              – There are no full table scans
              – Indexes MUST exist for every property we want to query
       • Performance depends on the shape of the data
       • Worse case scenario: if your query matches are highly sparse
       • Build composite indexes when you need them




         57


Thursday, May 26, 2011
Thursday, May 26, 2011
Entity Groups




Thursday, May 26, 2011
Why entity groups?
       • We can perform transactions within this group - but not outside
       • Data locality - data are stored “near” each other
       • Strongly consistent queries when using High Replication
         datastore within this entity group




         59


Thursday, May 26, 2011
Entity groups and transactions
       • A hierarchical structuring of your data into Megastore’s unit of
         atomicity
       • Allows for transactional behavior - but only within a single entity
         group
       • Key unit of consistency when using High Replication datastore




         60


Thursday, May 26, 2011
Example: Data for a blog hosting service

                    User

                                      Blog   Has many
                           Has many


                                                 Entry


                                                        Has many   Comment




         61


Thursday, May 26, 2011
Example: Data for a blog hosting service

                    User

                                      Blog   Has many
                           Has many


                                                 Entry
               This can be structured as
               an entity group (tree
               structure)!                              Has many   Comment




         62


Thursday, May 26, 2011
Structure this data as an entity group

          Entity
                                              User
          group root


                                     Blog            Blog


                             Entry          Entry      Entry


                         Comment
                         Comment                            Comment




         63


Thursday, May 26, 2011
How are entity groups stored?

              Entities table

              Bigtable key                                                                  Value
              AppId:User:ikai@google.com                                                    ( Protobuf serialized User )

               AppId:User:ikai@google.com/Blog:123                                          ( Protobuf serialized Blog )

               AppId:User:ikai@google.com/Blog:123/Entry:456                                ( Protobuf serialized Entry )

               AppId:User:ikai@google.com/Blog:123/Entry:789                                ( Protobuf serialized Entry )

               AppId:User:ikai@google.com/Blog:123/Entry:456/                               ( Protobuf serialized Comment )
               Comment:111
               AppId:User:ikai@google.com/Blog:123/Entry:456/                               ( Protobuf serialized Comment )
               Comment:222
               AppId:User:ikai@google.com/Blog:123/Entry:789/                               ( Protobuf serialized Comment )
               Comment:333



                     Read more: http://code.google.com/appengine/docs/python/datastore/entities.html




         64


Thursday, May 26, 2011
How are entity groups stored?

              Entities table                                       Entity groups have a single root entity
              Bigtable key                                                                  Value
              AppId:User:ikai@google.com                                                    ( Protobuf serialized User )

               AppId:User:ikai@google.com/Blog:123                                          ( Protobuf serialized Blog )

               AppId:User:ikai@google.com/Blog:123/Entry:456                                ( Protobuf serialized Entry )

               AppId:User:ikai@google.com/Blog:123/Entry:789                                ( Protobuf serialized Entry )

               AppId:User:ikai@google.com/Blog:123/Entry:456/                               ( Protobuf serialized Comment )
               Comment:111
               AppId:User:ikai@google.com/Blog:123/Entry:456/                               ( Protobuf serialized Comment )
               Comment:222
               AppId:User:ikai@google.com/Blog:123/Entry:789/                               ( Protobuf serialized Comment )
               Comment:333



                     Read more: http://code.google.com/appengine/docs/python/datastore/entities.html




         65


Thursday, May 26, 2011
How are entity groups stored?

              Entities table

              Bigtable key                                                                  Value
              AppId:User:ikai@google.com                                                    ( Protobuf serialized User )

               AppId:User:ikai@google.com/Blog:123                                          ( Protobuf serialized Blog )

               AppId:User:ikai@google.com/Blog:123/Entry:456                                ( Protobuf serialized Entry )

               AppId:User:ikai@google.com/Blog:123/Entry:789                                ( Protobuf serialized Entry )
                                     Child entities embed the entire ancestry in
               AppId:User:ikai@google.com/Blog:123/Entry:456/ ( Protobuf serialized Comment )
               Comment:111           their keys
               AppId:User:ikai@google.com/Blog:123/Entry:456/                               ( Protobuf serialized Comment )
               Comment:222
               AppId:User:ikai@google.com/Blog:123/Entry:789/                               ( Protobuf serialized Comment )
               Comment:333



                     Read more: http://code.google.com/appengine/docs/python/datastore/entities.html




         66


Thursday, May 26, 2011
Let’s write an entity group transactionally
               DatastoreService datastore = DatastoreServiceFactory
      	        	 .getDatastoreService();

      	        Entity ikai = new Entity("User", "ikai@google.com");
      	        Entity blog = new Entity("Blog", "ikaisays.com",
                 ikai.getKey());
      	        Entity entry = new Entity("Entry", "datastore-intro",
                 blog.getKey());
      	
      	        // Auto assign an ID
      	        Entity comment = new Entity("Comment", entry.getKey());
      	
      	        Transaction tx = datastore.beginTransaction();
      	
      	        // Helper function for clarity
      	        datastore.put(Arrays.asList(ikai, blog,entry, comment));
      	
      	        tx.commit();




          67


Thursday, May 26, 2011
Let’s write an entity group transactionally
               DatastoreService datastore = DatastoreServiceFactory
      	        	 .getDatastoreService();          Create the root entity
      	        Entity ikai = new Entity("User", "ikai@google.com");
      	        Entity blog = new Entity("Blog", "ikaisays.com",
                 ikai.getKey());
      	        Entity entry = new Entity("Entry", "datastore-intro",
                 blog.getKey());
      	
      	        // Auto assign an ID
      	        Entity comment = new Entity("Comment", entry.getKey());
      	
      	        Transaction tx = datastore.beginTransaction();
      	
      	        // Helper function for clarity
      	        datastore.put(Arrays.asList(ikai, blog,entry, comment));
      	
      	        tx.commit();




          68


Thursday, May 26, 2011
Let’s write an entity group transactionally
               DatastoreService datastore = DatastoreServiceFactory
      	        	 .getDatastoreService();

      	        Entity ikai = new Entity("User", "ikai@google.com");
      	        Entity blog = new Entity("Blog", "ikaisays.com",
                 ikai.getKey());
      	        Entity entry = new Entity("Entry", "datastore-intro",
                 blog.getKey());
      	
      	         This is the first child entity - notice the third
               // Auto assign an ID
      	        Entity comment = new Entity("Comment", entry.getKey());
      	         argument, which specifies the parent entity key
      	        Transaction tx = datastore.beginTransaction();
      	
      	        // Helper function for clarity
      	        datastore.put(Arrays.asList(ikai, blog,entry, comment));
      	
      	        tx.commit();




          69


Thursday, May 26, 2011
Let’s write an entity group transactionally
               DatastoreService datastore = DatastoreServiceFactory
      	        	 .getDatastoreService();

      	        Entity ikai = new Entity("User", "ikai@google.com");
      	        Entity blog = new Entity("Blog", "ikaisays.com",
                 ikai.getKey());
      	        Entity entry = new Entity("Entry", "datastore-intro",
                 blog.getKey());
      	
      	        // Auto assign an ID
      	        Entity comment = new Entity("Comment", entry.getKey());
      	        The next deeper entity sets the blog as the
      	        parent
               Transaction tx = datastore.beginTransaction();
      	
      	        // Helper function for clarity
      	        datastore.put(Arrays.asList(ikai, blog,entry, comment));
      	
      	        tx.commit();




          70


Thursday, May 26, 2011
Let’s write an entity group transactionally
               DatastoreService datastore = DatastoreServiceFactory
      	        	 .getDatastoreService();

      	        Entity ikai = new Entity("User", "ikai@google.com");
      	        Entity blog = new Entity("Blog", "ikaisays.com",

      	
                   We can also opt to not provide a key name and
                 ikai.getKey());
               Entity entry = new Entity("Entry", "datastore-intro",
                   just use a parent key for a new entity
                 blog.getKey());
      	
      	        // Auto assign an ID
      	        Entity comment = new Entity("Comment", entry.getKey());
      	
      	        Transaction tx = datastore.beginTransaction();
      	
      	        // Helper function for clarity
      	        datastore.put(Arrays.asList(ikai, blog,entry, comment));
      	
      	        tx.commit();




          71


Thursday, May 26, 2011
Let’s write an entity group transactionally
               DatastoreService datastore = DatastoreServiceFactory
      	        	 .getDatastoreService();

      	        Entity ikai = new Entity("User", "ikai@google.com");
      	        Entity blog = new Entity("Blog", "ikaisays.com",
                 ikai.getKey());
      	        Entity entry = new Entity("Entry", "datastore-intro",
                 blog.getKey());
      	
      	                       Start a new transaction
               // Auto assign an ID
      	        Entity comment = new Entity("Comment", entry.getKey());
      	
      	        Transaction tx = datastore.beginTransaction();
      	
      	        // Helper function for clarity
      	        datastore.put(Arrays.asList(ikai, blog,entry, comment));
      	
      	        tx.commit();




          72


Thursday, May 26, 2011
Let’s write an entity group transactionally
               DatastoreService datastore = DatastoreServiceFactory
      	        	 .getDatastoreService();

      	        Entity ikai = new Entity("User", "ikai@google.com");
      	        Entity blog = new Entity("Blog", "ikaisays.com",
                 ikai.getKey());
      	        Entity entry = new Entity("Entry", "datastore-intro",
                 blog.getKey());
      	
      	        // Auto assign an ID
      	        Entity comment = new Entity("Comment", entry.getKey());
      	
      	        Transaction tx = datastore.beginTransaction();
      	
      	        // Helper function for clarity
      	        datastore.put(Arrays.asList(ikai, blog,entry, comment));
      	
      	        tx.commit();
                                      Put the entities in parallel



          73


Thursday, May 26, 2011
Let’s write an entity group transactionally
               DatastoreService datastore = DatastoreServiceFactory
      	        	 .getDatastoreService();

      	        Entity ikai = new Entity("User", "ikai@google.com");
      	        Entity blog = new Entity("Blog", "ikaisays.com",
                 ikai.getKey());
      	        Entity entry = new Entity("Entry", "datastore-intro",
                 blog.getKey());
      	
      	        // Auto assign an ID
      	        Entity comment = new Entity("Comment", entry.getKey());
      	
      	        Transaction tx = datastore.beginTransaction();
      	
      	        // Helper function for clarity
      	        Actually commit the changes
               datastore.put(Arrays.asList(ikai, blog,entry, comment));
      	
      	        tx.commit();




          74


Thursday, May 26, 2011
Step 1: Commit




                         Changes to         Changes to entities
       Commit
                         entities visible   and indexes visible




       Roll the timestamp forward on
       the root entity



         75


Thursday, May 26, 2011
On read, check for the most
       Step 2: Entity visible               recent timestamp on the root
                                            entity




                         Changes to          Changes to entities
       Commit
                         entities visible    and indexes visible




                              This is the version we want
                              since it represents a
                              complete write


         76


Thursday, May 26, 2011
Step 3: Indexes updated




                         Changes to          Changes to entities
       Commit
                         entities visible    and indexes visible




                                      Indexes are written - now we
                                      can query for this entity with
                                      the new properties


         77


Thursday, May 26, 2011
Entity group and transactions takeaways
       • Structure data into hierarchical trees
              – Large enough to be useful, small enough to maximize
                transactional throughput
       • Transactions need an entity group root - roughly 1 transaction/
         second
              – If you write N entities that are all part of 1 entity group, it counts as
                1 write
       • Optimistic locking used - can be expensive with a lot of
         contention




         78


Thursday, May 26, 2011
General datastore tips
       • Denormalize as much as possible
              – As much as possible, treat datastore as a key-value store
                (Dictionary or Map like structure)
              – Move large reporting to offline processing. This lets you avoid
                unnecessary indexes
       • Use entity groups for your data
       • Build composite indexes where you need them - “need” depends
         on shape of your data




         79


Thursday, May 26, 2011
Thursday, May 26, 2011
Questions?




Thursday, May 26, 2011
Thursday, May 26, 2011

Más contenido relacionado

Similar a Hands on with the App Engine Datastore: Understanding Datastore Layers

AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...Patrick Chanezon
 
Building Scalable Web Apps
Building Scalable Web AppsBuilding Scalable Web Apps
Building Scalable Web Appszeeg
 
Build a modern data platform.pptx
Build a modern data platform.pptxBuild a modern data platform.pptx
Build a modern data platform.pptxIke Ellis
 
X Aware Ajax World V1
X Aware Ajax World V1X Aware Ajax World V1
X Aware Ajax World V1rajivmordani
 
Scaling data on public clouds
Scaling data on public cloudsScaling data on public clouds
Scaling data on public cloudsLiran Zelkha
 
Finding the Right Data Solution for Your Application in the Data Storage Hays...
Finding the Right Data Solution for Your Application in the Data Storage Hays...Finding the Right Data Solution for Your Application in the Data Storage Hays...
Finding the Right Data Solution for Your Application in the Data Storage Hays...Srinath Perera
 
Oracle database performance monitoring diagnosis and reporting with EG Innova...
Oracle database performance monitoring diagnosis and reporting with EG Innova...Oracle database performance monitoring diagnosis and reporting with EG Innova...
Oracle database performance monitoring diagnosis and reporting with EG Innova...eG Innovations
 
(ATS3-APP14) Troubleshooting Symyx Notebook client performance
(ATS3-APP14) Troubleshooting Symyx Notebook client performance(ATS3-APP14) Troubleshooting Symyx Notebook client performance
(ATS3-APP14) Troubleshooting Symyx Notebook client performanceBIOVIA
 
Oracle Table Partitioning - Introduction
Oracle Table Partitioning  - IntroductionOracle Table Partitioning  - Introduction
Oracle Table Partitioning - IntroductionMyOnlineITCourses
 
ScaleBase Webinar 8.16: ScaleUp vs. ScaleOut
ScaleBase Webinar 8.16: ScaleUp vs. ScaleOutScaleBase Webinar 8.16: ScaleUp vs. ScaleOut
ScaleBase Webinar 8.16: ScaleUp vs. ScaleOutScaleBase
 
Automating Servers in the Cloud
Automating Servers in the CloudAutomating Servers in the Cloud
Automating Servers in the CloudRightScale
 
Common MongoDB Use Cases
Common MongoDB Use CasesCommon MongoDB Use Cases
Common MongoDB Use CasesDATAVERSITY
 
Top100summit christina
Top100summit christinaTop100summit christina
Top100summit christinaChristina Geng
 
Sharing a Startup’s Big Data Lessons
Sharing a Startup’s Big Data LessonsSharing a Startup’s Big Data Lessons
Sharing a Startup’s Big Data LessonsGeorge Stathis
 
Using Schematron for appropriate layer validation: A case study
Using Schematron for appropriate layer validation: A case studyUsing Schematron for appropriate layer validation: A case study
Using Schematron for appropriate layer validation: A case studyaschwarzman
 
Jimwebber soa
Jimwebber soaJimwebber soa
Jimwebber soad0nn9n
 
Strudel: Framework for Transaction Performance Analyses on SQL/NoSQL Systems
Strudel: Framework for Transaction Performance Analyses on SQL/NoSQL SystemsStrudel: Framework for Transaction Performance Analyses on SQL/NoSQL Systems
Strudel: Framework for Transaction Performance Analyses on SQL/NoSQL Systemstatemura
 
Understanding Metadata: Why it's essential to your big data solution and how ...
Understanding Metadata: Why it's essential to your big data solution and how ...Understanding Metadata: Why it's essential to your big data solution and how ...
Understanding Metadata: Why it's essential to your big data solution and how ...Zaloni
 

Similar a Hands on with the App Engine Datastore: Understanding Datastore Layers (20)

AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
AFCEA C4I Symposium: The 4th C in C4I Stands for Cloud:Factors Driving Adopti...
 
Building Scalable Web Apps
Building Scalable Web AppsBuilding Scalable Web Apps
Building Scalable Web Apps
 
Build a modern data platform.pptx
Build a modern data platform.pptxBuild a modern data platform.pptx
Build a modern data platform.pptx
 
The Vocbench Project
The Vocbench ProjectThe Vocbench Project
The Vocbench Project
 
X Aware Ajax World V1
X Aware Ajax World V1X Aware Ajax World V1
X Aware Ajax World V1
 
Scaling data on public clouds
Scaling data on public cloudsScaling data on public clouds
Scaling data on public clouds
 
Finding the Right Data Solution for Your Application in the Data Storage Hays...
Finding the Right Data Solution for Your Application in the Data Storage Hays...Finding the Right Data Solution for Your Application in the Data Storage Hays...
Finding the Right Data Solution for Your Application in the Data Storage Hays...
 
Oracle database performance monitoring diagnosis and reporting with EG Innova...
Oracle database performance monitoring diagnosis and reporting with EG Innova...Oracle database performance monitoring diagnosis and reporting with EG Innova...
Oracle database performance monitoring diagnosis and reporting with EG Innova...
 
(ATS3-APP14) Troubleshooting Symyx Notebook client performance
(ATS3-APP14) Troubleshooting Symyx Notebook client performance(ATS3-APP14) Troubleshooting Symyx Notebook client performance
(ATS3-APP14) Troubleshooting Symyx Notebook client performance
 
Oracle Table Partitioning - Introduction
Oracle Table Partitioning  - IntroductionOracle Table Partitioning  - Introduction
Oracle Table Partitioning - Introduction
 
ScaleBase Webinar 8.16: ScaleUp vs. ScaleOut
ScaleBase Webinar 8.16: ScaleUp vs. ScaleOutScaleBase Webinar 8.16: ScaleUp vs. ScaleOut
ScaleBase Webinar 8.16: ScaleUp vs. ScaleOut
 
Automating Servers in the Cloud
Automating Servers in the CloudAutomating Servers in the Cloud
Automating Servers in the Cloud
 
Best Practices For Centrally Governing Your Portal And Taxonomy Echo Techno...
Best Practices For Centrally Governing Your Portal And Taxonomy   Echo Techno...Best Practices For Centrally Governing Your Portal And Taxonomy   Echo Techno...
Best Practices For Centrally Governing Your Portal And Taxonomy Echo Techno...
 
Common MongoDB Use Cases
Common MongoDB Use CasesCommon MongoDB Use Cases
Common MongoDB Use Cases
 
Top100summit christina
Top100summit christinaTop100summit christina
Top100summit christina
 
Sharing a Startup’s Big Data Lessons
Sharing a Startup’s Big Data LessonsSharing a Startup’s Big Data Lessons
Sharing a Startup’s Big Data Lessons
 
Using Schematron for appropriate layer validation: A case study
Using Schematron for appropriate layer validation: A case studyUsing Schematron for appropriate layer validation: A case study
Using Schematron for appropriate layer validation: A case study
 
Jimwebber soa
Jimwebber soaJimwebber soa
Jimwebber soa
 
Strudel: Framework for Transaction Performance Analyses on SQL/NoSQL Systems
Strudel: Framework for Transaction Performance Analyses on SQL/NoSQL SystemsStrudel: Framework for Transaction Performance Analyses on SQL/NoSQL Systems
Strudel: Framework for Transaction Performance Analyses on SQL/NoSQL Systems
 
Understanding Metadata: Why it's essential to your big data solution and how ...
Understanding Metadata: Why it's essential to your big data solution and how ...Understanding Metadata: Why it's essential to your big data solution and how ...
Understanding Metadata: Why it's essential to your big data solution and how ...
 

Más de ikailan

Your language doesn't scale
Your language doesn't scaleYour language doesn't scale
Your language doesn't scaleikailan
 
From 0-1 billion in 46 days
From 0-1 billion in 46 daysFrom 0-1 billion in 46 days
From 0-1 billion in 46 daysikailan
 
2011 august-gdd-mexico-city-rest-json-oauth
2011 august-gdd-mexico-city-rest-json-oauth2011 august-gdd-mexico-city-rest-json-oauth
2011 august-gdd-mexico-city-rest-json-oauthikailan
 
2011 aug-gdd-mexico-city-high-replication-datastore
2011 aug-gdd-mexico-city-high-replication-datastore2011 aug-gdd-mexico-city-high-replication-datastore
2011 aug-gdd-mexico-city-high-replication-datastoreikailan
 
2011 july-nyc-gtug-go
2011 july-nyc-gtug-go2011 july-nyc-gtug-go
2011 july-nyc-gtug-goikailan
 
2011 july-gtug-high-replication-datastore
2011 july-gtug-high-replication-datastore2011 july-gtug-high-replication-datastore
2011 july-gtug-high-replication-datastoreikailan
 
Intro to App Engine - Agency Dev Day NYC 2011
Intro to App Engine - Agency Dev Day NYC 2011Intro to App Engine - Agency Dev Day NYC 2011
Intro to App Engine - Agency Dev Day NYC 2011ikailan
 
2011 june-kuala-lumpur-gtug-hackathon
2011 june-kuala-lumpur-gtug-hackathon2011 june-kuala-lumpur-gtug-hackathon
2011 june-kuala-lumpur-gtug-hackathonikailan
 
2011 June - Singapore GTUG presentation. App Engine program update + intro to Go
2011 June - Singapore GTUG presentation. App Engine program update + intro to Go2011 June - Singapore GTUG presentation. App Engine program update + intro to Go
2011 June - Singapore GTUG presentation. App Engine program update + intro to Goikailan
 
Rapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbRapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbikailan
 
What is App Engine? O
What is App Engine? OWhat is App Engine? O
What is App Engine? Oikailan
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010ikailan
 
Boot camp 2010_app_engine_101
Boot camp 2010_app_engine_101Boot camp 2010_app_engine_101
Boot camp 2010_app_engine_101ikailan
 
Building TweetEngine
Building TweetEngineBuilding TweetEngine
Building TweetEngineikailan
 

Más de ikailan (14)

Your language doesn't scale
Your language doesn't scaleYour language doesn't scale
Your language doesn't scale
 
From 0-1 billion in 46 days
From 0-1 billion in 46 daysFrom 0-1 billion in 46 days
From 0-1 billion in 46 days
 
2011 august-gdd-mexico-city-rest-json-oauth
2011 august-gdd-mexico-city-rest-json-oauth2011 august-gdd-mexico-city-rest-json-oauth
2011 august-gdd-mexico-city-rest-json-oauth
 
2011 aug-gdd-mexico-city-high-replication-datastore
2011 aug-gdd-mexico-city-high-replication-datastore2011 aug-gdd-mexico-city-high-replication-datastore
2011 aug-gdd-mexico-city-high-replication-datastore
 
2011 july-nyc-gtug-go
2011 july-nyc-gtug-go2011 july-nyc-gtug-go
2011 july-nyc-gtug-go
 
2011 july-gtug-high-replication-datastore
2011 july-gtug-high-replication-datastore2011 july-gtug-high-replication-datastore
2011 july-gtug-high-replication-datastore
 
Intro to App Engine - Agency Dev Day NYC 2011
Intro to App Engine - Agency Dev Day NYC 2011Intro to App Engine - Agency Dev Day NYC 2011
Intro to App Engine - Agency Dev Day NYC 2011
 
2011 june-kuala-lumpur-gtug-hackathon
2011 june-kuala-lumpur-gtug-hackathon2011 june-kuala-lumpur-gtug-hackathon
2011 june-kuala-lumpur-gtug-hackathon
 
2011 June - Singapore GTUG presentation. App Engine program update + intro to Go
2011 June - Singapore GTUG presentation. App Engine program update + intro to Go2011 June - Singapore GTUG presentation. App Engine program update + intro to Go
2011 June - Singapore GTUG presentation. App Engine program update + intro to Go
 
Rapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodbRapid web development using tornado web and mongodb
Rapid web development using tornado web and mongodb
 
What is App Engine? O
What is App Engine? OWhat is App Engine? O
What is App Engine? O
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010
 
Boot camp 2010_app_engine_101
Boot camp 2010_app_engine_101Boot camp 2010_app_engine_101
Boot camp 2010_app_engine_101
 
Building TweetEngine
Building TweetEngineBuilding TweetEngine
Building TweetEngine
 

Último

Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 

Último (20)

Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 

Hands on with the App Engine Datastore: Understanding Datastore Layers

  • 2. Hands on with the App Engine Datastore Ikai Lan May 9th, 2011 2 Thursday, May 26, 2011
  • 3. About the speaker • Ikai Lan - Developer Programs Engineer, Developer Relations • Twitter: @ikai • Google Profile: http://profiles.google.com/ikai.lan 3 Thursday, May 26, 2011
  • 4. Lab prerequisites • JDK 1.5+ • Apache Ant • Codelab package: http://code.google.com/p/2011-datastore- bootcamp-codelab/downloads/detail?name=2011-datastore- bootcamp-codelab.zip Shortlink: http://tinyurl.com/datastore-bootcamp 4 Thursday, May 26, 2011
  • 5. Goals of this talk • Understand a bit of how the datastore works underneath the hood • Have a conceptual background for the persistence codelab 5 Thursday, May 26, 2011
  • 6. Understanding the datastore • The underlying Bigtable • Indexing and queries • Complex queries • Entity groups • Underlying infrastructure 6 Thursday, May 26, 2011
  • 7. Datastore layers Complex Entity Group Queries on Key range Get and set queries Transactions properties scan by key Datastore ✓ ✓ ✓ ✓ ✓ Megastore ✓ ✓ ✓ ✓ Bigtable ✓ ✓ 7 Thursday, May 26, 2011
  • 8. Datastore layers Get and set Complex Entity Group Group on Key on Complex Entity Queries Queries range byGet and set key, key queries Transactions properties queries Transactions properties scan range scans by key Datastore ✓✓ ✓ ✓ ✓ ✓✓ ✓✓ Megastore ✓ ✓ ✓ ✓✓ ✓✓ Bigtable ✓ ✓✓ 8 Thursday, May 26, 2011
  • 9. What does a Bigtable row look like? Source: http://static.googleusercontent.com/external_content/untrusted_dlcp/labs.google.com/en/us/papers/bigtable-osdi06.pdf 9 Thursday, May 26, 2011
  • 10. Bigtable API • “Give me the column ‘name’ at key 123” • “Set the column ‘name’ at key 123 to ‘ikai’” • “Give me all columns where the key is greater than 100 and less than 200” 10 Thursday, May 26, 2011
  • 11. Datastore layers Get and set Complex Entity Group Group on Key on Complex Entity Queries Queries range byGet and set key, key queries Transactions properties queries Transactions properties scan range scans by key Datastore ✓✓ ✓ ✓ ✓ ✓✓ ✓✓ Megastore ✓ ✓ ✓ ✓✓ ✓✓ Bigtable ✓ ✓✓ 11 Thursday, May 26, 2011
  • 12. Megastore API • “Give me all rows where the column ‘name’ equals ‘ikai’” • “Transactionally write an update to this group of entities” • “Do a cross datacenter write of this data such that reads will be strongly consistent” (High Replication Datastore) • Megastore paper: http://www.cidrdb.org/cidr2011/Papers/ CIDR11_Paper32.pdf 12 Thursday, May 26, 2011
  • 13. Datastore layers Get and set Complex Entity Group Group on Key on Complex Entity Queries Queries range byGet and set key, key queries Transactions properties queries Transactions properties scan range scans by key Datastore ✓✓ ✓ ✓ ✓ ✓✓ ✓✓ Megastore ✓ ✓ ✓ ✓✓ ✓✓ Bigtable ✓ ✓✓ 13 Thursday, May 26, 2011
  • 14. App Engine Datastore API • “Give me all Users for my app where the name equals ‘ikai’, company equals ‘Google’, and sort them by the ‘awesome’ column, descending” 14 Thursday, May 26, 2011
  • 17. Let’s save an Entity with the low-level Java API DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); ikai.setProperty("firstName", "ikai"); ikai.setProperty("company", "google"); ikai.setUnindexedProperty("biography", "Ikai is a great man, a great, great man."); datastore.put(ikai); 16 Thursday, May 26, 2011
  • 18. Get an instance of the DatastoreService DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Fetch a client instance Entity ikai = new Entity("User", "ikai@google.com"); ikai.setProperty("firstName", "ikai"); ikai.setProperty("company", "google"); ikai.setUnindexedProperty("biography", "Ikai is a great man, a great, great man."); datastore.put(ikai); 17 Thursday, May 26, 2011
  • 19. Instantiate a new Entity DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); Set the Entity Kind ikai.setProperty("firstName", "ikai"); ikai.setProperty("company", "google"); ikai.setUnindexedProperty("biography", "Ikai is a great man, a great, great man."); datastore.put(ikai); 18 Thursday, May 26, 2011
  • 20. Instantiate a new Entity DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); ikai.setProperty("firstName", "ikai"); a Set unique key ikai.setProperty("company", "google"); ikai.setUnindexedProperty("biography", "Ikai is a great man, a great, great man."); datastore.put(ikai); 19 Thursday, May 26, 2011
  • 21. Set indexed properties DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); First argument is the Entity ikai = new Entity("User", "ikai@google.com"); property name ikai.setProperty("firstName", "ikai"); ikai.setProperty("company", "google"); ikai.setUnindexedProperty("biography", argument Second is the property value "Ikai is a great man, a great, great man."); datastore.put(ikai); 20 Thursday, May 26, 2011
  • 22. Set unindexed properties DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); This property will be saved, but we ikai.setProperty("firstName", "ikai"); ikai.setProperty("company", "google"); will not run queries against it ikai.setUnindexedProperty("biography", "Ikai is a great man, a great, great man."); datastore.put(ikai); 21 Thursday, May 26, 2011
  • 23. Commit the entity to the datastore DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); ikai.setProperty("firstName", "ikai"); ikai.setProperty("company", "google"); ikai.setUnindexedProperty("biography", "Ikai is a thing! man, a great, great man."); Save the great datastore.put(ikai); 22 Thursday, May 26, 2011
  • 24. What happens when we save? Write the entity Make the Success! write RPC Write the indexes 23 Thursday, May 26, 2011
  • 25. What actually gets written? Entities table Bigtable key Value AppId:User:ikai@google.com ( Protobuf serialized entity - includes firstName, company and biography values ) Indexes table Bigtable key Value AppId:User:firstName:ikai:ikai@google.com ( Empty ) AppId:User:company:google:ikai@google.com ( Empty ) Read more: http://code.google.com/appengine/articles/storage_breakdown.html 24 Thursday, May 26, 2011
  • 26. Now let’s run a query • If we have the key, we can fetch it right away by key • What if we don’t? We need indexes. 25 Thursday, May 26, 2011
  • 27. Let’s run a query DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Query queryByName = new Query("User"); queryByName.addFilter("firstName", FilterOperator.EQUAL, "ikai"); List<Entity> results = datastore.prepare( queryByName).asList( FetchOptions.Builder.withDefaults()); // Roughly equivalent to: // SELECT * from User WHERE firstname = ‘ikai’; 26 Thursday, May 26, 2011
  • 28. Step 1: Query the indexes table Entities table Bigtable key Value AppId:User:ikai@google.com ( Protobuf serialized entity - includes firstName, company and biography values ) Scan the indexes table for values >= AppId:User:firstName: Indexes table Bigtable key Value AppId:User:firstName:ikai:ikai@google.com ( Empty ) AppId:User:company:google:ikai@google.com ( Empty ) Read more: http://code.google.com/appengine/articles/storage_breakdown.html 27 Thursday, May 26, 2011
  • 29. Step 2: Start extracting keys Entities table Bigtable key Value AppId:User:ikai@google.com ( Protobuf serialized entity - includes firstName, company and biography values ) Indexes table Bigtable key Value AppId:User:firstName:ikai:ikai@google.com ( Empty ) AppId:User:company:google:ikai@google.com ( Empty ) That gets us this row - extract the key ikai@google.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 28 Thursday, May 26, 2011
  • 30. Step 3: Batch get the entities themselves Entities table Bigtable key Value AppId:User:ikai@google.com ( Protobuf serialized entity - includes firstName, company and biography values ) Now Indexes table let’s go back to the entities table and fetch that key. Success! Value Bigtable key AppId:User:firstName:ikai:ikai@google.com ( Empty ) AppId:User:company:google:ikai@google.com ( Empty ) Read more: http://code.google.com/appengine/articles/storage_breakdown.html 29 Thursday, May 26, 2011
  • 31. Key takeaways • This isn’t a relational database – There are no full table scans – Indexes MUST exist for every property we want to query – Natively, we can only query on matches or startsWith queries – Don’t index what we never need to query on • Get by key = one step. Query on property value = 2 steps 30 Thursday, May 26, 2011
  • 32. Let’s run a more complex query! DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Query queryByName = new Query("User"); queryByName.addFilter("firstName", FilterOperator.EQUAL, "ikai"); queryByName.addFilter("company", FilterOperator.EQUAL, "google"); List<Entity> results = datastore.prepare( queryByName).asList( FetchOptions.Builder.withDefaults()); // Roughly equivalent to: // SELECT * from User WHERE firstname = ‘ikai’ // AND company = ‘google’; 31 Thursday, May 26, 2011
  • 33. Query resolution strategies • This query can be resolved using built in indexes – Zig zag merge join - we’ll cover this example • Can be optimized using composite indexes 32 Thursday, May 26, 2011
  • 34. Zig zag across multiple indexes Begin by scanning indexes >= Bigtable key AppId:User:company:google AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Bigtable key AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:ikai:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 33 Thursday, May 26, 2011
  • 35. Zig zag across multiple indexes Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com There’s at least a partial match, Bigtable key so we “jump” to the next index AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:ikai:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 34 Thursday, May 26, 2011
  • 36. Zig zag across multiple indexes Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com Move to the next index. Start a scan for keys >= AppId:User:company:megacorp:zed@megacorp.com AppId:User:firstName:ikai:david@google.com Bigtable key AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:ikai:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 35 Thursday, May 26, 2011
  • 37. Zig zag across multiple indexes Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com Okay, so that’s a twist. The first value that AppId:User:company:megacorp:zed@megacorp.com matches has key ikai@google.com! Does this Bigtable key value exist in the first index? AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:ikai:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 36 Thursday, May 26, 2011
  • 38. Zig zag across multiple indexes Let’s advance the original cursor to >= Bigtable key AppId:User:company:google:ikai@google.com AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Bigtable key AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:ikai:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 37 Thursday, May 26, 2011
  • 39. Zig zag across multiple indexes Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Bigtable key AppId:User:firstName:alfred:alfred@acme.com Alright! We found a match. Let’s AppId:User:firstName:ikai:ikai@acme.com add the key to our in memory list AppId:User:firstName:ikai:ikai@google.com and go back to the first index AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 38 Thursday, May 26, 2011
  • 40. Zig zag across multiple indexes Bigtable key Let’s move on to see if there are any more AppId:User:company:acme:alfred@acme.com matches. Let’s start at max@google.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Bigtable key Bigtable key AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:ikai:ikai@google.com AppId:User:firstName:ikai:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 39 Thursday, May 26, 2011
  • 41. Zig zag across multiple indexes Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com Are there any keys >= AppId:User:company:megacorp:zed@megacorp.com AppId:User:firstName:ikai:max@google.com? Bigtable key AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:ikai:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 40 Thursday, May 26, 2011
  • 42. Zig zag across multiple indexes Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com No. We’re at the end of our Bigtable key index scans. Let’s do a batch AppId:User:firstName:alfred:alfred@acme.com key of our list of keys: AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:ikai:ikai@google.com [ ‘ikai@google.com’ ] AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 41 Thursday, May 26, 2011
  • 43. Batch get the entities themselves Entities table Bigtable key Value AppId:User:ikai@google.com ( Protobuf serialized entity - includes firstName, company and biography values ) Now let’s go back to the entities table and fetch that key. Success! Read more: http://code.google.com/appengine/articles/storage_breakdown.html 42 Thursday, May 26, 2011
  • 44. Let’s change the shape of the data • Zig zag performance is HIGHLY dependent on the shape of the data • Let’s go ahead and muck with the data a bit 43 Thursday, May 26, 2011
  • 45. Same query, sparsely distributed matches Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Bigtable key AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:igor:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 44 Thursday, May 26, 2011
  • 46. Same query, sparsely distributed matches Begin by scanning indexes >= Bigtable key AppId:User:company:google AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Bigtable key AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:igor:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 45 Thursday, May 26, 2011
  • 47. Same query, sparsely distributed matches Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Move to the next index. Start a scan for keys >= Bigtable key AppId:User:firstName:ikai:david@google.com AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:igor:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 46 Thursday, May 26, 2011
  • 48. Same query, sparsely distributed matches Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Bigtable key Oh ... no matches. Let’s AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com move back to the first AppId:User:firstName:igor:ikai@google.com index and move the AppId:User:firstName:ikai:ikai@megacorp.com cursor down AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 47 Thursday, May 26, 2011
  • 49. Same query, sparsely distributed matches Bigtable key Okay, we’ve got another Googler AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Bigtable key AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:igor:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 48 Thursday, May 26, 2011
  • 50. Same query, sparsely distributed matches Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com AppId:User:company:google:ikai@google.com AppId:User:company:google:max@google.com AppId:User:company:megacorp:zed@megacorp.com Move to the next index. Start a scan for keys >= Bigtable key AppId:User:firstName:ikai:ikai@google.com AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:igor:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 49 Thursday, May 26, 2011
  • 51. Same query, sparsely distributed matches Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com Oh ... no matches here AppId:User:company:google:ikai@google.com either. Let’s go back to AppId:User:company:google:max@google.com the first index. AppId:User:company:megacorp:zed@megacorp.com Bigtable key AppId:User:firstName:alfred:alfred@acme.com AppId:User:firstName:ikai:ikai@acme.com AppId:User:firstName:igor:ikai@google.com AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 50 Thursday, May 26, 2011
  • 52. Same query, sparsely distributed matches Bigtable key AppId:User:company:acme:alfred@acme.com AppId:User:company:google:david@google.com Oh ... no matches here AppId:User:company:google:ikai@google.com either. Let’s go back to AppId:User:company:google:max@google.com the first index. AppId:User:company:megacorp:zed@megacorp.com Bigtable key AppId:User:firstName:alfred:alfred@acme.com ... if these indexes were AppId:User:firstName:ikai:ikai@acme.com huge, we could be here AppId:User:firstName:igor:ikai@google.com for a while! AppId:User:firstName:ikai:ikai@megacorp.com AppId:User:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 51 Thursday, May 26, 2011
  • 53. What happens in this case? • If we traverse too many indexes, the datastore throws a NeedIndexException • We’ll want to build a composite index 52 Thursday, May 26, 2011
  • 54. Composite index Bigtable key AppId:User:company:acme:firstName:alfred:alfred@acme.com AppId:User:company:google:firstName:david:david@google.com AppId:User:company:google:firstName:ikai:ikai@google.com AppId:User:company:google:firstName:max:max@google.com AppId:User:company:megacorp:firstName:zed:zed@megacorp.com Read more: http://code.google.com/appengine/articles/storage_breakdown.html 53 Thursday, May 26, 2011
  • 55. Composite index Bigtable key AppId:User:company:acme:firstName:alfred:alfred@acme.com AppId:User:company:google:firstName:david:david@google.com AppId:User:company:google:firstName:ikai:ikai@google.com AppId:User:company:google:firstName:max:max@google.com AppId:User:company:megacorp:firstName:zed:zed@megacorp.com Search for all keys >= AppId:User:company:google:firstName:ikai Read more: http://code.google.com/appengine/articles/storage_breakdown.html 54 Thursday, May 26, 2011
  • 56. Composite index Bigtable key AppId:User:company:acme:firstName:alfred:alfred@acme.com AppId:User:company:google:firstName:david:david@google.com AppId:User:company:google:firstName:ikai:ikai@google.com AppId:User:company:google:firstName:max:max@google.com AppId:User:company:megacorp:firstName:zed:zed@megacorp.com Well, that was much faster, wasn’t it? Read more: http://code.google.com/appengine/articles/storage_breakdown.html 55 Thursday, May 26, 2011
  • 57. Composite index tradeoffs • Created at entity save time - incurs additional datastore CPU and storage quota • You can only create 200 composite index • You need to know the possible queries ahead of time! 56 Thursday, May 26, 2011
  • 58. Complex Queries takeaways • This isn’t a relational database – There are no full table scans – Indexes MUST exist for every property we want to query • Performance depends on the shape of the data • Worse case scenario: if your query matches are highly sparse • Build composite indexes when you need them 57 Thursday, May 26, 2011
  • 61. Why entity groups? • We can perform transactions within this group - but not outside • Data locality - data are stored “near” each other • Strongly consistent queries when using High Replication datastore within this entity group 59 Thursday, May 26, 2011
  • 62. Entity groups and transactions • A hierarchical structuring of your data into Megastore’s unit of atomicity • Allows for transactional behavior - but only within a single entity group • Key unit of consistency when using High Replication datastore 60 Thursday, May 26, 2011
  • 63. Example: Data for a blog hosting service User Blog Has many Has many Entry Has many Comment 61 Thursday, May 26, 2011
  • 64. Example: Data for a blog hosting service User Blog Has many Has many Entry This can be structured as an entity group (tree structure)! Has many Comment 62 Thursday, May 26, 2011
  • 65. Structure this data as an entity group Entity User group root Blog Blog Entry Entry Entry Comment Comment Comment 63 Thursday, May 26, 2011
  • 66. How are entity groups stored? Entities table Bigtable key Value AppId:User:ikai@google.com ( Protobuf serialized User ) AppId:User:ikai@google.com/Blog:123 ( Protobuf serialized Blog ) AppId:User:ikai@google.com/Blog:123/Entry:456 ( Protobuf serialized Entry ) AppId:User:ikai@google.com/Blog:123/Entry:789 ( Protobuf serialized Entry ) AppId:User:ikai@google.com/Blog:123/Entry:456/ ( Protobuf serialized Comment ) Comment:111 AppId:User:ikai@google.com/Blog:123/Entry:456/ ( Protobuf serialized Comment ) Comment:222 AppId:User:ikai@google.com/Blog:123/Entry:789/ ( Protobuf serialized Comment ) Comment:333 Read more: http://code.google.com/appengine/docs/python/datastore/entities.html 64 Thursday, May 26, 2011
  • 67. How are entity groups stored? Entities table Entity groups have a single root entity Bigtable key Value AppId:User:ikai@google.com ( Protobuf serialized User ) AppId:User:ikai@google.com/Blog:123 ( Protobuf serialized Blog ) AppId:User:ikai@google.com/Blog:123/Entry:456 ( Protobuf serialized Entry ) AppId:User:ikai@google.com/Blog:123/Entry:789 ( Protobuf serialized Entry ) AppId:User:ikai@google.com/Blog:123/Entry:456/ ( Protobuf serialized Comment ) Comment:111 AppId:User:ikai@google.com/Blog:123/Entry:456/ ( Protobuf serialized Comment ) Comment:222 AppId:User:ikai@google.com/Blog:123/Entry:789/ ( Protobuf serialized Comment ) Comment:333 Read more: http://code.google.com/appengine/docs/python/datastore/entities.html 65 Thursday, May 26, 2011
  • 68. How are entity groups stored? Entities table Bigtable key Value AppId:User:ikai@google.com ( Protobuf serialized User ) AppId:User:ikai@google.com/Blog:123 ( Protobuf serialized Blog ) AppId:User:ikai@google.com/Blog:123/Entry:456 ( Protobuf serialized Entry ) AppId:User:ikai@google.com/Blog:123/Entry:789 ( Protobuf serialized Entry ) Child entities embed the entire ancestry in AppId:User:ikai@google.com/Blog:123/Entry:456/ ( Protobuf serialized Comment ) Comment:111 their keys AppId:User:ikai@google.com/Blog:123/Entry:456/ ( Protobuf serialized Comment ) Comment:222 AppId:User:ikai@google.com/Blog:123/Entry:789/ ( Protobuf serialized Comment ) Comment:333 Read more: http://code.google.com/appengine/docs/python/datastore/entities.html 66 Thursday, May 26, 2011
  • 69. Let’s write an entity group transactionally DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); Entity blog = new Entity("Blog", "ikaisays.com", ikai.getKey()); Entity entry = new Entity("Entry", "datastore-intro", blog.getKey()); // Auto assign an ID Entity comment = new Entity("Comment", entry.getKey()); Transaction tx = datastore.beginTransaction(); // Helper function for clarity datastore.put(Arrays.asList(ikai, blog,entry, comment)); tx.commit(); 67 Thursday, May 26, 2011
  • 70. Let’s write an entity group transactionally DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Create the root entity Entity ikai = new Entity("User", "ikai@google.com"); Entity blog = new Entity("Blog", "ikaisays.com", ikai.getKey()); Entity entry = new Entity("Entry", "datastore-intro", blog.getKey()); // Auto assign an ID Entity comment = new Entity("Comment", entry.getKey()); Transaction tx = datastore.beginTransaction(); // Helper function for clarity datastore.put(Arrays.asList(ikai, blog,entry, comment)); tx.commit(); 68 Thursday, May 26, 2011
  • 71. Let’s write an entity group transactionally DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); Entity blog = new Entity("Blog", "ikaisays.com", ikai.getKey()); Entity entry = new Entity("Entry", "datastore-intro", blog.getKey()); This is the first child entity - notice the third // Auto assign an ID Entity comment = new Entity("Comment", entry.getKey()); argument, which specifies the parent entity key Transaction tx = datastore.beginTransaction(); // Helper function for clarity datastore.put(Arrays.asList(ikai, blog,entry, comment)); tx.commit(); 69 Thursday, May 26, 2011
  • 72. Let’s write an entity group transactionally DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); Entity blog = new Entity("Blog", "ikaisays.com", ikai.getKey()); Entity entry = new Entity("Entry", "datastore-intro", blog.getKey()); // Auto assign an ID Entity comment = new Entity("Comment", entry.getKey()); The next deeper entity sets the blog as the parent Transaction tx = datastore.beginTransaction(); // Helper function for clarity datastore.put(Arrays.asList(ikai, blog,entry, comment)); tx.commit(); 70 Thursday, May 26, 2011
  • 73. Let’s write an entity group transactionally DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); Entity blog = new Entity("Blog", "ikaisays.com", We can also opt to not provide a key name and ikai.getKey()); Entity entry = new Entity("Entry", "datastore-intro", just use a parent key for a new entity blog.getKey()); // Auto assign an ID Entity comment = new Entity("Comment", entry.getKey()); Transaction tx = datastore.beginTransaction(); // Helper function for clarity datastore.put(Arrays.asList(ikai, blog,entry, comment)); tx.commit(); 71 Thursday, May 26, 2011
  • 74. Let’s write an entity group transactionally DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); Entity blog = new Entity("Blog", "ikaisays.com", ikai.getKey()); Entity entry = new Entity("Entry", "datastore-intro", blog.getKey()); Start a new transaction // Auto assign an ID Entity comment = new Entity("Comment", entry.getKey()); Transaction tx = datastore.beginTransaction(); // Helper function for clarity datastore.put(Arrays.asList(ikai, blog,entry, comment)); tx.commit(); 72 Thursday, May 26, 2011
  • 75. Let’s write an entity group transactionally DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); Entity blog = new Entity("Blog", "ikaisays.com", ikai.getKey()); Entity entry = new Entity("Entry", "datastore-intro", blog.getKey()); // Auto assign an ID Entity comment = new Entity("Comment", entry.getKey()); Transaction tx = datastore.beginTransaction(); // Helper function for clarity datastore.put(Arrays.asList(ikai, blog,entry, comment)); tx.commit(); Put the entities in parallel 73 Thursday, May 26, 2011
  • 76. Let’s write an entity group transactionally DatastoreService datastore = DatastoreServiceFactory .getDatastoreService(); Entity ikai = new Entity("User", "ikai@google.com"); Entity blog = new Entity("Blog", "ikaisays.com", ikai.getKey()); Entity entry = new Entity("Entry", "datastore-intro", blog.getKey()); // Auto assign an ID Entity comment = new Entity("Comment", entry.getKey()); Transaction tx = datastore.beginTransaction(); // Helper function for clarity Actually commit the changes datastore.put(Arrays.asList(ikai, blog,entry, comment)); tx.commit(); 74 Thursday, May 26, 2011
  • 77. Step 1: Commit Changes to Changes to entities Commit entities visible and indexes visible Roll the timestamp forward on the root entity 75 Thursday, May 26, 2011
  • 78. On read, check for the most Step 2: Entity visible recent timestamp on the root entity Changes to Changes to entities Commit entities visible and indexes visible This is the version we want since it represents a complete write 76 Thursday, May 26, 2011
  • 79. Step 3: Indexes updated Changes to Changes to entities Commit entities visible and indexes visible Indexes are written - now we can query for this entity with the new properties 77 Thursday, May 26, 2011
  • 80. Entity group and transactions takeaways • Structure data into hierarchical trees – Large enough to be useful, small enough to maximize transactional throughput • Transactions need an entity group root - roughly 1 transaction/ second – If you write N entities that are all part of 1 entity group, it counts as 1 write • Optimistic locking used - can be expensive with a lot of contention 78 Thursday, May 26, 2011
  • 81. General datastore tips • Denormalize as much as possible – As much as possible, treat datastore as a key-value store (Dictionary or Map like structure) – Move large reporting to offline processing. This lets you avoid unnecessary indexes • Use entity groups for your data • Build composite indexes where you need them - “need” depends on shape of your data 79 Thursday, May 26, 2011