2021年9月18日土曜日

[ブラ三] ゼロストップについてダラダラと

出兵処理などのカウントダウンが「あと00:00:00」で止まったままで即時処理されず、
数十秒~数分かかって処理される、いわゆるゼロストップという現象が最近多くなってきました。
 
古くは盟主攻略時など、瞬間的に火力を集中した際によく起きていた現象ですが
最近はごくごく日常の光景になってきましたw
争覇などはその最たるものですね。
 
これ、何故どのように起きているかご存知でしょうか。
わからない方、興味ある方に向けて解説します。
 
まずブラウザ三国志の基本的な仕様ですが
攻撃やら施設作成といった処理はどのように管理/処理されているのかというと
ワールドに1つだけあるハッシュテーブルで管理/処理されています。
ワールドに1つなのでワールドハッシュと呼称しましょうか。
ハッシュ(テーブル)というのはキーに対して値がある構造です。
ワールドハッシュのキーには年月日時分秒が格納されています。
キーに対応する値は、その年月日時分秒に処理する処理内容がキュー形式で収められています。


ワールドハッシュの内容を例示するとこんなかんじ。

2021/02/04 20:00:01

①鹵獲着弾 プレイヤーA カードID:1000001 座標:(100,100)

②攻撃着弾 プレイヤーB カードID:2345678 座標:(123,123)

③自動鹵獲着弾 プレイヤーC カードID:xxxxxxx 座標:(1200,1200)

④造兵完了 プレイヤーD 拠点ID:xxxxxxx 重盾 65000

⑤援軍着弾 プレイヤーE カードID:xxxxxxx 双剣 50000 座標:(123,123)

⑥領地保護期間終了 座標:(256,256)

⑦拠点完成 座標:(500,500)

⑧鹵獲帰還 プレイヤーF カードID:1234567 座標:(456,456)

⑨施設削除完了 拠点ID:xxxxxxx 拠点内座標:(1,1)

⑩攻撃着弾 プレイヤーX カードID:xxxxxxx 座標:(123,123)
2021/02/04 20:00:02

⑪攻撃着弾 プレイヤーX カードID:xxxxxxx 座標:(nnn,nnn)

⑫攻撃着弾 プレイヤーX カードID:xxxxxxx 座標:(nnn,nnn)

・・・

 

例えば、プレイヤーAさんが19時55分にカードID:1000001で座標(100,100)に鹵獲を
出したとします。着弾までは5分と1秒かかるものとします。
その場合、鹵獲の出兵ボタンを押した瞬間に、19時55分+5分1秒=20時0分1秒のキューに
①の処理が追加されます。
 
そして時間が経過しワールドの時刻が20時0分1秒に到達した時、
ワールドハッシュを処理するプロセスはワールド時刻「2021/02/04 20:00:01」をキーに
処理内容を詰め込んだキューを取得し、キューの先頭から順に結果を計算していきます。
①→②→・・・→⑩といった順番ですね。
キューの順番は大事です。
同秒着弾でも車が先に着弾するか殲滅が先に着弾するかで結果が大きく違うのはご存知のとおりですね。
 
さてこの処理なのですが、では2021/02/04 20:00:02になったら⑪、⑫の処理が行われるかというと、そうとも限りません。
2021/02/04 20:00:02になっても2021/02/04 20:00:01のキーに対するキューが消化しきれていない場合、前のキューが完了するまで待って処理することになります。
これがいわゆるゼロストップという現象です。
ゼロストップは単位時間当たりにサーバが処理可能な処理数を超えてキューに処理が乗っているときに起こります。 
 
