These servers are optimized for both internal architecture and network topology to handle requests for static resources. To the client, static files look like any other resource served by your app. You upload the static files of your application right alongside the application code.
You can configure several aspects of how static files are served, including the URLs for static files, content types, and instructions for browsers to keep copies of the files in a cache for a given amount of time to reduce traffic and speed up rendering of the page. Most useful web applications need to store information during the handling of a request for retrieval during a later request.
A typical arrangement for a small website involves a single database server for the entire site, and one or more web servers that connect to the database to store or retrieve data. Using a single central database server makes it easy to have one canonical representation of the data, so multiple users accessing multiple web servers all see the same and most recent information.
But a central server is difficult to scale once it reaches its capacity for simultaneous connections. Other kinds of data storage systems include hierarchical datastores filesystems, XML databases and object databases.
And each kind of database has its own techniques for growing past the first server. As with the runtime environment, the design of the App Engine datastore is an abstraction that allows App Engine to handle the details of distributing and scaling the application, so your code can focus on other things.
An App Engine application stores its data as one or more datastore entities. An entity has one or more properties , each of which has a name, and a value that is of one of several primitive value types. Each entity is of a named kind , which categorizes the entity for the purpose of queries. At first glance, this seems similar to a relational database: entities of a kind are like rows in a table, and properties are like columns fields.
However, there are two major differences between entities and rows. First, an entity of a given kind is not required to have the same properties as other entities of the same kind. Second, an entity can have a property of the same name as another entity has, but with a different type of value. Another difference between an entity and a table row is that an entity can have multiple values for a single property. This feature is a bit quirky, but can be quite useful once understood.
Every datastore entity has a unique key that is either provided by the application or generated by App Engine your choice. You can fetch an entity quickly if you know its key, and you can perform queries on key values. Neither can its kind. A datastore query returns zero or more entities of a single kind. It can also return just the keys of entities that would be returned for a query. A query can also filter and sort using keys.
In a typical relational database, queries are planned and executed in real time against the data tables, which are stored just as they were designed by the developer. The developer can also tell the database to produce and maintain indexes on certain columns to speed up certain queries.
App Engine does something dramatically different. With App Engine, every query has a corresponding index maintained by the datastore. Of course, this requires that App Engine know ahead of time which queries the application is going to perform. App Engine provides a set of indexes for simple queries by default, based on which properties exist on entities of a kind. For more complex queries, an app must include index specifications in its configuration.
The App Engine SDK helps produce this configuration file by watching which queries are performed as you test your application with the provided development web server on your computer. When you upload your app, the datastore knows to make indexes for every query the app performed during testing. You can also edit the index configuration manually. When your application creates new entities and updates existing ones, the datastore updates every corresponding index.
This makes queries very fast each query is a simple table scan at the expense of entity updates possibly many tables may need updating for a single change. In fact, the performance of an index-backed query is not affected by the number of entities in the datastore, only the size of the result set.
We discuss indexes in detail in Chapter 6. When an application has many clients attempting to read or write the same data simultaneously, it is imperative that the data always be in a consistent state. When an application updates the properties of a single entity, App Engine ensures that either every update to the entity succeeds all at once, or the entire update fails and the entity remains the way it was prior to the beginning of the update.
Other users do not see any effects of the change until the change succeeds. In other words, an update of a single entity occurs in a transaction. Each transaction is atomic : the transaction either succeeds completely or fails completely, and cannot succeed or fail in smaller pieces. An application can read or update multiple entities in a single transaction, but it must tell App Engine which entities will be updated together when it creates the entities.
The application does this by creating entities in entity groups. App Engine uses entity groups to control how entities are distributed across servers, so it can guarantee a transaction on a group succeeds or fails completely. In database terms, the App Engine datastore natively supports local transactions. When an application calls the datastore API to update an entity, the call returns only after the transaction succeeds or fails, and it returns with knowledge of success or failure.
For updates, this means the service waits for all entities to be updated before returning a result. The application can call the datastore asynchronously, such that the app code can continue executing while the datastore is preparing a result.
But the update itself does not return until it has confirmed the change. The other user must try her operation again, possibly rereading values and calculating the update from fresh data. Contention is expected, so retries are common. Reading the entity never fails due to contention.
The application just sees the entity in its most recent stable state. You can also read multiple entities from the same entity group by using a transaction to ensure that all the data in the group is current and consistent with itself. In most cases, retrying a transaction on a contested entity will succeed. But if an application is designed such that many users might update a single entity, the more popular the application gets, the more likely users will get contention failures.
It is important to design entity groups to avoid a high rate of contention failures even with a large number of users. It is often important to read and write data in the same transaction. For example, the application can start a transaction, read an entity, update a property value based on the last read value, save the entity, and then commit the transaction.
In this case, the save action does not occur unless the entire transaction succeeds without conflict with another transaction. If there is a conflict and the app wants to try again, the app should retry the entire transaction: read the possibly updated entity again, use the new value for the calculation, and attempt the update again. By including the read operation in the transaction, the datastore can assume that related writes and reads from multiple simultaneous requests do not interleave and produce inconsistent results.
With indexes and optimistic concurrency control, the App Engine datastore is designed for applications that need to read data quickly, ensure that the data it sees is in a consistent form, and scale the number of users and the size of the data automatically.
While these goals are somewhat different from those of a relational database, they are especially well suited to web applications. Google App Engine includes several other self-scaling services useful for web applications. The memory cache or memcache service is a short-term key-value storage service. Its main advantage over the datastore is that it is fast, much faster than the datastore for simple storage and retrieval. The memcache stores values in memory instead of on disk for faster access.
It is distributed like the datastore, so every request sees the same set of keys and values. However, it is not persistent like the datastore: if a server goes down, such as during a power failure, memory is erased. It also has a more limited sense of atomicity and transactionality than the datastore. As the name implies, the memcache service is best used as a cache for the results of frequently performed queries or calculations.
App Engine provides a storage system for large values called the Blobstore. Your app can use the Blobstore to store, manage, and serve large files, such as images, videos, or file downloads. The Blobstore can also accept large files uploaded by users and offline processes. This service is distinct from the datastore to work around infrastructure limits on request and response sizes between users, application servers, and services.
Application code can read values from the Blobstore in chunks that fit within these limits. Code can also query for metadata about Blobstore values. The service makes HTTP requests to other servers on the Internet, such as to retrieve pages or interact with web services.
App Engine applications can send messages using the Mail service. Show and hide more. Table of contents Product information.
Yet Getting Started 2. ISBN: Author … book Software Engineering at Google by Titus Winters, Tom Manshreck, Hyrum Wright Today, software engineers need to know not only how to program effectively but also how to … book Building Microservices, 2nd Edition by Sam Newman Distributed systems have become more fine-grained as organizations shift from code-heavy monolithic applications to smaller, self-contained … book Designing Distributed Systems by Brendan Burns Without established design patterns to guide them, developers have had to build distributed systems from scratch, ….
Get it now. New eBooks. Search Engine. Google App Engine makes it easy to create a web application that can serve millions of people as easily as serving hundreds, with minimal up-front investment.
With Programming Google App Engine, Google engineer Dan Sanderson provides practical guidance for designing and developing your application on Google's vast infrastructure, using App Engine's scalable services and simple development model.
Through clear and concise instructions, you'll learn how to get the most out of App Engine's nearly unlimited computing power. This second edition is fully updated and expanded to cover Python 2. Understand how App Engine handles web requests and executes application code Learn about new datastore features for queries and indexes, transactions, and data modeling Create, manipulate, and serve large data files with the Blobstore Use task queues to parallelize and distribute computation across the infrastructure Employ scalable services for email, instant messaging, and communicating with web services Track resource consumption, and optimize your application for speed and cost effectiveness.
Programming Google App Engine with Java.
0コメント