云计算百科
云计算领域专业知识百科平台

从原子单调序号到四签名滑动窗口

从原子单调序号到四签名滑动窗口

引言

资金精确一次:迟到必须补账,重放必须拦截。迟到、重放、补发是分布式结算的日常:即时结算刚落账玩家就退出,终局二次结算姗姗来迟;网络抖动让同一笔投递两次;持久队列在故障恢复时重放历史;跨服每一跳超时都会重试。系统同时做两件矛盾事:迟到补,一分不少;重放拦,一分不多。少记是丢账,多记是多账。判重状态记住谁已处理,再来跳过——问题只剩它该长什么样。起点是单调序号,终点是只容纳四个签名的滑动窗口,切换的理由只有三条根本原因。

一、单调序号为何是第一直觉

一笔一号,只认期望:小于期望是过去,重放,丢弃;等于是当前,处理并推进;大于期望是未来,缓存等待。存储恒定,语义干净。成立前提三条:写入方唯一,无人倒带;方向不可逆,过去永为过去;清零先于写入,重置跑不到使用之后。三条全成立,序号是资产;缺一条,它就是负债。阶段去重、防抖、单次守卫都是它,在别处跑了很多年,只是不在这里。

#mermaid-svg-Hjmx2oWwFCqRjOdD{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Hjmx2oWwFCqRjOdD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Hjmx2oWwFCqRjOdD .error-icon{fill:#552222;}#mermaid-svg-Hjmx2oWwFCqRjOdD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Hjmx2oWwFCqRjOdD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Hjmx2oWwFCqRjOdD .marker.cross{stroke:#333333;}#mermaid-svg-Hjmx2oWwFCqRjOdD svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Hjmx2oWwFCqRjOdD p{margin:0;}#mermaid-svg-Hjmx2oWwFCqRjOdD .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Hjmx2oWwFCqRjOdD .cluster-label text{fill:#333;}#mermaid-svg-Hjmx2oWwFCqRjOdD .cluster-label span{color:#333;}#mermaid-svg-Hjmx2oWwFCqRjOdD .cluster-label span p{background-color:transparent;}#mermaid-svg-Hjmx2oWwFCqRjOdD .label text,#mermaid-svg-Hjmx2oWwFCqRjOdD span{fill:#333;color:#333;}#mermaid-svg-Hjmx2oWwFCqRjOdD .node rect,#mermaid-svg-Hjmx2oWwFCqRjOdD .node circle,#mermaid-svg-Hjmx2oWwFCqRjOdD .node ellipse,#mermaid-svg-Hjmx2oWwFCqRjOdD .node polygon,#mermaid-svg-Hjmx2oWwFCqRjOdD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Hjmx2oWwFCqRjOdD .rough-node .label text,#mermaid-svg-Hjmx2oWwFCqRjOdD .node .label text,#mermaid-svg-Hjmx2oWwFCqRjOdD .image-shape .label,#mermaid-svg-Hjmx2oWwFCqRjOdD .icon-shape .label{text-anchor:middle;}#mermaid-svg-Hjmx2oWwFCqRjOdD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Hjmx2oWwFCqRjOdD .rough-node .label,#mermaid-svg-Hjmx2oWwFCqRjOdD .node .label,#mermaid-svg-Hjmx2oWwFCqRjOdD .image-shape .label,#mermaid-svg-Hjmx2oWwFCqRjOdD .icon-shape .label{text-align:center;}#mermaid-svg-Hjmx2oWwFCqRjOdD .node.clickable{cursor:pointer;}#mermaid-svg-Hjmx2oWwFCqRjOdD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Hjmx2oWwFCqRjOdD .arrowheadPath{fill:#333333;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Hjmx2oWwFCqRjOdD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Hjmx2oWwFCqRjOdD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Hjmx2oWwFCqRjOdD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Hjmx2oWwFCqRjOdD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Hjmx2oWwFCqRjOdD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Hjmx2oWwFCqRjOdD .cluster text{fill:#333;}#mermaid-svg-Hjmx2oWwFCqRjOdD .cluster span{color:#333;}#mermaid-svg-Hjmx2oWwFCqRjOdD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Hjmx2oWwFCqRjOdD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Hjmx2oWwFCqRjOdD rect.text{fill:none;stroke-width:0;}#mermaid-svg-Hjmx2oWwFCqRjOdD .icon-shape,#mermaid-svg-Hjmx2oWwFCqRjOdD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Hjmx2oWwFCqRjOdD .icon-shape p,#mermaid-svg-Hjmx2oWwFCqRjOdD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Hjmx2oWwFCqRjOdD .icon-shape .label rect,#mermaid-svg-Hjmx2oWwFCqRjOdD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Hjmx2oWwFCqRjOdD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Hjmx2oWwFCqRjOdD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Hjmx2oWwFCqRjOdD :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

