天梯榜单的查询与写入都压在主库:结算高峰期主库 CPU 飙到 90%,普通聊天消息的落库都被拖慢。榜单读写分离封装:写入走主库、查询走只读副本,榜单场景天然容忍分钟级延迟——副本数据旧一分钟,玩家看到的名次变化晚一分钟,属于可接受范围。
双通道读写与延迟标记:写主读副、降级回落。示例代码如下:
local function writeScore(actorName, delta)
execTransaction("UPDATE arena SET score=score+" .. delta ..
" WHERE name='" .. actorName .. "'")
setsysvarex("ReplicaLag", os.time(), 1)
end
local function readRank(page)
local ok, rows = pcall(queryReplica,
"SELECT name,score FROM arena ORDER BY score DESC LIMIT 20 OFFSET " .. (page - 1) * 20)
if ok and rows then
return rows, false
end
return queryMaster("SELECT name,score FROM arena ORDER BY score DESC LIMIT 20"), true
end
local function showRank(actorName, page)
local actor = getplayerbyname(actorName)
local rows, degraded = readRank(page)
if degraded then
sendmsg(actor, 1, "榜单查询切换主库,响应稍慢。")
end
for i, r in ipairs(rows) do
sendmsg(actor, 1, (page - 1) * 20 + i .. ". " .. r.name .. " " .. r.score)
end
end
一致性敏感查询走主库示例代码如下:
local function confirmPaid(orderId)
return queryMaster("SELECT state FROM orders WHERE id=" .. orderId)
end
writeScore 全部走主库事务,写后打 ReplicaLag 时间戳标记最近一次写入时刻;readRank 的查询走 queryReplica,副本故障时 pcall 捕获回落主库并置 degraded 标记提示调用方。玩家充值确认这类强一致查询绕过副本直连主库——读写分离的前提是给"哪些查询容忍旧数据"画出明确清单,榜单在容忍清单内。
读写分离踩过三个坑:一是主从延迟实测超过预期(副本回放积压时延迟 5 分钟),玩家充了钱在副本里查不到到账,强一致查询清单没画全,充值确认这类查询必须白名单走主库;二是只读副本故障时没有回落逻辑,榜单整页报错——pcall 包裹加主库回落是底线,回落期间打告警;三是写入高峰期副本回放积压,延迟曲线跟着写入量走,写入限速与副本扩容二选一,不能让延迟无上限增长。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
一、抛坑提问:500 件掉落物要按名字即时改爆率,每次线性扫 500 项还是建一次索引?反向索引把"名字到位置"变成 O(1…
一、一行代码拆解:MIGRATE[1] = function(c) ... end —— 这一行把版本升级写成补丁链:从旧版…
一、隐蔽陷阱:给装备对象做播报,"装备" .. obj 报 attempt to concatenate a table v…
一、线上事故:守城加成函数 5 个参数,12 处调用每处传全量,一次改签名漏改 4 处,加成系数错发 2 小时。 二、底层原…
一、线上事故:掉落码含竖线与引号直接进聊天广播,被消息管道当分隔符切碎,500 条掉落码 88 条残缺,捡包脚本集体失灵。 …
一、抛坑提问:公告模板 "({name}({count}))" 括号层层嵌套,怎么在渲染前就知道它不会烂?栈式配对扫一遍字符…