@Test public void testAssignMigrations() { servers.clear(); servers.put( new TServerInstance(HostAndPort.fromParts("127.0.0.1", 1234), "a"), new FakeTServer()); servers.put( new TServerInstance(HostAndPort.fromParts("127.0.0.1", 1235), "b"), new FakeTServer()); servers.put( new TServerInstance(HostAndPort.fromParts("127.0.0.1", 1236), "c"), new FakeTServer()); List<KeyExtent> metadataTable = new ArrayList<KeyExtent>(); String table = "t1"; metadataTable.add(makeExtent(table, null, null)); table = "t2"; metadataTable.add(makeExtent(table, "a", null)); metadataTable.add(makeExtent(table, null, "a")); table = "t3"; metadataTable.add(makeExtent(table, "a", null)); metadataTable.add(makeExtent(table, "b", "a")); metadataTable.add(makeExtent(table, "c", "b")); metadataTable.add(makeExtent(table, "d", "c")); metadataTable.add(makeExtent(table, "e", "d")); metadataTable.add(makeExtent(table, null, "e")); Collections.sort(metadataTable); TestDefaultLoadBalancer balancer = new TestDefaultLoadBalancer(); SortedMap<TServerInstance, TabletServerStatus> current = new TreeMap<TServerInstance, TabletServerStatus>(); for (Entry<TServerInstance, FakeTServer> entry : servers.entrySet()) { current.put(entry.getKey(), entry.getValue().getStatus(entry.getKey())); } assignTablets(metadataTable, servers, current, balancer); // Verify that the counts on the tables are correct Map<String, Integer> expectedCounts = new HashMap<String, Integer>(); expectedCounts.put("t1", 1); expectedCounts.put("t2", 1); expectedCounts.put("t3", 2); checkBalance(metadataTable, servers, expectedCounts); // Rebalance once for (Entry<TServerInstance, FakeTServer> entry : servers.entrySet()) { current.put(entry.getKey(), entry.getValue().getStatus(entry.getKey())); } // Nothing should happen, we are balanced ArrayList<TabletMigration> out = new ArrayList<TabletMigration>(); balancer.getMigrations(current, out); assertEquals(out.size(), 0); // Take down a tabletServer TServerInstance first = current.keySet().iterator().next(); current.remove(first); FakeTServer remove = servers.remove(first); // reassign offline extents assignTablets(remove.extents, servers, current, balancer); checkBalance(metadataTable, servers, null); }
@Test public void testUnevenAssignment2() { servers.clear(); // make 26 servers for (char c : "abcdefghijklmnopqrstuvwxyz".toCharArray()) { String cString = Character.toString(c); HostAndPort fakeAddress = HostAndPort.fromParts("127.0.0.1", (int) c); String fakeInstance = cString; TServerInstance tsi = new TServerInstance(fakeAddress, fakeInstance); FakeTServer fakeTServer = new FakeTServer(); servers.put(tsi, fakeTServer); } // put 60 tablets on 25 of them List<Entry<TServerInstance, FakeTServer>> shortList = new ArrayList<Entry<TServerInstance, FakeTServer>>(servers.entrySet()); Entry<TServerInstance, FakeTServer> shortServer = shortList.remove(0); int c = 0; for (int i = 0; i < 60; i++) { for (Entry<TServerInstance, FakeTServer> entry : shortList) { entry.getValue().extents.add(makeExtent("t" + c, null, null)); } } // put 10 on the that short server: for (int i = 0; i < 10; i++) { shortServer.getValue().extents.add(makeExtent("s" + i, null, null)); } TestDefaultLoadBalancer balancer = new TestDefaultLoadBalancer(); Set<KeyExtent> migrations = Collections.emptySet(); int moved = 0; // balance until we can't balance no more! while (true) { List<TabletMigration> migrationsOut = new ArrayList<TabletMigration>(); balancer.balance(getAssignments(servers), migrations, migrationsOut); if (migrationsOut.size() == 0) break; for (TabletMigration migration : migrationsOut) { if (servers.get(migration.oldServer).extents.remove(migration.tablet)) moved++; servers.get(migration.newServer).extents.add(migration.tablet); } } // average is 58, with 2 at 59: we need 48 more moved to the short server assertEquals(48, moved); }
private void assignTablets( List<KeyExtent> metadataTable, Map<TServerInstance, FakeTServer> servers, SortedMap<TServerInstance, TabletServerStatus> status, TestDefaultLoadBalancer balancer) { // Assign tablets for (KeyExtent extent : metadataTable) { TServerInstance assignment = balancer.getAssignment(status, extent, null); assertNotNull(assignment); assertFalse(servers.get(assignment).extents.contains(extent)); servers.get(assignment).extents.add(extent); } }
@Test public void testUnevenAssignment() { servers.clear(); for (char c : "abcdefghijklmnopqrstuvwxyz".toCharArray()) { String cString = Character.toString(c); HostAndPort fakeAddress = HostAndPort.fromParts("127.0.0.1", (int) c); String fakeInstance = cString; TServerInstance tsi = new TServerInstance(fakeAddress, fakeInstance); FakeTServer fakeTServer = new FakeTServer(); servers.put(tsi, fakeTServer); fakeTServer.extents.add(makeExtent(cString, null, null)); } // Put more tablets on one server, but not more than the number of servers Entry<TServerInstance, FakeTServer> first = servers.entrySet().iterator().next(); first.getValue().extents.add(makeExtent("newTable", "a", null)); first.getValue().extents.add(makeExtent("newTable", "b", "a")); first.getValue().extents.add(makeExtent("newTable", "c", "b")); first.getValue().extents.add(makeExtent("newTable", "d", "c")); first.getValue().extents.add(makeExtent("newTable", "e", "d")); first.getValue().extents.add(makeExtent("newTable", "f", "e")); first.getValue().extents.add(makeExtent("newTable", "g", "f")); first.getValue().extents.add(makeExtent("newTable", "h", "g")); first.getValue().extents.add(makeExtent("newTable", "i", null)); TestDefaultLoadBalancer balancer = new TestDefaultLoadBalancer(); Set<KeyExtent> migrations = Collections.emptySet(); int moved = 0; // balance until we can't balance no more! while (true) { List<TabletMigration> migrationsOut = new ArrayList<TabletMigration>(); balancer.balance(getAssignments(servers), migrations, migrationsOut); if (migrationsOut.size() == 0) break; for (TabletMigration migration : migrationsOut) { if (servers.get(migration.oldServer).extents.remove(migration.tablet)) moved++; servers.get(migration.newServer).extents.add(migration.tablet); } } assertEquals(8, moved); }