小于期望

等于期望

大于期望

新结算到达

序号与期望比较

过去,重放,丢弃

当前,处理并推进

未来,缓存等待

二、根本原因之一:对称性破缺

锚点的灵魂不是递增,而是回合与序号一一对应。

单次结算下每局恰好一笔:未来序号对应的对局尚未发生,不可能被处理过,未来必未处理成立;空缺只可能是丢失或延迟,等就对了,超时判丢也语义自洽——空缺不可能是本来就没有。三态完备,近乎完美。

#mermaid-svg-kuOuuGP9KxGsDWlw{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kuOuuGP9KxGsDWlw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kuOuuGP9KxGsDWlw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kuOuuGP9KxGsDWlw .error-icon{fill:#552222;}#mermaid-svg-kuOuuGP9KxGsDWlw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kuOuuGP9KxGsDWlw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kuOuuGP9KxGsDWlw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kuOuuGP9KxGsDWlw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kuOuuGP9KxGsDWlw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kuOuuGP9KxGsDWlw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kuOuuGP9KxGsDWlw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kuOuuGP9KxGsDWlw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kuOuuGP9KxGsDWlw .marker.cross{stroke:#333333;}#mermaid-svg-kuOuuGP9KxGsDWlw svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kuOuuGP9KxGsDWlw p{margin:0;}#mermaid-svg-kuOuuGP9KxGsDWlw .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-kuOuuGP9KxGsDWlw .cluster-label text{fill:#333;}#mermaid-svg-kuOuuGP9KxGsDWlw .cluster-label span{color:#333;}#mermaid-svg-kuOuuGP9KxGsDWlw .cluster-label span p{background-color:transparent;}#mermaid-svg-kuOuuGP9KxGsDWlw .label text,#mermaid-svg-kuOuuGP9KxGsDWlw span{fill:#333;color:#333;}#mermaid-svg-kuOuuGP9KxGsDWlw .node rect,#mermaid-svg-kuOuuGP9KxGsDWlw .node circle,#mermaid-svg-kuOuuGP9KxGsDWlw .node ellipse,#mermaid-svg-kuOuuGP9KxGsDWlw .node polygon,#mermaid-svg-kuOuuGP9KxGsDWlw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kuOuuGP9KxGsDWlw .rough-node .label text,#mermaid-svg-kuOuuGP9KxGsDWlw .node .label text,#mermaid-svg-kuOuuGP9KxGsDWlw .image-shape .label,#mermaid-svg-kuOuuGP9KxGsDWlw .icon-shape .label{text-anchor:middle;}#mermaid-svg-kuOuuGP9KxGsDWlw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kuOuuGP9KxGsDWlw .rough-node .label,#mermaid-svg-kuOuuGP9KxGsDWlw .node .label,#mermaid-svg-kuOuuGP9KxGsDWlw .image-shape .label,#mermaid-svg-kuOuuGP9KxGsDWlw .icon-shape .label{text-align:center;}#mermaid-svg-kuOuuGP9KxGsDWlw .node.clickable{cursor:pointer;}#mermaid-svg-kuOuuGP9KxGsDWlw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kuOuuGP9KxGsDWlw .arrowheadPath{fill:#333333;}#mermaid-svg-kuOuuGP9KxGsDWlw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kuOuuGP9KxGsDWlw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kuOuuGP9KxGsDWlw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kuOuuGP9KxGsDWlw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kuOuuGP9KxGsDWlw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kuOuuGP9KxGsDWlw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kuOuuGP9KxGsDWlw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kuOuuGP9KxGsDWlw .cluster text{fill:#333;}#mermaid-svg-kuOuuGP9KxGsDWlw .cluster span{color:#333;}#mermaid-svg-kuOuuGP9KxGsDWlw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kuOuuGP9KxGsDWlw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kuOuuGP9KxGsDWlw rect.text{fill:none;stroke-width:0;}#mermaid-svg-kuOuuGP9KxGsDWlw .icon-shape,#mermaid-svg-kuOuuGP9KxGsDWlw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kuOuuGP9KxGsDWlw .icon-shape p,#mermaid-svg-kuOuuGP9KxGsDWlw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kuOuuGP9KxGsDWlw .icon-shape .label rect,#mermaid-svg-kuOuuGP9KxGsDWlw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kuOuuGP9KxGsDWlw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kuOuuGP9KxGsDWlw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kuOuuGP9KxGsDWlw :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

