GAE数据库压力测试
2009 11 25 02:15 PM 1917次查看
分类:Google App Engine 标签:Google App Engine, Python
用的方法是产生大量异步Urlfetch,然后看响应时间和数据库时间。
测试的这个模型有约32万个实体,27M空间(含索引),每个实体只有一个字符串属性。
因为测试结果波动较大,我就不列出了,只给出结论:
异步Urlfetch的时间影响很小,每个约0.1ms,所以基本不对测试造成影响。
直接返回一个'0',在10秒内约可支持1600多个并发。1600个共用7.92秒,平均每个请求4.95ms。
插入1个实体,在10秒内约可支持1100多个并发。1000个共用9.60秒,平均每个请求9.60ms。数据库API时间为47.68秒。
查询10个实体(一般查询量都比较大),在10秒内约可支持1000个并发。1000个共用10.05秒,完成990个,平均每个请求10.2ms。数据库API时间为60.14秒。
更新1个实体,在10秒内约可支持200个并发。200个共用9.15秒,完成198个,平均每个请求46.2ms。数据库API时间为27.50秒。
删除1个实体,在10秒内约可支持200个并发。200个共用8.10秒,平均每个请求40.5ms。数据库API时间为29.90秒。
可以看出,插入的效率很高,可能是因为只需要在一台服务器插入,复制所需时间不计算在内;而更新和删除需要保证所有备份的一致性,同步需要一些时间。
从查询的效率来看,并发大概在100个/秒左右。按一个论坛平均每个页面4次查询来计算,每人每分钟浏览2个网页,约可以支撑1500人同时在线。
这个速度有点差强人意了…要知道Discuz!和PHPWind可是用MySQL支持数万人同时在线的。
服务器端测试代码:
from random import random
from time import time
from wsgiref.handlers import CGIHandler
from google.appengine.api import apiproxy_stub_map
from google.appengine.ext import webapp
from google.appengine.ext import db
result = [0, 0]
def before_db(service, call, request, response):
result[0] = time()
def after_db(service, call, request, response):
result[1] = time()
apiproxy_stub_map.apiproxy.GetPreCallHooks().Append('before_db', before_db, 'datastore_v3')
apiproxy_stub_map.apiproxy.GetPostCallHooks().Push('after_db', after_db, 'datastore_v3')
class TestModel(db.Model):
content = db.StringProperty()
class Nothing(webapp.RequestHandler):
def get(self):
self.response.out.write('0')
class Add(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
size = int(self.request.get('size'))
if size < 1:
raise Exception
entities = []
for i in xrange(size):
entity = TestModel(content=`random()`)
entities.append(entity)
db.put(entities)
self.response.out.write(`result[1] - result[0]`)
class Fetch(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
size = int(self.request.get('size'))
if size < 1:
raise Exception
entities = TestModel.all().fetch(size)
assert len(entities) == size
self.response.out.write(`result[1] - result[0]`)
class Update(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
size = int(self.request.get('size'))
if size < 1:
raise Exception
entities = TestModel.all().fetch(size)
assert len(entities) == size
for entity in entities:
entity.content = `random()`
db.put(entities)
self.response.out.write(`result[1] - result[0]`)
class Del(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
size = int(self.request.get('size'))
if size < 1:
raise Exception
entities = TestModel.all(keys_only=True).fetch(size)
assert len(entities) == size
db.delete(entities)
self.response.out.write(`result[1] - result[0]`)
application = webapp.WSGIApplication([('/test/nothing', Nothing),
('/test/add', Add),
('/test/fetch', Fetch),
('/test/update', Update),
('/test/del', Del)])
def main():
CGIHandler().run(application)
if __name__ == '__main__':
main()
控制台测试代码:from google.appengine.api import urlfetch
from time import time
result = []
def handle_result(rpc):
def handle():
try:
result.append(float(rpc.get_result().content))
except:
pass
return handle
rpcs = []
t = time()
for i in xrange(1000):
rpc = urlfetch.create_rpc(deadline=10)
rpc.callback = handle_result(rpc)
urlfetch.make_fetch_call(rpc, 'http://你的应用程序地址/test/fetch?size=10') # 这里的URL按需要更改
rpcs.append(rpc)
t2 = time()
for rpc in rpcs:
rpc.wait()
t3 = time()
print t2 - t
print t3 - t
s = sum(result)
l = len(result)
print s
print l
print s / l
0条评论 你不来一发么↓