Shuffle the partitions to reassign on a ring rebalance.

This commit is contained in:
gholt
2011-01-13 09:05:44 -08:00
parent 2962557612
commit d6aaba670b
2 changed files with 37 additions and 1 deletions

View File

@@ -14,7 +14,7 @@
# limitations under the License. # limitations under the License.
from array import array from array import array
from random import randint from random import randint, shuffle
from time import time from time import time
from swift.common.ring import RingData from swift.common.ring import RingData
@@ -413,6 +413,7 @@ class RingBuilder(object):
dev['parts_wanted'] += 1 dev['parts_wanted'] += 1
dev['parts'] -= 1 dev['parts'] -= 1
reassign_parts.append(part) reassign_parts.append(part)
shuffle(reassign_parts)
return reassign_parts return reassign_parts
def _reassign_parts(self, reassign_parts): def _reassign_parts(self, reassign_parts):

View File

@@ -125,6 +125,41 @@ class TestRingBuilder(unittest.TestCase):
counts[dev_id] = counts.get(dev_id, 0) + 1 counts[dev_id] = counts.get(dev_id, 0) + 1
self.assertEquals(counts, {0: 256, 2: 256, 3: 256}) self.assertEquals(counts, {0: 256, 2: 256, 3: 256})
def test_shuffled_gather(self):
if self._shuffled_gather_helper() and \
self._shuffled_gather_helper():
raise AssertionError('It is highly likely the ring is no '
'longer shuffling the set of partitions to reassign on a '
'rebalance.')
def _shuffled_gather_helper(self):
rb = ring.RingBuilder(8, 3, 1)
rb.add_dev({'id': 0, 'zone': 0, 'weight': 1, 'ip': '127.0.0.1',
'port': 10000, 'device': 'sda1'})
rb.add_dev({'id': 1, 'zone': 1, 'weight': 1, 'ip': '127.0.0.1',
'port': 10001, 'device': 'sda1'})
rb.add_dev({'id': 2, 'zone': 2, 'weight': 1, 'ip': '127.0.0.1',
'port': 10002, 'device': 'sda1'})
rb.rebalance()
rb.add_dev({'id': 3, 'zone': 3, 'weight': 1, 'ip': '127.0.0.1',
'port': 10003, 'device': 'sda1'})
rb.pretend_min_part_hours_passed()
parts = rb._gather_reassign_parts()
max_run = 0
run = 0
last_part = 0
for part in parts:
if part > last_part:
run += 1
else:
if run > max_run:
max_run = run
run = 0
last_part = part
if run > max_run:
max_run = run
return max_run > len(parts) / 2
def test_rerebalance(self): def test_rerebalance(self):
rb = ring.RingBuilder(8, 3, 1) rb = ring.RingBuilder(8, 3, 1)
rb.add_dev({'id': 0, 'zone': 0, 'weight': 1, 'ip': '127.0.0.1', rb.add_dev({'id': 0, 'zone': 0, 'weight': 1, 'ip': '127.0.0.1',