私たちは現在、「外部ID」(facebook idなど)を分析に役立つすべてのサービスに固有の「内部(uu)ID」にマッピングする、小型でシンプルな中央HTTPサービスを構築しています。GAE/NDBからどのような応答時間が期待できますか?
"私たちのスタック"(フラスコ+ postgresql)の最初のプロトタイプは1日以内に完了しました。しかし、サービスが(ほぼ)決して失敗することはなく、自動的に拡大することを望んでいるので、Google App Engineを使用することに決めました。この質問をベンチマーク&をしようと&を読み取る週間後
が出てくる:(NDB付き)のApp Engine上で「ノーマル」と考えられている何の応答時間
?
我々はよく90percentile内の1以上の平均とに一貫上記の500msである応答時間を得ています。
私は、誰かが明白な欠陥を指摘できることを願って、下記のコードを削除しました。私たちは本当にオートスケーリングと分散ストレージが好きですが、私たちのケースでは500msが実際に期待される性能であるとは想像できません。 SQLベースのプロトタイプは、高速で(一貫して)、無料のキャッシュレスpostgresql(ORMの場合でも)を使用して、1つのHeroku dynoでホストされました。
以下のコードの同期型と非同期型の両方を試し、appstatsプロファイルを見ました。非常に長い(50ms〜100ms)RPC呼び出し(常にmemcacheとdatastoreの両方)は、複数の呼び出し(たとえばmc.get()+ ds.get()+ ds.set )を書く)。また、タスクキューにできるだけ多くの遅延をかけずに、試行待ちにしました。私の経験では、完全性期すため
import json
import uuid
from google.appengine.ext import ndb
import webapp2
from webapp2_extras.routes import RedirectRoute
def _parse_request(request):
if request.content_type == 'application/json':
try:
body_json = json.loads(request.body)
provider_name = body_json.get('provider_name', None)
provider_user_id = body_json.get('provider_user_id', None)
except ValueError:
return webapp2.abort(400, detail='invalid json')
else:
provider_name = request.params.get('provider_name', None)
provider_user_id = request.params.get('provider_user_id', None)
return provider_name, provider_user_id
class Provider(ndb.Model):
name = ndb.StringProperty(required=True)
class Identity(ndb.Model):
user = ndb.KeyProperty(kind='GlobalUser')
class GlobalUser(ndb.Model):
uuid = ndb.StringProperty(required=True)
@property
def identities(self):
return Identity.query(Identity.user==self.key).fetch()
class ResolveHandler(webapp2.RequestHandler):
@ndb.toplevel
def post(self):
provider_name, provider_user_id = _parse_request(self.request)
if not provider_name or not provider_user_id:
return self.abort(400, detail='missing provider_name and/or provider_user_id')
identity = ndb.Key(Provider, provider_name, Identity, provider_user_id).get()
if identity:
user_uuid = identity.user.id()
else:
user_uuid = uuid.uuid4().hex
GlobalUser(
id=user_uuid,
uuid=user_uuid
).put_async()
Identity(
parent=ndb.Key(Provider, provider_name),
id=provider_user_id,
user=ndb.Key(GlobalUser, user_uuid)
).put_async()
return webapp2.Response(
status='200 OK',
content_type='application/json',
body = json.dumps({
'provider_name' : provider_name,
'provider_user_id' : provider_user_id,
'uuid' : user_uuid
})
)
app = webapp2.WSGIApplication([
RedirectRoute('/v1/resolve', ResolveHandler, 'resolve', strict_slash=True)
], debug=False)
(ほぼデフォルト)app.yamlを
application: GAE_APP_IDENTIFIER
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: .*
script: main.app
libraries:
- name: webapp2
version: 2.5.2
- name: webob
version: 1.2.3
inbound_services:
- warmup
Yepp、あなたはdev_appserverのパフォーマンス(ssdのsqlite ...)について正しいので、私たちは実稼働環境(payed account even)でテストします。反復については、通常、約5分間テストを実行します。私たちはまた、各実行に匹敵する量のヒット/ミスがあることを確認しようとします(実行間のデータストア/ memcacheを空にするか、 'provider_user_id'の範囲内で再生することによって)。 – selkie
注:大きなベンチマークを実行している場合は、トラフィックを徐々に(例えば5〜10分)スピンアップし、しばらく(5〜10分)持続させて現実的な効果を測定する必要があります。 App Engineは、負荷が0から100になるとすぐに必要なインスタンスをスピンアップしません。不安定さを避けるためにこのプロセスに「ガバナ」があります。 –
私は、HRDの "1エンティティグループあたり1回の書き込み"動作について読みました。上のコードでは、彼が私たちの問題を説明しないでしょうか?少数のプロバイダ(主にFacebook)があり、_Identity_は_Provider_を親として持っていて、それを_entity group_にしていますか? – selkie