多次不对称

对局一

即时

二次

对局二

笔数不定

单次对称

对局一

一笔

对局二

一笔

多次结算下每局两笔,即时加二次,对称碎成三截。一对多:序号不再编码对局结构,边界不可见,期望指针无处对齐。笔数不定:空缺可能是丢失,也可能本来就没有,等还是不等无解。超时也救不了:超时只证明等太久,证明不了不存在。跨局交错:旧局第二笔晚于新局第一笔到达,严判误杀丢账,宽判漏拦多记,按序等则跨局队头阻塞。前者序号恰是后者的前驱,后者先到被处理,前者后到即成过去,顺序本身成了陷阱。

即使同步完美,语义依然崩塌。这是语义死刑,不是工程困难。

三、根本原因之二:跨房冲突必须平衡同步

人已在新房,旧房二次结算才到:旧房即时结算,退出,新房开打,旧房二次迟到。新旧两笔流在同一玩家身上交汇,要求四立:不丢,不多,不串房,不阻塞新房。

判重新房玩家旧房判重新房玩家旧房#mermaid-svg-kDclmc10p41BJuRb{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kDclmc10p41BJuRb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kDclmc10p41BJuRb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kDclmc10p41BJuRb .error-icon{fill:#552222;}#mermaid-svg-kDclmc10p41BJuRb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kDclmc10p41BJuRb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kDclmc10p41BJuRb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kDclmc10p41BJuRb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kDclmc10p41BJuRb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kDclmc10p41BJuRb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kDclmc10p41BJuRb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kDclmc10p41BJuRb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kDclmc10p41BJuRb .marker.cross{stroke:#333333;}#mermaid-svg-kDclmc10p41BJuRb svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kDclmc10p41BJuRb p{margin:0;}#mermaid-svg-kDclmc10p41BJuRb .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kDclmc10p41BJuRb text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-kDclmc10p41BJuRb .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kDclmc10p41BJuRb .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-kDclmc10p41BJuRb .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-kDclmc10p41BJuRb .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-kDclmc10p41BJuRb #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-kDclmc10p41BJuRb .sequenceNumber{fill:white;}#mermaid-svg-kDclmc10p41BJuRb #sequencenumber{fill:#333;}#mermaid-svg-kDclmc10p41BJuRb #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-kDclmc10p41BJuRb .messageText{fill:#333;stroke:none;}#mermaid-svg-kDclmc10p41BJuRb .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kDclmc10p41BJuRb .labelText,#mermaid-svg-kDclmc10p41BJuRb .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-kDclmc10p41BJuRb .loopText,#mermaid-svg-kDclmc10p41BJuRb .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-kDclmc10p41BJuRb .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kDclmc10p41BJuRb .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-kDclmc10p41BJuRb .noteText,#mermaid-svg-kDclmc10p41BJuRb .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-kDclmc10p41BJuRb .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kDclmc10p41BJuRb .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kDclmc10p41BJuRb .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kDclmc10p41BJuRb .actorPopupMenu{position:absolute;}#mermaid-svg-kDclmc10p41BJuRb .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-kDclmc10p41BJuRb .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kDclmc10p41BJuRb .actor-man circle,#mermaid-svg-kDclmc10p41BJuRb line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-kDclmc10p41BJuRb :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}即时结算,序号为甲退出并开打即时结算,序号为乙,予以处理二次结算迟到,序号仍为甲甲小于期望,作重放丢弃,是为误杀

