App Engine中文教程

App Engine最新动态

关于Google App Engine的最新资讯和Google App Engine SDK的最新更新。

Google App Engine重大更新:缩小限制

发布者:Kang kang,发布时间:2009-2-13 上午7:10   [ 更新时间:2009-2-13 上午7:11 ]

Google App Engine使用了越多就越会发现,它的限制实在是烦人。比如不能使用urllib2进行request,比如request的限时为5秒,这使得我们在编程过程中需要做很多让步和改变。前几天,GAE SDK 1.1.9支持了urllib2。今天,Google App Engine小组将GAE的限制再一次提高,这让我们看到了GAE这个服务走向正式版的光辉道路。

下面说说具体的更新:

  • 不再有"High CPU Requests"! App Engine Apps 的CPU限制一直被人诟病,App Engine Group里就有人发了个测试,它的程序啥也没做,结果CPU使用超标了。现在GAE对CPU的限制几乎没有了
  • 响应时间限制提高到30 seconds. 原来限于时间限制是5秒,这个时间很苛刻,就算Google的urlfetch再牛,也可能出现不稳定的情况,5秒实在是太少了,现在改为30秒,让人感觉好些。
  • 源代码,静待文件,响应文件大小增至 10MB! App Engine apps 可以上传源代码,静态文件,并且可以用urlfecth来POST和GET文件,现在这个文件的大小限制从1MB增加到了10MB,于是可以上传中文分词的库了。

Google App Engine SDK 1.1.9发布

发布者:Kang kang,发布时间:2009-2-13 上午2:19   [ 更新时间:2009-2-13 上午2:20 ]

Google App Engine Team 在前天推出了App Engine SDK 1.1.9,下载地址。下面来看看新的SDK带来了一些什么内容:

1.重大更新:现在在GAE里面可以使用urllib

urllib2 或者 httplib 了。这就意味着,httprequest变得简单,各大网站的api可以无缝地在GAE里使用了。

2.数据上传变得简单:原来虽然有一篇关于如何上传数据到GAE的文章,但很多人都在Google Groups里面提问,说自己在上传过程中遇到了问题。现在,GAE Team将上传程序放在了App Engine SDK里面,并且写了篇更详细的Google Groups里面提问,说自己在上传过程中遇到了问题。现在,GAE Team将上传程序放在了App Engine SDK里面,并且写了篇更详细的使用说明

3.GQL语言更新:可以使用更多的操作符,如IN 和 !=。

4.修正bug

下面是来自于对Google App Engine SDK 1.1.9的观察:

在google.appengine.ext.remote_api里面,我们看到这个离线访问GAE数据的这个API,这就意味着,定时任务之类的离线应用将可以在本地完成,如果你自己有一台服务器,那么在这台服务器上运行GAE的离线任务,将成为可能。

from Google App Engine的最新更新(090212)

Google App Engine SDK Version 1.1.8发布

发布者:Kang kang,发布时间:2009-1-19 上午9:48

Google App Engine SDK Version 1.1.8发布了,下载地址为:

http://code.google.com/appengine/downloads.html

下面是Release Notes:

Google App Engine开发组解释GAE的Index是如何构建的

发布者:Kang kang,发布时间:2008-11-25 下午5:43   [ 更新时间:2008-11-25 下午5:45 ]

很多使用了Google App Engine的用户都对于Google App Engine构建Index的问题提出了质问,所以Google App Engine小组发表了一篇文章进行解释,原文如下:

How Index Building Works

Ryan Barrett
November 24, 2008

Introduction

Every App Engine datastore query is served by an index. The built-in indexes can handle simple queries, including all entities of a given kind, filters and sort orders on a single property, and equality filters on any number of properties. More complex queries, on the other hand, need custom developer-defined indexes.

Internally, we call these composite indexes, to distinguish them from the built-in kind and single property indexes. We use the word composite because their index data is composed of multiple values per index row.

When you add a new composite index to your app, it must be populated with existing data from your datastore before it can serve queries. Similarly, when you delete an index from your app, its index rows must be removed. App Engine runs an index building workflow behind the scenes that populates and deletes indexes.

This article describes how indexes are laid outhow the index building workflow works, and common questions about index building.

