先日のGoogle App Engine SDK 1.5のリリースで処理時間に制限のないBackendsがリリースされ、さらにこれまで処理で利用したCPU時間に対して課金される仕組みが今後Instanceの起動(アサイン)時間に対して課金されるようになることが発表されました。
つまり、Instanceが1時間起動している間に100回リクエストを捌こうと10回捌こうと金額は変わらないということです。
従来であれば、cronでの最小間隔である1分間に1回処理を実行すると最初の数秒はCPU時間を消費して処理を実行して、残りの40~50秒は何もしない、イコール課金されないという方が理にかなっていました。
しかし、Instance時間になるとたとえ40~50秒間処理を行わなてもInstanceが起動されている間は常に課金されてしまいます。
そうなると、いかにCPUが働いていない40~50秒間を有効に使うか、ということが問題になります。
そこで考えたのが、無限ループです。
特定の処理を無限にループする事によって、Instanceの起動時間全てをループ内の処理に割り当てることができ、Instance時間を有効に活用することができます。
あいにく、まだInstance時間は通常のスケールするInstanceに対しては適用されませんが、BackendsではInstance時間でのQuotaの計算がされています。
将来的な変化に慣れるためにもちょっと実装してみました。
今回ははじめてFlaskというフレームワークを使って書いてみました。
これです。
==========ここから==========
@app.route('/')
def put_queue():
taskqueue.add(url=url_for('work'),target='test')
return 'Done'
@app.route('/work',methods=['POST'])
def work():
for var in range(3600):
now = datetime.datetime.now() + datetime.timedelta(hours=9)
str_now = datetime.datetime.strftime(now,'%Y%m%d%H%M%S')
logging.info(str_now)
key = 'SPOTS:'+str_now
logging.info(key)
rate = GetCurrentRate()
logging.info(str(rate))
SPOTS(key_name=key
,update=now
,USDJPY = rate['USDJPY']
,EURJPY = rate['EURJPY']
,EURUSD = rate['EURUSD']
,AUDJPY = rate['AUDJPY']
,GBPJPY = rate['GBPJPY']
,NZDJPY = rate['NZDJPY']
,CADJPY = rate['CADJPY']
,CHFJPY = rate['CHFJPY']
,HKDJPY = rate['HKDJPY']
,GBPUSD = rate['GBPUSD']
,USDCHF = rate['USDCHF']
,ZARJPY = rate['ZARJPY']).put_with_cache(key_name=key)
time.sleep(0.7)
return 'Done'
==========ここまで==========
簡単なもんです。
まず、通常のcronでput_queue()を叩きます。
次にBackends側でTaskQueueのTaskを受け取り(POST)、3600回繰り返し実行します。
ループの中では為替レートの取得、DataStoreへのput()を行っています。
ログで見る限り、DataStoreへのput()にかかるCPU時間が400~600ms程度。
そこにtime.sleep(0.7)で0.7秒=700msの待ちを加えて約1000~1300ms間隔で実行します。
DataStoreを見るとループ1回で実質1.1秒程度かかっていて、ちょうど1秒間隔の為替レートが取得できています。
上記実行回数(3600回)を考えればもうお分かりのように、1時間に1回cronでput_queue()を叩いてやるように設定してやるだけです。
これでBackendsでの無限ループ処理を簡単に実装できますね。
つまり、Instanceが1時間起動している間に100回リクエストを捌こうと10回捌こうと金額は変わらないということです。
従来であれば、cronでの最小間隔である1分間に1回処理を実行すると最初の数秒はCPU時間を消費して処理を実行して、残りの40~50秒は何もしない、イコール課金されないという方が理にかなっていました。
しかし、Instance時間になるとたとえ40~50秒間処理を行わなてもInstanceが起動されている間は常に課金されてしまいます。
そうなると、いかにCPUが働いていない40~50秒間を有効に使うか、ということが問題になります。
そこで考えたのが、無限ループです。
特定の処理を無限にループする事によって、Instanceの起動時間全てをループ内の処理に割り当てることができ、Instance時間を有効に活用することができます。
あいにく、まだInstance時間は通常のスケールするInstanceに対しては適用されませんが、BackendsではInstance時間でのQuotaの計算がされています。
将来的な変化に慣れるためにもちょっと実装してみました。
今回ははじめてFlaskというフレームワークを使って書いてみました。
これです。
==========ここから==========
@app.route('/')
def put_queue():
taskqueue.add(url=url_for('work'),target='test')
return 'Done'
@app.route('/work',methods=['POST'])
def work():
for var in range(3600):
now = datetime.datetime.now() + datetime.timedelta(hours=9)
str_now = datetime.datetime.strftime(now,'%Y%m%d%H%M%S')
logging.info(str_now)
key = 'SPOTS:'+str_now
logging.info(key)
rate = GetCurrentRate()
logging.info(str(rate))
SPOTS(key_name=key
,update=now
,USDJPY = rate['USDJPY']
,EURJPY = rate['EURJPY']
,EURUSD = rate['EURUSD']
,AUDJPY = rate['AUDJPY']
,GBPJPY = rate['GBPJPY']
,NZDJPY = rate['NZDJPY']
,CADJPY = rate['CADJPY']
,CHFJPY = rate['CHFJPY']
,HKDJPY = rate['HKDJPY']
,GBPUSD = rate['GBPUSD']
,USDCHF = rate['USDCHF']
,ZARJPY = rate['ZARJPY']).put_with_cache(key_name=key)
time.sleep(0.7)
return 'Done'
==========ここまで==========
簡単なもんです。
まず、通常のcronでput_queue()を叩きます。
次にBackends側でTaskQueueのTaskを受け取り(POST)、3600回繰り返し実行します。
ループの中では為替レートの取得、DataStoreへのput()を行っています。
ログで見る限り、DataStoreへのput()にかかるCPU時間が400~600ms程度。
そこにtime.sleep(0.7)で0.7秒=700msの待ちを加えて約1000~1300ms間隔で実行します。
DataStoreを見るとループ1回で実質1.1秒程度かかっていて、ちょうど1秒間隔の為替レートが取得できています。
上記実行回数(3600回)を考えればもうお分かりのように、1時間に1回cronでput_queue()を叩いてやるように設定してやるだけです。
これでBackendsでの無限ループ処理を簡単に実装できますね。
コメント
コメントを投稿