読者です 読者をやめる 読者になる 読者になる

仕事中の問題と解決メモ。

最近はPythonとGoogle Cloud Platformがメイン。株式会社ビズオーシャンで企画と開発運用、データ活用とか。 http://mstdn.bizocean.co.jp/@uyamazak https://github.com/uyamazak/

リトライ間隔の重要性

この記事を読んで、定期的な同期時や、エラーからの復帰時のリトライで負荷の増大や偏りが出てしまうことを知る。自業自得のDDosって文言にちょっと釣られたけど読んでみて納得。

googlecloudplatform-japan.blogspot.jp


早速リトライ時の以下の条件でスリープ時間を変えるのをpythonで書いて、oceanusでリトライする時に使ってみた。

  • リトライの回数によって、待機時間を倍増させる
  • 待機時間にジッター(ゆらぎ)を加える
import random
from sys import exit


def retry_wait(retry_num,
               base_seconds=3,
               jitter=0.1,
               wait_seconds_limit=30):
    """
    http://googlecloudplatform-japan.blogspot.jp/2016/11/ddos-cre.html
    """
    if retry_num <= 0:
        retry_num = 1
    jitter_rate = random.uniform(1 - jitter, 1 + jitter)
    wait_seconds = base_seconds * retry_num * jitter_rate
    if wait_seconds > wait_seconds_limit:
        wait_seconds = wait_seconds_limit

    sleep(wait_seconds)

プラスマイナスのゆらぎを持たせる処理はちょっと悩んだけど、random.uniformを使って書いてみた。

random.uniform(1 - jitter, 1 + jitter)

これでjitterが0.2だったら0.8から1.2の間の乱数が出てくるので、それをベースとなる時間にかけて使う。


今回はサーバー間(Redis、BigQuery)に繋げる処理で使い、同時に動くかもしれないプロセス数は最大で10程度を想定しているけど、クライアント数が多くなるスマホアプリの場合はこういった工夫が重要になると思う。

How Google Works (ハウ・グーグル・ワークス)  ―私たちの働き方とマネジメント

How Google Works (ハウ・グーグル・ワークス) ―私たちの働き方とマネジメント