第4回まで、モデルと買い方の話を書いてきました。
今回は、その予想をどう公開しているかです。
当たった日も外れた日も全部出す。
そう決めたときに必要だったのは、意志ではなく仕組みのほうでした。
予想サイトで、いちばん簡単なごまかし
結果が出てから買い目を書き換える。
これが一番簡単で、外からも分かりにくい方法です。
当たった予想だけが残っているサイトと、本当に事前予想を当てているサイトは、完成した画面だけを見ても区別しにくい。
結局「運営者が正直に記録している」と信じるしかありません。
自分で公開運用を始めて分かったのは、これを意志の問題にすると危ないということでした。
負けが続けば、「このレースは特殊だったから集計から外そう」「これはテストだから別扱いにしよう」と言いたくなる瞬間は普通に来ます。
ならば、自分の判断で簡単に変えられないようにしておいたほうがいい。
公開した買い目は、通常処理では書き換えられない
公開済みの買い目は、データベース側で更新を拒否するようにしています。
公開後に通常の処理から内容を変更しようとしても通りません。
実際に1件書き換えようとすると、こう返ってきます。
public_bets is insert-only: a published selection cannot change
削除も同じです。
レース、公開時刻、使用したモデルの版といった予想側の情報も固定します。
あとから追加できるのは、着順や払戻など結果側の情報だけです。
朝の予想処理をやり直した場合も、元の予想を上書きしません。新しい予想として別に記録します。
前の予想もそのまま残るので、「再実行したら都合の悪い予想が消えた」ということが起きにくい構造にしています。
予想と結果の出所を分ける
もうひとつ意識したのが、予想と結果を同じ処理に持たせないことです。
予想を作る処理が、そのまま結果まで自由に書ける構成にはしませんでした。
| やること | 担当 | 出すもの |
|---|---|---|
| 予想の作成と公開 | 手元のPC | 買い目(正本) |
| 夜の確定処理 | 手元のPC | 公式データによる確定結果 |
| 昼間の速報取得 | 借りているサーバ | 速報結果だけを書いたファイル |
昼間の速報は表示を早くするためのものです。
最終的には、手元のPCで公式データを取得して確定結果として保存します。速報より確定側を優先する構造です。
1.3GBのデータベースは共有サーバに載せなかった
最初は、予想から結果取得まで全部を借りているサーバで動かそうと考えました。
すぐにやめました。
データベースが約1.31GB、モデル一式が約88MB。学習に使ったレースは約26万件あります。さらに機械学習用のライブラリも必要です。
私が使っている共有ホスティングへ、そのまま全部持っていく構成には向いていません。
一方で、終了したレースの着順と払戻を見るだけなら処理はかなり軽くできます。
そこで、昼間の結果取得だけを切り離してサーバ側に置きました。
手元のPCが止まっていても、サイト上では速報結果を更新できます。
実測では、公式の結果ページ1件を取得するのに8〜10秒程度かかりました。接続開始そのものは約0.2秒なので、待ち時間の大半は取得先からの応答です。
3本並列にすると約10.5秒で処理できたため、現在は最大3接続で動かしています。24レースならおよそ80秒です。
公式サイトを2か所から同時に取りに行かない
ここは少し気をつけました。
手元のPCとサーバの両方が同じ結果を取りに行けば、公式サイトへのアクセス回数は単純に増えます。
そこで設定を1つ用意し、どちらが速報取得を担当するか切り替えるようにしました。
両方を同時に動かさない、というルールもコード側に残しています。
取得は10分間隔、1回24レースまで、同時接続は最大3本。
ページを何度開かれても、そのたびに公式へ取りに行く構造にはしていません。
壊れ方を先に決めておく
サーバ側で動かしている処理自体は小さいものです。
その代わり、「失敗したときにどうなるか」は先に決めました。
| 起きてほしくないこと | 対策 |
|---|---|
| 書き込み途中のファイルを読ませる | 一時ファイルへ書いてから置き換える |
| 同じ処理が重なって走る | ロックを取り、取得できなければその回は終了する |
| 一部の取得失敗で過去の結果まで消える | 前回データへ成功分だけ上書きする |
| 公式HTMLの変更で誤った結果を載せる | 着順と払戻が揃わなければ未取得のままにする |
| いつから止まっているか分からない | 実行ログと最終成功時刻を残す |
| 前日の速報を今日の結果として出す | 日付が変わったら速報を引き継がない |
| 速報値が確定結果を上書きする | 手元で確定した結果を常に優先する |
実装より、環境の罠にハマった
実際にサーバへ置くと、コードそのものとは別のところで何度か詰まりました。
まず、借りているサーバでPHPがまとめてエラーになりました。
上位ディレクトリからセキュリティプラグインの設定が継承され、このサブドメインには存在しないファイルを読もうとしていたのが原因でした。
自分のディレクトリ側に設定ファイルを置き、その継承を打ち消して対応しました。
次はPHPのバージョンです。
ブラウザから動かしたときとは違い、定時実行から呼ばれる php がPHP 5.4になっていて、スクリプトが構文エラーになりました。
これは実行時に使うPHPのバージョンを明示して回避しました。
もうひとつはキャッシュです。
URLへアクセスして処理を動かす形にしたところ、サーバ側のページキャッシュに拾われました。
処理を呼んだつもりなのに実際には実行されず、前回の応答だけが返ってくる状態です。
このせいで、私は一度「定時実行が止まっている」と誤判定しました。
7分待って数字が動かなかったためですが、実際には直前に自分で処理を走らせた影響が残っていただけでした。
プログラムそのものより、「どのPHPで動いているか」「何がキャッシュされているか」のほうが原因になることもあります。
816レース、全部残す
現在公開しているのは816レース分の予想と、その結果です。
買い目は3,134点。
当たりも外れも、そのまま残しています。
もちろん管理者である以上、データベースを直接操作すれば変更そのものが物理的に不可能というわけではありません。
ただ、通常の公開処理では、結果を見てから買い目を書き換えたり消したりできないようにしています。
「やらない」だけではなく、「普段の運用では簡単にできない」状態にしておく。
そこまでやって、ようやく自分自身も集計結果を信用しやすくなりました。
次回は、その大量の予想をどう見せるかという話です。
情報を増やし続けた結果、自分がいちばん見たい数字が画面から消えました。
そこから「10秒で見終わるサイト」に作り直します。

コメント