Tarantool中的冲突解决(在多主模式下解决复制冲突的方法)
2019-6-24 13:3:6
收藏:0
阅读:101
评论:3
我在使用Tarantool进行多主场景下的开发时,如何实现冲突解决?
我正在开发一个需要高可用性的服务,因此决定将nginx作为负载均衡器(使用backup指令)用于两个Tarantool节点(禁用只读选项)。如果请求失败,它会重试到其他节点,但在网络问题(例如Tarantool节点之间的问题)的情况下,可能会发生冲突。
我该如何实现以下场景之一:
- 在每个节点上选择较新的元组
- 自定义逻辑(可以是针对冲突的另一个空间等)
另一个问题是如何定义独特的可空复合索引(空值是可以出现多次的值)
| id | user_id | type | {some data} |
索引:
id - PK
user_id + type - 独特的可空树形索引(type可以为空)
user_id具有非唯一的树形索引
点赞
用户9141779
关于 Kostja 回答的第二点(on_ctl_init+_space:on_replace 的组合),还有一个技巧:你需要利用 box.on_commit 来获取正在创建的 space。生成的代码片段如下所示:
local my_space_name = 'ny_space'
local my_trigger = function(old, new) ... end
box.schema.on_schema_init(function()
box.space._space:on_replace(function(_, new_space)
if new_space.name == my_space_name then
box.on_commit(function()
box.space[my_space_name]:before_replace(my_trigger)
end
end
end)
end)
2019-07-11 13:09:37
用户11896037
关于2) 我遇到了问题。在我的情况下启用触发器"在创建空间时"会导致只读错误。原因是:触发器在从WAL读取时尝试 upsert 到统计表。
local function before_replace(old, new)
-- collision resolving here
if box.session.type() ~= 'applier' then
box.space.stat:upsert(
{ "key", 0 },
{
{"+", stat.COUNT, 1}
})
end
return
end
在这种情况下,我需要在读取完WAL之后才能启用触发器。并且在复制同步开始之前(否则我可能会遇到冲突或丢失统计数据)。我发现这里是合适的时间。我在 box.info.status 从 "loading" 变化后启用触发器。类似这样:
local my_space_name = 'myspace'
local function loading_before_replace(old, new)
if box.info.status == "loading" then
return
end
box.space.my_space_name:before_replace(before_replace, loading_before_replace)
return before_replace(old,new)
end
local function _space_on_replace(old, new)
if not new or not new.name then
return
end
-- skip system spaces
if string.startswith(new.name, "_") then
return
end
if new.name == my_space_name then
box.on_commit(function()
box.space.my_space_name:before_replace(loading_before_replace)
end)
end
end
local function set_triggers()
box.ctl.on_schema_init(function()
box.space._space:on_replace(_space_on_replace)
end)
end
因此,在初始WAL读取后,before_replace() 触发器将在首次提交到“myspace”时执行和启用。
也许有可能在 box.info.status 的变化时触发触发器?这可能会使代码更清晰。但我不知道这是否可行。
2019-08-07 13:50:49
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

https://www.tarantool.io/en/doc/2.1/book/box/box_space/#box-space-before-replace
https://www.tarantool.io/en/doc/2.1/book/box/box_space/#box-space-on-replace before_replace 和 on_replace 之间的区别在于 on_replace 调用了行插入 space 后,而 before_replace 在调用之前调用。
https://www.tarantool.io/en/doc/2.1/book/box/box_ctl/#lua-function.box.ctl.on_schema_init