()
| 218 | } |
| 219 | |
| 220 | func (s *Server) chooseTablet() (predicate string, srcGroup uint32, dstGroup uint32) { |
| 221 | s.RLock() |
| 222 | defer s.RUnlock() |
| 223 | if s.state == nil { |
| 224 | return |
| 225 | } |
| 226 | numGroups := len(s.state.Groups) |
| 227 | if !s.Node.AmLeader() || numGroups <= 1 { |
| 228 | return |
| 229 | } |
| 230 | |
| 231 | // Sort all groups by their sizes. |
| 232 | type kv struct { |
| 233 | gid uint32 |
| 234 | size int64 // in bytes |
| 235 | } |
| 236 | var groups []kv |
| 237 | for k, v := range s.state.Groups { |
| 238 | space := int64(0) |
| 239 | for _, tab := range v.Tablets { |
| 240 | space += tab.OnDiskBytes |
| 241 | } |
| 242 | groups = append(groups, kv{k, space}) |
| 243 | } |
| 244 | sort.Slice(groups, func(i, j int) bool { |
| 245 | return groups[i].size < groups[j].size |
| 246 | }) |
| 247 | |
| 248 | glog.Infof("\n\nGroups sorted by size: %+v\n\n", groups) |
| 249 | for lastGroup := numGroups - 1; lastGroup > 0; lastGroup-- { |
| 250 | srcGroup = groups[lastGroup].gid |
| 251 | dstGroup = groups[0].gid |
| 252 | sizeDiff := groups[lastGroup].size - groups[0].size |
| 253 | glog.Infof("size_diff %v\n", sizeDiff) |
| 254 | // Don't move a node unless you receive atleast one update regarding tablet size. |
| 255 | // Tablet size would have come up with leader update. |
| 256 | if !s.hasLeader(dstGroup) { |
| 257 | return |
| 258 | } |
| 259 | // We move the predicate only if the difference between size of both machines is |
| 260 | // atleast 10% of dst group. |
| 261 | if float64(sizeDiff) < 0.1*float64(groups[0].size) { |
| 262 | continue |
| 263 | } |
| 264 | |
| 265 | // Try to find a predicate which we can move. |
| 266 | size := int64(0) |
| 267 | group := s.state.Groups[srcGroup] |
| 268 | for _, tab := range group.Tablets { |
| 269 | // Reserved predicates should always be in group 1 so do not re-balance them. |
| 270 | if x.IsReservedPredicate(tab.Predicate) { |
| 271 | continue |
| 272 | } |
| 273 | |
| 274 | // Finds a tablet as big a possible such that on moving it dstGroup's size is |
| 275 | // less than or equal to srcGroup. |
| 276 | if tab.OnDiskBytes <= sizeDiff/2 && tab.OnDiskBytes > size { |
| 277 | predicate = tab.Predicate |
no test coverage detected