GAE技巧汇总

1. 免sharding的高并发计数器.
核心思想: 采用memcached作临时存储,定期写入datastore.
incrementCounter
 1 def incrementCounter(key, update_interval=10):
 2   """Increments a memcached counter.
 3   Args:
 4     key: The key of a datastore entity that contains the counter.
 5     update_interval: Minimum interval between updates.
 6   """
 7   lock_key = "counter_lock:%s" % (key,)
 8   count_key = "counter_value:%s" % (key,)
 9   if memcache.add(lock_key, None, time=update_interval):
10     # Time to update the DB
11     count = int(memcache.get(count_key) or 0) + 1
12     def tx():
13       entity = db.get(key)
14       entity.counter += count
15       entity.put()
16     db.run_in_transaction(tx)
17     memcache.delete(count_key)
18   else:
19     # Just update memcache
20     memcache.incr(count_key, initial_value=0)


2.使用model cache给你的GAE应用程序加速
使用很简单,在你的models.py 最上方
import datastore_cache
datastore_cache.DatastoreCachingShim.Install()

3.在memcache之上构建的SessionManager.

4.全文检索(Simple Full Text Search)
测试代码的下载地址:http://github.com/DocSavage/appengine-search

Searchable
class Page(Searchable, db.Model):
  author_name 
= db.StringProperty()
  content 
= db.TextProperty()

myPage 
= Page(author_name='John Doe', content='My amazing content!')
myPage.put()
# This will enqueue indexing via Task Queue API
myPage.enqueue_indexing(url='/tasks/searchindexing')
# After index is complete, you can run searches
Page.search('search phrase')          # -> Returns Page entities
Page.search('stuff', keys_only=True)  # -> Returns Page keys

 
5.用GoogleFileService上传超过10M的大文件.(For Java)
(详细请看: http://code.google.com/p/google-file-service/)
简单地调用 DatastoreUtils.insertGoogleFile().方法就可以存入文件了.

6.脏数据保存

IsDirty
profile = Profile.get_by_key_name('someuser')
for field in ['username''password''description']:
  setattr(profile, field, self.request.get(field, getattr(profile, field))) 

profile.age 
= int(self.request.get('age'), 10)
if profile.dirty:
  db.put(profile)


#profile.put(if_dirty=True)


7.通用的翻页器(PagerQuery)

8. CSV Property

CSVProperty
class MyModel(db.Model):
    rules 
= CsvProperty(field_count=3)

new_entity 
= MyModel()
new_entity.rules 
= [('foo''bar''baz'), ('abc''def''ghi'),('my''new''property')]
new_entity.put()


9.用memcache来缓存Avatar以减少datastore的API调用.

Code
from google.appengine.ext import webappfrom google.appengine.api import memcache
import timefrom datetime 
import datetime

class AvatarHandler(webapp.RequestHandler):
    
def output_avatar(self):
        
if self.avatar is None:
            self.avatar 
= Avatar.get_by_key_name('avatar_%s' % self.u)
        
# store the last modified timestamp to the memcache
        memcache.set('avatar_%s_lastmod' % self.u,
                     int(time.mktime(self.avatar.updated.timetuple())),
                     
60*60)
        
# set the cache headers
        lastmod = self.avatar.updated
        fmt 
= '%a, %d %b %Y %H:%M:%S GMT'
        self.response.headers.update({
            
'Cache-Control''max-age=86400',
            
'Expires': (lastmod + timedelta(days=1)).strftime(fmt),
            
'Last-Modified': lastmod.strftime(fmt),
            
'Content-Type''image/png'
        })
        self.response.out.write(self.avatar.content)
    
def get(self, username):
        self.avatar 
= None
        self.u 
= username
        
# get the last modified timestamp from memcache
        # if the cache is empty (or replaced), look up it from bigtable
        lastmod = memcache.get('avatar_%s_lastmod' % self.u)
        
if lastmod is None:
            self.avatar 
= Avatar.get_by_key_name('avatar_%s' % self.u)
            lastmod 
= int(time.mktime(self.avatar.updated.timetuple()))
        
else:
            lastmod 
= int(lastmod)
        
# check if the output is necessary.
        if self.request.headers.has_key('If-Modified-Since'):
            dt 
= self.request.headers['If-Modified-Since'].split(';')[0]
            since 
= int(time.mktime(datetime.strptime(dt, '%a, %d %b %Y %H:%M:%S %Z').timetuple()))
            
if since > lastmod:
                self.response.set_status(
304)
            
else:
                self.output_avatar()
        
else:
            self.output_avatar()

 

你可能感兴趣的:(GAE技巧汇总)