from http://googleappengine.blogspot.com/2008/04/posted-by-ken-ashcraft-software.html
Posted by Ken Ashcraft, Software Engineer
Google App Engine makes writing scalable apps easier, and a
well-designed app should be able to grow automatically from one user to
millions. What does it mean for a Google App Engine application to be
"well-designed," though? Here are a few simple tips that, if you design
with them in mind, should help ensure your App will stand up with grace
and aplomb, even under heavy load.
- Avoid contention on datastore entities.
If every
request to your app reads or writes a particular entity, latency will
increase as your traffic goes up because reads and writes on a given
entity are sequential. One example construct you should avoid at all
costs is the gobal counter, i.e. an entity that keeps track of a count
and is updated or read on every request. There are some interesting
ways of simulating this behavior that don't require reads/writes on
every request, and we'll talk about a handy way to cache entities for
reads below.
- Avoid large entity groups
.
Any two entities that share a common ancestor belong to the same entity
groups. All writes to an entity group are sequential, so large entity
groups can bog down popular apps quickly if there are a lot of writes
to that group. Instead, use small, localized groups in your design.
- Write sparingly.
Writes are more expensive than
reads; keep this in mind when designing your data model. If you can
avoid a write--it's best to do so.
- Define a
main()
function for code reuse.
Instances of your app are kept running for a certain period after each
request, so there's a chance that any request will hit an
already-running app. Apps that define main
as in the following example:
def main():
application = webapp.WSGIApplication(_URLS, debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
can reuse global variables, so although there's
no guarantee that any given request will hit a running app instance,
you can take advantage of this to non-deterministically cache entities
and other expensive values. This works simply because App Engine will
detect if main()
is present in an already-loaded script and call it instead of re-importing.
- Profile your code
.
You can use the Python profiler to profile your code's performance.
Do you have tips for scaling web apps on App Engine? Post them in our Google Group
!