@@ -1783,6 +1783,103 @@ public void testRegionsWithDiskWeight() throws Exception {
17831783 assertEquals (3 , ensemble .size ());
17841784 }
17851785
1786+ @ Test
1787+ public void testRegionsWithDifferentDiskWeight () throws Exception {
1788+ repp .uninitalize ();
1789+ repp = new RegionAwareEnsemblePlacementPolicy ();
1790+ conf .setProperty (REPP_ENABLE_VALIDATION , false );
1791+ conf .setDiskWeightBasedPlacementEnabled (true );
1792+ repp .initialize (conf , Optional .empty (), timer , DISABLE_ALL ,
1793+ NullStatsLogger .INSTANCE , BookieSocketAddress .LEGACY_BOOKIEID_RESOLVER );
1794+ BookieSocketAddress addr1 = new BookieSocketAddress ("127.0.0.2" , 3181 );
1795+ BookieSocketAddress addr2 = new BookieSocketAddress ("127.0.0.3" , 3181 );
1796+ BookieSocketAddress addr3 = new BookieSocketAddress ("127.0.0.4" , 3181 );
1797+ BookieSocketAddress addr4 = new BookieSocketAddress ("127.0.0.5" , 3181 );
1798+ BookieSocketAddress addr5 = new BookieSocketAddress ("127.0.0.6" , 3181 );
1799+
1800+ // update dns mapping
1801+ StaticDNSResolver .addNodeToRack (addr1 .getHostName (), "/region1/r1" );
1802+ StaticDNSResolver .addNodeToRack (addr2 .getHostName (), "/region1/r1" );
1803+ StaticDNSResolver .addNodeToRack (addr3 .getHostName (), "/region2/r2" );
1804+ StaticDNSResolver .addNodeToRack (addr4 .getHostName (), "/region2/r2" );
1805+ StaticDNSResolver .addNodeToRack (addr5 .getHostName (), "/region2/r2" );
1806+ // Update cluster
1807+ Set <BookieId > addrs = new HashSet <>();
1808+ addrs .add (addr1 .toBookieId ());
1809+ addrs .add (addr2 .toBookieId ());
1810+ addrs .add (addr3 .toBookieId ());
1811+ addrs .add (addr4 .toBookieId ());
1812+ addrs .add (addr5 .toBookieId ());
1813+ repp .onClusterChanged (addrs , new HashSet <>());
1814+
1815+ // update bookie weight
1816+ // due to default BookieMaxWeightMultipleForWeightBasedPlacement=3, the test cases need to be in the range
1817+ Map <BookieId , BookieInfoReader .BookieInfo > bookieInfoMap = new HashMap <>();
1818+ bookieInfoMap .put (addr1 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 800000 ));
1819+ bookieInfoMap .put (addr2 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 400000 ));
1820+ bookieInfoMap .put (addr3 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 200000 ));
1821+ bookieInfoMap .put (addr4 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 300000 ));
1822+ bookieInfoMap .put (addr5 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 400000 ));
1823+ repp .updateBookieInfo (bookieInfoMap );
1824+
1825+ List <BookieId > ensemble ;
1826+ Map <BookieId , Integer > countMap = new HashMap <>();
1827+ addrs .forEach (a -> countMap .put (a , 0 ));
1828+ int loopTimes = 5000 ;
1829+ for (int i = 0 ; i < loopTimes ; ++i ) {
1830+ ensemble = repp .newEnsemble (2 , 2 , 2 , null ,
1831+ new HashSet <>()).getResult ();
1832+ for (BookieId bookieId : ensemble ) {
1833+ countMap .put (bookieId , countMap .get (bookieId ) + 1 );
1834+ }
1835+ }
1836+
1837+ // c1 should be 2x than c2
1838+ // c4 should be 1.5x than c3
1839+ // c5 should be 2x than c3
1840+ // we allow a range of (-50%, 50%) deviation instead of the exact multiples
1841+ int c1 , c2 , c3 , c4 , c5 ;
1842+ c1 = countMap .get (addr1 .toBookieId ());
1843+ c2 = countMap .get (addr2 .toBookieId ());
1844+ c3 = countMap .get (addr3 .toBookieId ());
1845+ c4 = countMap .get (addr4 .toBookieId ());
1846+ c5 = countMap .get (addr5 .toBookieId ());
1847+ assertTrue (Math .abs ((double ) c1 / c2 - 2.0 ) < 1.0 );
1848+ assertTrue (Math .abs ((double ) c4 / c3 - 1.5 ) < 1.0 );
1849+ assertTrue (Math .abs ((double ) c5 / c3 - 2.0 ) < 1.0 );
1850+
1851+ // update bookie weight
1852+ // due to default BookieMaxWeightMultipleForWeightBasedPlacement=3, the test cases need to be in the range
1853+ bookieInfoMap .put (addr1 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 400000 ));
1854+ bookieInfoMap .put (addr2 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 800000 ));
1855+ bookieInfoMap .put (addr3 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 400000 ));
1856+ bookieInfoMap .put (addr4 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 300000 ));
1857+ bookieInfoMap .put (addr5 .toBookieId (), new BookieInfoReader .BookieInfo (1000000 , 200000 ));
1858+ repp .updateBookieInfo (bookieInfoMap );
1859+
1860+ addrs .forEach (a -> countMap .put (a , 0 ));
1861+ for (int i = 0 ; i < loopTimes ; ++i ) {
1862+ ensemble = repp .newEnsemble (2 , 2 , 2 , null ,
1863+ new HashSet <>()).getResult ();
1864+ for (BookieId bookieId : ensemble ) {
1865+ countMap .put (bookieId , countMap .get (bookieId ) + 1 );
1866+ }
1867+ }
1868+
1869+ // c2 should be 2x than c1
1870+ // c4 should be 1.5x than c5
1871+ // c3 should be 2x than c5
1872+ // we allow a range of (-50%, 50%) deviation instead of the exact multiples
1873+ c1 = countMap .get (addr1 .toBookieId ());
1874+ c2 = countMap .get (addr2 .toBookieId ());
1875+ c3 = countMap .get (addr3 .toBookieId ());
1876+ c4 = countMap .get (addr4 .toBookieId ());
1877+ c5 = countMap .get (addr5 .toBookieId ());
1878+ assertTrue (Math .abs ((double ) c2 / c1 - 2.0 ) < 1.0 );
1879+ assertTrue (Math .abs ((double ) c4 / c5 - 1.5 ) < 1.0 );
1880+ assertTrue (Math .abs ((double ) c3 / c5 - 2.0 ) < 1.0 );
1881+ }
1882+
17861883 @ Test
17871884 public void testNotifyRackChangeWithOldRegion () throws Exception {
17881885 BookieSocketAddress addr1 = new BookieSocketAddress ("127.0.1.1" , 3181 );
0 commit comments