From a63653544afafe4b9d8c1a57cc3e640abbbba55c Mon Sep 17 00:00:00 2001 From: Eugene Paniot Date: Tue, 10 Jan 2023 13:03:18 +0000 Subject: [PATCH 1/4] Add callro methods based on node zone --- vshard/replicaset.lua | 28 +++++++++++++++++++++++++++- vshard/router/init.lua | 16 +++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/vshard/replicaset.lua b/vshard/replicaset.lua index 7f27f06c..359fa202 100644 --- a/vshard/replicaset.lua +++ b/vshard/replicaset.lua @@ -577,13 +577,35 @@ local function replicaset_template_multicallro(prefer_replica, balance) local function pick_next_replica(replicaset, now) local r local master = replicaset.master + if balance then + local prefered_zone = replicaset.priority_list[1].zone local i = #replicaset.priority_list while i > 0 do r = replicaset_balance_replica(replicaset) i = i - 1 if r:is_connected() and (not prefer_replica or r ~= master) and - replica_check_backoff(r, now) then + replica_check_backoff(r, now) + then + -- Pick a replica according prefered zone (highest priority replica zone) in round-robin manner. + if balance == 2 and prefered_zone then + -- save current rr-cursor position + local cbi = replicaset.balance_i + -- find next replica + local nr = replicaset_balance_replica(replicaset) + + if prefered_zone and r.zone and r.zone == prefered_zone -- current replica is in prefered_zone + and nr.zone and nr.zone ~= prefered_zone -- next replica is from different zone (reached prefered_zone replicas) + and (not prefer_replica or nr ~= master) + then + -- reset cursor to the main position + replicaset.balance_i = 1 + else + -- restore rr-cursor position + replicaset.balance_i = cbi + end + end + return r end end @@ -637,6 +659,7 @@ local function replicaset_template_multicallro(prefer_replica, balance) end end opts.timeout = timeout + net_status, storage_status, retval, err = replica_call(replica, func, args, opts) now = fiber_clock() @@ -990,8 +1013,10 @@ local replicaset_mt = { callrw = replicaset_master_call; callro = replicaset_template_multicallro(false, false); callbro = replicaset_template_multicallro(false, true); + callbzro = replicaset_template_multicallro(false, 2); callre = replicaset_template_multicallro(true, false); callbre = replicaset_template_multicallro(true, true); + callbzre = replicaset_template_multicallro(true, 2); map_call = replicaset_map_call, update_master = replicaset_update_master, }; @@ -1235,6 +1260,7 @@ local function buildall(sharding_cfg) local function replica_cmp_weight(r1, r2) -- Master has priority over replicas with the same -- weight. + if r1.weight == r2.weight then return r1 == new_replicaset.master else diff --git a/vshard/router/init.lua b/vshard/router/init.lua index bd686afa..6e91fda0 100644 --- a/vshard/router/init.lua +++ b/vshard/router/init.lua @@ -576,11 +576,15 @@ local function router_call_impl(router, bucket_id, mode, prefer_replica, local call if mode == 'read' then if prefer_replica then - if balance then + if balance == 2 then + call = 'callbzre' + elseif balance then call = 'callbre' else call = 'callre' end + elseif balance == 2 then + call = 'callbzro' elseif balance then call = 'callbro' else @@ -698,6 +702,10 @@ local function router_callbro(router, bucket_id, ...) return router_call_impl(router, bucket_id, 'read', false, true, ...) end +local function router_callbzro(router, bucket_id, ...) + return router_call_impl(router, bucket_id, 'read', false, 2, ...) +end + local function router_callrw(router, bucket_id, ...) return router_call_impl(router, bucket_id, 'write', false, false, ...) end @@ -710,6 +718,10 @@ local function router_callbre(router, bucket_id, ...) return router_call_impl(router, bucket_id, 'read', true, true, ...) end +local function router_callbzre(router, bucket_id, ...) + return router_call_impl(router, bucket_id, 'read', true, 2, ...) +end + local function router_call(router, bucket_id, opts, ...) local mode, prefer_replica, balance if opts then @@ -1660,6 +1672,8 @@ local router_mt = { call = router_make_api(router_call), callro = router_make_api(router_callro), callbro = router_make_api(router_callbro), + callbzro = router_make_api(router_callbzro), + callbzre = router_make_api(router_callbzre), callrw = router_make_api(router_callrw), callre = router_make_api(router_callre), callbre = router_make_api(router_callbre), From b3656e73adaa0afa6bdbade8113d39042ac24902 Mon Sep 17 00:00:00 2001 From: Eugene Paniot Date: Tue, 17 Jan 2023 21:55:04 +0000 Subject: [PATCH 2/4] Update comments --- vshard/replicaset.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/vshard/replicaset.lua b/vshard/replicaset.lua index 359fa202..719993b3 100644 --- a/vshard/replicaset.lua +++ b/vshard/replicaset.lua @@ -587,18 +587,17 @@ local function replicaset_template_multicallro(prefer_replica, balance) if r:is_connected() and (not prefer_replica or r ~= master) and replica_check_backoff(r, now) then - -- Pick a replica according prefered zone (highest priority replica zone) in round-robin manner. + -- Pick a replica according prefered zone (highest priority replica zone) in round-robin manner if balance == 2 and prefered_zone then - -- save current rr-cursor position local cbi = replicaset.balance_i - -- find next replica local nr = replicaset_balance_replica(replicaset) - if prefered_zone and r.zone and r.zone == prefered_zone -- current replica is in prefered_zone - and nr.zone and nr.zone ~= prefered_zone -- next replica is from different zone (reached prefered_zone replicas) + if prefered_zone and r.zone and r.zone == prefered_zone + and nr.zone and nr.zone ~= prefered_zone and (not prefer_replica or nr ~= master) then - -- reset cursor to the main position + -- Reset cursor to the main position if next replica is in different zone, + -- reached prefered_zone replicas replicaset.balance_i = 1 else -- restore rr-cursor position From 774dfb26d6ba4f944f53399d52a378d8d35e6120 Mon Sep 17 00:00:00 2001 From: Eugene Paniot Date: Sun, 22 Jan 2023 16:51:52 +0000 Subject: [PATCH 3/4] Use strings as load-balancing algorithm identificator --- vshard/replicaset.lua | 11 +++++------ vshard/router/init.lua | 8 ++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/vshard/replicaset.lua b/vshard/replicaset.lua index 719993b3..e71bfcaa 100644 --- a/vshard/replicaset.lua +++ b/vshard/replicaset.lua @@ -588,7 +588,7 @@ local function replicaset_template_multicallro(prefer_replica, balance) replica_check_backoff(r, now) then -- Pick a replica according prefered zone (highest priority replica zone) in round-robin manner - if balance == 2 and prefered_zone then + if balance == "prefer_zone" and prefered_zone then local cbi = replicaset.balance_i local nr = replicaset_balance_replica(replicaset) @@ -596,11 +596,10 @@ local function replicaset_template_multicallro(prefer_replica, balance) and nr.zone and nr.zone ~= prefered_zone and (not prefer_replica or nr ~= master) then - -- Reset cursor to the main position if next replica is in different zone, - -- reached prefered_zone replicas + -- Reset cursor to the main position if next replica is in different zone. replicaset.balance_i = 1 else - -- restore rr-cursor position + -- Restore rr-cursor position. replicaset.balance_i = cbi end end @@ -1012,10 +1011,10 @@ local replicaset_mt = { callrw = replicaset_master_call; callro = replicaset_template_multicallro(false, false); callbro = replicaset_template_multicallro(false, true); - callbzro = replicaset_template_multicallro(false, 2); + callbzro = replicaset_template_multicallro(false, "prefer_zone"); callre = replicaset_template_multicallro(true, false); callbre = replicaset_template_multicallro(true, true); - callbzre = replicaset_template_multicallro(true, 2); + callbzre = replicaset_template_multicallro(true, "prefer_zone"); map_call = replicaset_map_call, update_master = replicaset_update_master, }; diff --git a/vshard/router/init.lua b/vshard/router/init.lua index 6e91fda0..9fbe6162 100644 --- a/vshard/router/init.lua +++ b/vshard/router/init.lua @@ -576,14 +576,14 @@ local function router_call_impl(router, bucket_id, mode, prefer_replica, local call if mode == 'read' then if prefer_replica then - if balance == 2 then + if balance == "prefer_zone" then call = 'callbzre' elseif balance then call = 'callbre' else call = 'callre' end - elseif balance == 2 then + elseif balance == "prefer_zone" then call = 'callbzro' elseif balance then call = 'callbro' @@ -703,7 +703,7 @@ local function router_callbro(router, bucket_id, ...) end local function router_callbzro(router, bucket_id, ...) - return router_call_impl(router, bucket_id, 'read', false, 2, ...) + return router_call_impl(router, bucket_id, 'read', false, "prefer_zone", ...) end local function router_callrw(router, bucket_id, ...) @@ -719,7 +719,7 @@ local function router_callbre(router, bucket_id, ...) end local function router_callbzre(router, bucket_id, ...) - return router_call_impl(router, bucket_id, 'read', true, 2, ...) + return router_call_impl(router, bucket_id, 'read', true, "prefer_zone", ...) end local function router_call(router, bucket_id, opts, ...) From d22797c5270a52a14984b70708954d0c3dfc09e2 Mon Sep 17 00:00:00 2001 From: Eugene Paniot Date: Wed, 15 Feb 2023 14:35:48 +0000 Subject: [PATCH 4/4] Update test/router/router.result add new funct --- test/router/router.result | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/router/router.result b/test/router/router.result index 4032e6e7..2f66b4f5 100644 --- a/test/router/router.result +++ b/test/router/router.result @@ -1465,6 +1465,8 @@ error_messages - Use replicaset:callbro(...) instead of replicaset.callbro(...) - Use replicaset:callre(...) instead of replicaset.callre(...) - Use replicaset:callro(...) instead of replicaset.callro(...) + - Use replicaset:callbzre(...) instead of replicaset.callbzre(...) + - Use replicaset:callbzro(...) instead of replicaset.callbzro(...) - Use replicaset:callrw(...) instead of replicaset.callrw(...) - Use replicaset:connect(...) instead of replicaset.connect(...) - Use replicaset:connect_all(...) instead of replicaset.connect_all(...)