さて、処理内容のキューについて、デッキアップなどの要素がない点について疑問に持たれた方もいると思います。
これは書き忘れた訳でも端折ったわけでもなく、ワールドハッシュに乗らない行為だからです。
デッキアップ/ダウンは武将が拠点にいる/いなくなる結果を引き起こすので本来はワールドハッシュに乗せるべき処理です。
(全軍や守護◯陣などを考えると重要性もあいまってわかりやすいと思います)
ですが、デッキアップ/ダウンまでワールドハッシュに乗せて厳密に順番を意識して処理するとデッキ画面の表示が馬鹿遅くなりゲームに支障をきたすので、ワールドハッシュを介さない即時処理にしてあるのですね。
0ストップ時でもデッキ画面の表示がサクサク出来るのはこの仕様のためです。
 
同様にデッキアップによる差し込みもこの仕様があってのことです。
上の例で②が大砲で⑩が車の場合、②で殲滅されても③~⑨を処理している間にデッキにあげる操作をしてサーバ側で処理を受付&処理完了出来れば、
⑩を処理するタイミングで武将があがっていて、車を壊すことが出来るという寸法です。
ちなみに受付けただけでなく処理完了まで出来ていないとダメというのがミソです。
この受付~処理完了のタイムラグがあるため、デッキアップは安定しないのですね。

 
全軍についても補足しておきますか。
あなたは大砲を撃ちましたが、着弾時間を過ぎてもゼロストップしています。
このとき全軍を下ろしていいかどうか?ですが、仕組みを考えれば下ろしてはいけません。
ゼロストップ中はまだ処理が完了していません。全軍がデッキにあがっているかの判定は
攻撃出兵を解決するその瞬間におこなわれるので、下ろしてしまうと全軍が計算に乗ってくれません。
もちろんデッキから下ろして、なにか他のこと(神医など)をして再度上げて、その後に攻撃出兵が解決されればもちろん有効ですが、少しギャンブルですねw
ちなみに神医などの発動即終了スキルはハッシュに乗らないので即時反映となります。(なるはずw)
ハッシュに乗るか乗らないかの見分け方は、カウントダウンが表示されるか否かがわかりやすい指標となります。
 
 
なんだか話が逸れましたが、ゼロストップは単位時間当たりの処理可能量を超えてキューに処理が積まれたときに起こるということは理解して頂けたと思います。
 
じゃあ処理可能量を超えてキューに処理が積まれやすい時間帯=ゴールデンタイムは
さぞかしゼロストップが多いだろうと推測されます。
確かに体感的には明け方よりも、夕飯時くらいの方が重い気はします。
というわけでw1サーバ全体の出兵数を時間帯ごとに調べてみました。
 
時間帯平均出兵数
016947
116816
216220
315551
414971
514921
615108
715683
816005
916102
1016430
1116713
1216318
1315766
1415634
1515071
1615026
1714989
1814855
1914855
2014724
2115321
2215804
2316129
 
計測は2021/9/12~9/18で実施しました。
思ったより数のバラツキがないのですね~。意外。
ということは推測になりますが 、出兵の多くを自動鹵獲が占めていると推測されます。
となると17時~20時台が少ないのは自動鹵獲を切って、貯めた資源でなんやかやしているのだと思われます。(南蛮など)
ただ体感ではやはりゴールデンタイムが重いので、処理数の多寡だけがゼロストップを引き起こすわけではないことが推測されます。
同じ1処理でも粒の大小があるわけですね。単なる武将単騎による賊討伐の1処理と100の援軍を集めて行う南蛮の1処理ではそりゃあ集めるデータ量、計算量も違うというわけですね。
 
上記結果や争覇で自動鹵獲にウェイトをかけたことを鑑みると
自動鹵獲については現状のワールドハッシュと切り離した新たな仕様で再設計したほうが良いのではないかと思います。
通常マップで鹵獲させるから同様に処理せねばならないわけで、自動鹵獲専用のマップ
(マップすら持たなくてもよいかも。距離と土地タイプの指定だけでok)に鹵獲させるなら
別のハッシュでパラレルに処理することが可能ですよね。
上記は一案ですが、なにかいい手を考えて頂ければなーと思います。
 

それでは今日はこのへんで。