不处理的每一种省事都会引入新问题:直接记入,串账污染对账;丢弃,等于克扣应得;等待,等于跨局阻塞;用序号区分,旧账小号恰好撞上误杀条件。

签名解法让冲突双方不再相见:签名自带房间身份,旧账记在旧房名下,新房对账永不可见;只问处理过没有,不问大小先后,各自独立记账。窗口按相邻两局覆盖,旧房两笔加新房两笔,防护恰好包住冲突的完整跨度。二次结算可能是扣款,串房扣款直动新房资金,比多记更危险。旧房防护在新房开局后依然有效,直到被自然淘汰,全程没有一瞬失忆。

四、难听的实话:选它只因更简单

纸面优雅属于序号,一个整数对四个签名;线上复杂度也属于序号。剥开卖点只剩省内存,代价是跨方同步、对称重建、空缺裁决、交错处理,用正确性复杂度换几字节内存。内存按字节计价,事故按资金计价。何况省下的只是字节量级,欠下的是正确性量级。过度节约内存本身就是一种问题。简单是正确性的前提:维护成本最低的方案,出错概率也最低。选窗口,就是把复杂度从线上拿掉,而不是把它藏进序号里。

#mermaid-svg-ooGDo6GUM3uzx0GC{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ooGDo6GUM3uzx0GC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ooGDo6GUM3uzx0GC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ooGDo6GUM3uzx0GC .error-icon{fill:#552222;}#mermaid-svg-ooGDo6GUM3uzx0GC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ooGDo6GUM3uzx0GC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ooGDo6GUM3uzx0GC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ooGDo6GUM3uzx0GC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ooGDo6GUM3uzx0GC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ooGDo6GUM3uzx0GC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ooGDo6GUM3uzx0GC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ooGDo6GUM3uzx0GC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ooGDo6GUM3uzx0GC .marker.cross{stroke:#333333;}#mermaid-svg-ooGDo6GUM3uzx0GC svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ooGDo6GUM3uzx0GC p{margin:0;}#mermaid-svg-ooGDo6GUM3uzx0GC .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ooGDo6GUM3uzx0GC .cluster-label text{fill:#333;}#mermaid-svg-ooGDo6GUM3uzx0GC .cluster-label span{color:#333;}#mermaid-svg-ooGDo6GUM3uzx0GC .cluster-label span p{background-color:transparent;}#mermaid-svg-ooGDo6GUM3uzx0GC .label text,#mermaid-svg-ooGDo6GUM3uzx0GC span{fill:#333;color:#333;}#mermaid-svg-ooGDo6GUM3uzx0GC .node rect,#mermaid-svg-ooGDo6GUM3uzx0GC .node circle,#mermaid-svg-ooGDo6GUM3uzx0GC .node ellipse,#mermaid-svg-ooGDo6GUM3uzx0GC .node polygon,#mermaid-svg-ooGDo6GUM3uzx0GC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ooGDo6GUM3uzx0GC .rough-node .label text,#mermaid-svg-ooGDo6GUM3uzx0GC .node .label text,#mermaid-svg-ooGDo6GUM3uzx0GC .image-shape .label,#mermaid-svg-ooGDo6GUM3uzx0GC .icon-shape .label{text-anchor:middle;}#mermaid-svg-ooGDo6GUM3uzx0GC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ooGDo6GUM3uzx0GC .rough-node .label,#mermaid-svg-ooGDo6GUM3uzx0GC .node .label,#mermaid-svg-ooGDo6GUM3uzx0GC .image-shape .label,#mermaid-svg-ooGDo6GUM3uzx0GC .icon-shape .label{text-align:center;}#mermaid-svg-ooGDo6GUM3uzx0GC .node.clickable{cursor:pointer;}#mermaid-svg-ooGDo6GUM3uzx0GC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ooGDo6GUM3uzx0GC .arrowheadPath{fill:#333333;}#mermaid-svg-ooGDo6GUM3uzx0GC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ooGDo6GUM3uzx0GC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ooGDo6GUM3uzx0GC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ooGDo6GUM3uzx0GC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ooGDo6GUM3uzx0GC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ooGDo6GUM3uzx0GC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ooGDo6GUM3uzx0GC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ooGDo6GUM3uzx0GC .cluster text{fill:#333;}#mermaid-svg-ooGDo6GUM3uzx0GC .cluster span{color:#333;}#mermaid-svg-ooGDo6GUM3uzx0GC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ooGDo6GUM3uzx0GC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ooGDo6GUM3uzx0GC rect.text{fill:none;stroke-width:0;}#mermaid-svg-ooGDo6GUM3uzx0GC .icon-shape,#mermaid-svg-ooGDo6GUM3uzx0GC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ooGDo6GUM3uzx0GC .icon-shape p,#mermaid-svg-ooGDo6GUM3uzx0GC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ooGDo6GUM3uzx0GC .icon-shape .label rect,#mermaid-svg-ooGDo6GUM3uzx0GC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ooGDo6GUM3uzx0GC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ooGDo6GUM3uzx0GC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ooGDo6GUM3uzx0GC :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

