同時実行の枠を増やす前に見るもの:2 コアのサーバーで、枠を 8 から 14 にした判断と、半分間違っていた前の結論
トレカダッシュ 開発の記録 / 2026年9月
iOS アプリ「トレカダッシュ」の裏側は、1 台の小さなサーバー(2 コア、メモリ 3.8GB)で、200 を超える定期処理を動かしています。同時に走れる処理の数には、上限があります(同時実行の枠)。
2026 年 9 月 7 日、先着の監視を速くしようとして、処理の間隔を詰めたところ、いちばん速く見たい監視が、枠の順番待ちで遅くなりました。そこで枠を 8 から 11、さらに 14 に増やしました。この記事は、その判断と、判断を分けた「見るもの」の記録です。
数字は、2026 年 9 月 7 日の作業の記録から書いています。
枠が 8 では、足りなかった
先着の反応を上げるために、いくつかの処理の間隔を詰めました。すると、1 分おきの「瞬殺監視」(在庫が数分で消える先着を見る処理)が、見送られるようになりました。同時実行の枠 8 が、いっぱいになったからです。
| 枠 8(詰めた後) | 枠 11 | |
|---|---|---|
| 順番待ちの数 | 17〜29 | 0 |
| 同時に走っている数 | 8 で張り付き | 6 / 11(余裕あり) |
| 瞬殺監視の見送り | 6 回 / 10 分 | 1 回 / 10 分 |
| 負荷(load average) | 1.62 | 1.24 |
| メモリの使用 | 1,161MB | 667MB |
枠を 11 に増やすと、待ちは 0 になり、負荷もメモリも、むしろ下がりました。処理のほとんどは、通信の返事を待っているだけで、CPU を使っていません。上限は、CPU ではなく、枠だったのです。
ここで、枠の値は、サーバーの設定ファイル(runner.env)にだけ書かれていて、git(コードの履歴)には入りません。配備用のスクリプトが、このファイルを送らないからです。リポジトリを見ても、この変更は分かりません。作り直すときに忘れないよう、記録に残し、元の値の控えも作りました。
「2 コアだから、これ以上は無理」は、半分間違いだった
その後、人気の弾を速く回す枠と、最速で見る枠を足しました。すると、同時実行は 11 で張り付き、待ちが 15 件まで伸びて、瞬殺監視が 2 回見送られました(実質の間隔が 1.0 分から 1.4 分)。
調べると、こうでした。
- CPU は 2 コア。負荷は 1.66 で、2 コアの 83%。
- 楽天系の長い処理は、楽天の API の「1.5 秒待ち」で、枠を握ったまま眠っている。在庫の再検証 240 秒、楽天市場 181 秒、新規出品 110 秒、在庫 104 秒。
- CPU は使っていないのに、枠だけを消費する。いちばん見えにくい犯人でした。
このときは、「2 コアだから、枠を広げても全部が遅くなるだけ」と判断して、楽天の人気枠の頻度を減らしました。
| 足した後 | 減らした後 | |
|---|---|---|
| 同時実行 | 11 に張り付き | 9〜11 |
| 順番待ち | 最大 15 | 0〜1 |
| 瞬殺監視の見送り | 2 回 / 10 分 | 0 回 |
| 瞬殺監視の実質の間隔 | 1.4 分 | 1.0 分 |
| 負荷 | 1.66 | 1.25 |
ところが、その後、この判断が半分間違いだったと分かりました。枠を握っている楽天系の処理は、API の 1.5 秒待ちで眠っているだけで、CPU を使っていません。枠を増やしても、「同時に眠れる数」が増えるだけで、CPU の取り合いにはなりません。枠を 11 から 14 にして測り直しました。
| 枠 11 | 枠 14 | |
|---|---|---|
| 瞬殺監視の見送り | 1 回 / 5 分 | 0 回 / 6.7 分 |
| 瞬殺監視の実質の間隔 | 1.3 分 | 1.0 分 |
| 負荷 | 1.25 | 1.25(変わらず) |
判断を分けるのは、「CPU を使うか、待っているか」
枠を増やしてよいかは、処理がCPU を使うのか、待っているのかで決まります。
- 待っている処理が枠を握っているなら、枠を増やしてよい。負荷(
uptime)が上がらないことを確かめる。 - CPU を使う処理が枠を握っているなら、増やすと全部が遅くなる。
見る場所は 2 つです。順番待ちの数(ヘルスチェックの queued)が、いつも 1 以上なら、空きがありません。もう 1 つは、処理ごとの平均の所要秒数を、長い順に並べることです。楽天の API を使う長い処理が上位に並んでいたら、それが枠を握って眠っている犯人です。
この日だけで、同じ形の回帰を4 回出しました。Amazon の 5 分おき、あみあみの 5 分おき、楽天の人気枠のまとめ回し、楽天の人気枠の 10 分おき。速くしたつもりが、枠を食って、いちばん速く見たいものを遅くしました。
分かったこと
枠は、数を数えるのではなく、握っているものを見る。
- 「1 回の所要時間 ≧ 間隔」の処理は、枠を占有する。速くするほど、ほかが待ちます。
- 上限の正体を、測る。CPU なのか、枠なのか。負荷とメモリを見ます。
- 前の結論が、半分間違っていることがある。「2 コアだから無理」は、待ちの処理には当てはまりませんでした。
- gitに入らない設定は、記録に残す。サーバーにだけある値は、リポジトリを見ても分かりません。
- 速くするなら、何かを遅くする。どれを守るかを、先に決めます。
この話に出てくるもの
- トレカダッシュ — トレカの抽選・予約・先着の情報を集める iPhone アプリ
- 「1 分おき」の監視は、1 件あたり 10 分に 1 回だった — 同じ日の、見直しの間隔の話
- 配備のたびに、日次の処理が丸ごと走り直していた — 同じ「定期処理」の別の失敗
ほかの記録
- 競合サイトと突き合わせて、取りこぼしを数えた:最初の「カバー率 23%」は測り方の間違いで、本当は 49% だった — 他のサイトが出している抽選を、こちらが出せているかを数えた。最初の 23% は、商品名の書き方の違いと期限切れの記事で歪んでいた。直して 49%、穴埋めの 5 つの問題を直して 90% に。規約で自動取得が禁止のサイトは取り込まなかった。
- 自分で作った仕組みが、自分を傷つけた 4 つの記録:要約が条件を捨て、1 つの未定義が保存を止め、点検が本番の IP を閉め出された — 「15 文字程度」の指示で応募の条件が 671 件の点検で抜けていた、undefined が 1 つで保存が全部失敗し 1 日の消費の 41% を溶かした、点検の 6 並列で本番と同じ IP が拒否された、直っても鳴り続ける警告を作った。
- X 監視の漏れ 4 つ:検索に出ない投稿、持ち主が変わるアカウント、店を探せない検索、止まった後の取り戻し — 店の X 投稿を巡回する監視で、4 店の告知が検索に 751 件取っても出なかった、登録した店が個人になっていた、店の発掘が 63 店中 11 店だった、6 日止まった後 2 時間で 2,866 件中 185 件しか読めなかった。直し方と、費用の見積もり。
コメント
感想や、記事の間違いの指摘は、ここへ。書くには、GitHub のアカウントが要ります。
押すと、giscus(giscus.app)と GitHub に接続します。押さなければ、接続しません。詳しくはあつかいに書いています。