Index Layout

App Engine stores index data in four Bigtables, shared across all apps. The first three tables store the built-in kind, single property ascending, and single property descending indexes. The last table stores all of the composite indexes.

The index data for a given index row is stored in the Bigtable row name. This includes app id, kind, key, and extra data that varies by index. The built-in single property indexes' extra data includes the property name and value. The built-in kind index has no extra data.

Composite indexes' extra data includes the values for each property in the index definition, along with the ancestor, if specified. Property names are omitted to save space, since the index definitions themselves include the property names. However, composite index rows do include an index id, which distinguishes between index rows from different composite indexes that happen to have the same property values in the same order.

For more on index layout, see the Google I/O talk Under the Covers of the Google App Engine Datastore.

Index Building and Deleting

When you define a new index and ask us to build it, we follow these steps:

  1. Add the index definition metadata to the app.
  2. Mark the index metadata Building. This tells the datastore to update it on all writes, but to not use it for queries (yet).
  3. Map over the existing entities and populate them in the index.
  4. Mark the index Serving. This tells the datastore that the index is available for querying.

Deleting an index is almost the same process:

  1. Mark the index metadata Deleting. This tells the datastore to ignore it on both writes and queries.
  2. Remove the index's rows.
  3. Delete the index's metadata.

When an entity is created or deleted, all of the index rows for that entity must be updated. However, when an existing entity is updated, the datastore determines the delta, i.e. the properties that were changed, and only updates the index rows that include those properties.

Furthermore, the datastore handles composite indexes automatically. When an entity is put or deleted, the datastore determines the composite index rows that need updating, as above, and updates them.

Since the datastore handles index updates efficiently and automatically, the index building workflow simply reuses the datastore's code. To build or delete an index, the workflow maps over all of the app's entities, one at a time. For each entity, the workflow uses the datastore to read it and write it back, unchanged, in a transaction. The datastore detects any Building or Deleting indexes and updates the relevant index rows accordingly.

Doing Work in Parallel

The index building workflow has workers that build and delete indexes incrementally, in parallel. This allows it to build and delete indexes for different apps at the same time. It also allows for parallelizing the work of building or deleting a single app's indexes. Finally, it allows for checkpointing and resuming work if a worker dies for any reason.

The workflow maintains a central list of all apps with indexes to be built or deleted. Each app's data is split into shards. When a worker is idle, it consults this list, takes a lease on a shard of data, and maps over the entities in that shard, populating index rows as described above. If the lease expires before the worker is done, it gives up, discards the partially completed work, and the shard becomes available for other workers to retry.

We've implemented a few different mechanisms for sharding data: first by Bigtable tablet, then later within tablets. Both of these methods are explained below.

Splitting by Tablet

Surprisingly, splitting an app's entities into shards isn't easy. Ideally, the workflow would just ask Bigtable for every Nth row, starting from the app's first entity and ending at the last. Those would be the "split" points that demarcate each shard.

However, Bigtable intentionally doesn't provide such an offset operation. So, we approximated. Bigtable splits data into contiguous ranges of rows called tablets, which may be split, merged, and moved between tablet servers at runtime. Bigtable does know each tablet's start and end rows, so we started by inserting a shard for each tablet.

Unfortunately, tablets are limited only by total data size, so the number of rows (ie entities) can vary widely across tablets. The time required to populate index data varied much more by the number of properties in an entity than the size of that entity, so different tablets shards took workers drastically different amounts of time. Workers often exceeded their leases on tablets with a large number of rows, which kept indexes building or deleting for long periods of time.

Splitting Within Tablets

To address this, we recently added support for splitting large shards. When a worker notices that its lease on a shard is about to expire, it gives up working and instead splits the shard into n smaller shards. Each smaller shard includes the original shard's row range and two sharding parametersn, which is the same for all pieces, and k, which ranges from 0 to n-1.

When a worker takes on a shard that's been split with sharding parameters, it maps over all of the entities in the shard's row range, as usual. As it encounters each entity, it hashes the entity's key, and only populates indexes for that entity if the hash equals k modulo n.

An alternative design would be to populate every kth entity. This would be simpler, but might miss entities, since the app is serving during this process and could insert or delete entities.

