couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rnew...@apache.org
Subject [26/50] mem3 commit: updated refs/heads/master to 64c0c74
Date Thu, 28 Aug 2014 12:22:46 GMT
Ensure all shards are moved off non-target nodes

BugzID: 20742


Project: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/commit/6d9983fc
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/tree/6d9983fc
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/diff/6d9983fc

Branch: refs/heads/master
Commit: 6d9983fce97f9395049061a9e051eaac4a95ffe0
Parents: 720049b
Author: Adam Kocoloski <adam@cloudant.com>
Authored: Fri Aug 16 13:40:50 2013 -0400
Committer: Robert Newson <rnewson@apache.org>
Committed: Wed Jul 23 18:46:26 2014 +0100

----------------------------------------------------------------------
 src/mem3_rebalance.erl | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-mem3/blob/6d9983fc/src/mem3_rebalance.erl
----------------------------------------------------------------------
diff --git a/src/mem3_rebalance.erl b/src/mem3_rebalance.erl
index 8f5872a..28cd32e 100644
--- a/src/mem3_rebalance.erl
+++ b/src/mem3_rebalance.erl
@@ -23,8 +23,43 @@ rebalance(DbName) ->
 rebalance(DbName, TargetNodes) when is_binary(DbName) ->
     rebalance(mem3:shards(DbName), TargetNodes);
 rebalance(Shards, TargetNodes) when is_list(Shards) ->
+    %% first migrate shards off of non-target nodes
+    {OK, MoveThese} = lists:partition(fun(#shard{node=Node}) ->
+        lists:member(Node, TargetNodes)
+    end, Shards),
+    ShardsByTargetNode0 = lists:foldl(fun(Shard, Acc) ->
+        orddict:append(Shard#shard.node, Shard, Acc)
+    end, orddict:new(), OK),
+    ShardsByTargetNode = lists:sort(lists:foldl(fun(Node, Acc) ->
+        case orddict:is_key(Node, ShardsByTargetNode0) of
+            true ->
+                Acc;
+            false ->
+                [{Node, []} | Acc]
+        end
+    end, ShardsByTargetNode0, TargetNodes)),
+    Moves = find_replacements(MoveThese, ShardsByTargetNode, []),
+    Moved = [Shard#shard{node = Node} || {Shard, Node} <- Moves],
     TargetLevel = length(Shards) div length(TargetNodes),
-    rebalance2(TargetLevel, Shards, TargetNodes, TargetNodes, []).
+    rebalance2(TargetLevel, OK ++ Moved, TargetNodes, TargetNodes, Moves).
+
+find_replacements([], _ShardsByTargetNode, Result) ->
+    Result;
+find_replacements([Shard | Rest], ShardsByNode, Acc) ->
+    Zone = mem3:node_info(Shard#shard.node, <<"zone">>),
+    % Find a node in the same zone
+    InZone = [{Node, Shards} || {Node, Shards} <- ShardsByNode,
+        mem3:node_info(Node, <<"zone">>) =:= Zone],
+    % Prefer a node with the fewest number of shards
+    if InZone =:= [] ->
+        erlang:error({empty_zone, Zone, Shard});
+    true ->
+        ok
+    end,
+    [{TargetNode, _} | _] = lists:sort(fun smallest_first/2, InZone),
+    TargetShard = Shard#shard{node = TargetNode},
+    find_replacements(Rest, orddict:append(TargetNode, TargetShard, ShardsByNode),
+        [{Shard, TargetNode} | Acc]).
 
 rebalance2(_TargetLevel, Shards, _Nodes, [], Moves) ->
     {Shards, Moves};
@@ -71,6 +106,9 @@ victim(TargetLevel, Shards, Nodes, TargetNode) ->
 largest_first({_, A}, {_, B}) ->
     length(A) >= length(B).
 
+smallest_first({_, A}, {_, B}) ->
+    length(A) < length(B).
+
 replace(A, B, List) ->
     replace(A, B, List, []).
 


Mime
View raw message