需要去重

写入方唯一

签名加有界窗口

生命周期一致

跨权威域或跨局

单调序号

五、方案:签名加窗口四

签名等于房间、轮次、净额、终局四元,各端独立重算,零跨节点同步。四元各防一种混淆:房间防串房,轮次防跨局,净额与终局防同局同轮多笔互串。状态只存玩家私有,一方写入。超限只淘汰最旧一条,绝不整体清空,清空即状态遗忘。窗口等于每局两笔乘以相邻两局,等于四,最小安全值。设三,第四笔写入恰好挤掉第一笔防护;设多,只是浪费。

#mermaid-svg-CVmcy2tDtwIsNRXL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CVmcy2tDtwIsNRXL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CVmcy2tDtwIsNRXL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CVmcy2tDtwIsNRXL .error-icon{fill:#552222;}#mermaid-svg-CVmcy2tDtwIsNRXL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CVmcy2tDtwIsNRXL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CVmcy2tDtwIsNRXL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CVmcy2tDtwIsNRXL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CVmcy2tDtwIsNRXL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CVmcy2tDtwIsNRXL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CVmcy2tDtwIsNRXL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CVmcy2tDtwIsNRXL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CVmcy2tDtwIsNRXL .marker.cross{stroke:#333333;}#mermaid-svg-CVmcy2tDtwIsNRXL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CVmcy2tDtwIsNRXL p{margin:0;}#mermaid-svg-CVmcy2tDtwIsNRXL .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-CVmcy2tDtwIsNRXL .cluster-label text{fill:#333;}#mermaid-svg-CVmcy2tDtwIsNRXL .cluster-label span{color:#333;}#mermaid-svg-CVmcy2tDtwIsNRXL .cluster-label span p{background-color:transparent;}#mermaid-svg-CVmcy2tDtwIsNRXL .label text,#mermaid-svg-CVmcy2tDtwIsNRXL span{fill:#333;color:#333;}#mermaid-svg-CVmcy2tDtwIsNRXL .node rect,#mermaid-svg-CVmcy2tDtwIsNRXL .node circle,#mermaid-svg-CVmcy2tDtwIsNRXL .node ellipse,#mermaid-svg-CVmcy2tDtwIsNRXL .node polygon,#mermaid-svg-CVmcy2tDtwIsNRXL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CVmcy2tDtwIsNRXL .rough-node .label text,#mermaid-svg-CVmcy2tDtwIsNRXL .node .label text,#mermaid-svg-CVmcy2tDtwIsNRXL .image-shape .label,#mermaid-svg-CVmcy2tDtwIsNRXL .icon-shape .label{text-anchor:middle;}#mermaid-svg-CVmcy2tDtwIsNRXL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CVmcy2tDtwIsNRXL .rough-node .label,#mermaid-svg-CVmcy2tDtwIsNRXL .node .label,#mermaid-svg-CVmcy2tDtwIsNRXL .image-shape .label,#mermaid-svg-CVmcy2tDtwIsNRXL .icon-shape .label{text-align:center;}#mermaid-svg-CVmcy2tDtwIsNRXL .node.clickable{cursor:pointer;}#mermaid-svg-CVmcy2tDtwIsNRXL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CVmcy2tDtwIsNRXL .arrowheadPath{fill:#333333;}#mermaid-svg-CVmcy2tDtwIsNRXL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CVmcy2tDtwIsNRXL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CVmcy2tDtwIsNRXL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CVmcy2tDtwIsNRXL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CVmcy2tDtwIsNRXL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CVmcy2tDtwIsNRXL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CVmcy2tDtwIsNRXL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CVmcy2tDtwIsNRXL .cluster text{fill:#333;}#mermaid-svg-CVmcy2tDtwIsNRXL .cluster span{color:#333;}#mermaid-svg-CVmcy2tDtwIsNRXL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CVmcy2tDtwIsNRXL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CVmcy2tDtwIsNRXL rect.text{fill:none;stroke-width:0;}#mermaid-svg-CVmcy2tDtwIsNRXL .icon-shape,#mermaid-svg-CVmcy2tDtwIsNRXL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CVmcy2tDtwIsNRXL .icon-shape p,#mermaid-svg-CVmcy2tDtwIsNRXL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CVmcy2tDtwIsNRXL .icon-shape .label rect,#mermaid-svg-CVmcy2tDtwIsNRXL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CVmcy2tDtwIsNRXL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CVmcy2tDtwIsNRXL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CVmcy2tDtwIsNRXL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