It's worth emphasizing that a shard's row range doesn't change when it's split. Workers still scan over the entire row range. This scan is relatively cheap compared to the reads and writes required to update the indexes, though. Disk bandwidth is much cheaper than disk seeks, so Bigtable scans are much cheaper than random access reads and writes to individual rows!

FAQs

Here are some common questions about how we build and delete indexes internally. (If you're curious about how to specify indexes for your app, see our documentation.)

Q: Why do my indexes stay Building or Deleting for long periods of time? 
A: In the past, this often happened because worker shards were too large to be completed within the lease period. To address this, we first increased the lease period. Now, we split individual tablets into shards. Index building can still take some time, but it's considerably faster than it was before.

Q: Why are my indexes marked Error
A: They're probably exploding indexes. Occasionally, though, we have to move indexes into Error manually. We usually contact you directly when we do this.

Q: Why map over the app's whole datastore? Can't you use the built-in kind index to map over just the entities of the index's kind, and skip the other kinds? 
A: The transaction isolation level of individual entity reads and writes is READ COMMITTED, but indexes don't have the same guarantee. Given that, the kind index might miss some entities. See Transaction Isolation in App Engine for more details.

Q: When an index is deleted, can't you just delete its index rows directly? You could do a Bigtable prefix scan with the app id and the index id, right? Why map over the entities themselves? 
A: We wish it were that easy! The entities include metadata about the composite indexes that apply to them, so we need to update that metadata as well as deleting the index rows.

Google App Engine SDK 1.1.7发布

发布者:Kang kang,发布时间:2008-11-25 下午5:25   [ 更新时间:2008-11-25 下午5:37 ]

更新:今天早晨我们发布了SDK 1.1.7(由于1.1.6的一个问题)。SDK 1.1.7包含了这个问题的修复,以及下面所列举的修复和功能。

今天我们发布了1.1.6 SDK。你可以从我们的Google 项目托管上下载。更详细的release notes也已经发布。

这次更新带了了几个显著的功能,包括很多对于数据库存储的内容:

  • 你现在可以 sort and filter 通过一条数据记录的key。
  • 你现在可以根据一条记录的key来直接删除这条记录,而无需加载整个model。
  • 如果你在创建一个Model的时候设定了了key_name,这个key将可以在put()之前被运用。
  • URLFetch请求有了5秒的时间限制,和发布版一样了。

当然,新的SDK也包含了下面一些bug的修改:

欢迎访问Google App Engine的 Google Group进行讨论。

ghs.google.com再度被封

发布者:Kang kang,发布时间:2008-11-25 下午5:22   [ 更新时间:2008-11-25 下午5:23 ]

很多实用Google服务的人都会将自己的域名chname到ghs.google.com,无论是使用Google Apps的用户,还是使用GoogleSites的用户,亦或是Google App Engine的编程人员。

最近,ghs.google.com再次被GFW,还好,好心的人们没有彻底断掉后路,把这些服务都没有G掉,而是把绑定域名给弄掉了。可是,这对于Google的服务走向商业化更加困难,希望尽快恢复,要么把Google直接屏蔽了,要么还是开放吧~

原文地址:ghs.google.com再度被封 (转载请注明) 

Google App Engine支持HTTPS

发布者:Kang kang,发布时间:2008-11-25 下午5:16   [ 更新时间:2008-11-25 下午5:22 ]

由于很多人在Google App Engine的Groups上提出建议,希望GAE支持HTPPS,终于,昨天GAE官方发布Blog,说明现在GAE已经支持HTTPS了。

下面介绍一下用法:

* app.yaml 现在支持一个新的handler, 叫 "secure":

url: /accounts/.*
  script: admin.py
  login: admin
secure: always

*secure的属性可以设成 "always", "optional", or "never" (默认)。详细的文档:http://code.google.com/appengine/docs/configuringanapp.html#Secure_URLs

*HTTPS有自己的带宽限制,但也算在总的带宽限制里面

有关SSL的基础知识,请看:

http://en.wikipedia.org/wiki/Https#Limitations

原文地址:Google App Engine支持HTTPS (转载请注明) 

‹ 上一页    1-7/7    下一页 ›