窗内甲乙

加丙

加丁,窗满甲乙丙丁

加戊,淘汰甲

兼容:老存档怎么办

老存档是映射表,签名为键;新存档是数组,签名为元素。首键为一即数组,直接入窗;有值非一即老数据,收键归一。遍历首键行为与填充顺序无关,已实测钉死,地基若变,测试先红。

为什么不用二次结算专用变量

看似更简单的做法:给二次结算单独加个变量,记它办过没有。省事,但只省在纸面上。

复杂度一点没少:第二个变量同样需要一整条原子确认流水线,去重、重放拦截、迟到处理、与新房结算的先后关系,一个不少。原来一条流水线,现在两条;原来一组边界,现在两组,还多出一组变量之间的互斥与顺序。状态翻倍,同步点翻倍,出错面翻倍。

扩展性直接归零:如果出现第三次结算呢?再加第三个变量、第三条流水线?第几种结算配第几个变量,结构跟着业务笔数长,改一次结构,复制一次流水线。

滑动窗口把笔数从结构变成参数:多次结算只是窗里多占位置,新增一种结算,放大上限即可,四改六,一行常量。代价是多存几条字符串签名,字节量级,离庞大内存占用差着几个数量级。按类型分变量是把业务笔数硬编码进数据结构,统一窗口是把笔数变成容量参数,两种变更的维护成本不在一个量级。

六、对照

单调序号签名窗口
依赖 全网同步推进 零跨节点同步
权威源 无,多方共写 唯一,玩家私有
顺序 语义依赖顺序 与顺序无关
到达乱序 即错 天然收敛
跨局 重建归零,迁移搬运,重放倒带 签名跨局有效
失败 误杀丢账,漏拦多记 窗内两者皆无
存储 一个整数 四个签名
容量依据 两笔乘两局,可推导

七、原则

  • 幂等键自包含:能从载荷算出,就不同步计数器。
  • 判重状态单写入方:先问权威源是谁。
  • 上限用先进先出:满了清空是状态遗忘,只对纯缓存合法。
  • 数字从业务极限推导并写进注释:改数字先推翻推导。
  • 序号只用在权威域内;跨出即换签名。
  • 负向知识写进代码注释:什么路走不通,什么数字不准动。
  • 推理与断言双射:每条产品推理对应一条以上断言,先红后绿,顺序不可反。

结语

单调序号输掉的唯一原因是成立前提不存在。数的不是假设个数,是假设重量。四签名,零同步,最小的设计赢了。数字是推导式的影子:规则变则重推,推导不变则数字不准动。

赞(0)
未经允许不得转载:网硕互联帮助中心 » 从原子单调序号到四签名滑动窗口
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!