[Checkins] SVN: zc.resumelb/trunk/src/zc/resumelb/ Change the load-balancing algorithm to take backlogs of
jim
cvs-admin at zope.org
Mon Apr 23 16:46:32 UTC 2012
Log message for revision 125237:
Change the load-balancing algorithm to take backlogs of
underutilized workers into account to allow a lower variance
parameter to be used, which allows new workers to be better
utilized.
Changed:
U zc.resumelb/trunk/src/zc/resumelb/README.txt
U zc.resumelb/trunk/src/zc/resumelb/lb.py
U zc.resumelb/trunk/src/zc/resumelb/lb.test
U zc.resumelb/trunk/src/zc/resumelb/pool.test
U zc.resumelb/trunk/src/zc/resumelb/worker.test
-=-
Modified: zc.resumelb/trunk/src/zc/resumelb/README.txt
===================================================================
--- zc.resumelb/trunk/src/zc/resumelb/README.txt 2012-04-23 12:08:39 UTC (rev 125236)
+++ zc.resumelb/trunk/src/zc/resumelb/README.txt 2012-04-23 16:46:28 UTC (rev 125237)
@@ -242,6 +242,14 @@
Change History
==============
+0.4.0 (2012-04-23)
+------------------
+
+- Change the load-balancing algorithm to take backlogs of
+ underutilized workers into account to allow a lower variance
+ parameter to be used, which allows new workers to be better
+ utilized.
+
0.3.0 (2012-03-28)
------------------
Modified: zc.resumelb/trunk/src/zc/resumelb/lb.py
===================================================================
--- zc.resumelb/trunk/src/zc/resumelb/lb.py 2012-04-23 12:08:39 UTC (rev 125236)
+++ zc.resumelb/trunk/src/zc/resumelb/lb.py 2012-04-23 16:46:28 UTC (rev 125237)
@@ -115,7 +115,7 @@
_meta_settings = dict(
unskilled_score=1.0,
- variance=4.0,
+ variance=1.0,
backlog_history=9
)
@@ -224,8 +224,9 @@
skilled = self.skilled[rclass] = set()
max_backlog = max(self.variance * self.mbacklog / self.nworkers, 1)
+ min_backlog = unskilled.first.value.mbacklog + 1
for score, worker in skilled:
- if worker.mbacklog > max_backlog:
+ if (worker.mbacklog - min_backlog) > max_backlog:
continue
backlog = worker.backlog + 1
score /= backlog
Modified: zc.resumelb/trunk/src/zc/resumelb/lb.test
===================================================================
--- zc.resumelb/trunk/src/zc/resumelb/lb.test 2012-04-23 12:08:39 UTC (rev 125236)
+++ zc.resumelb/trunk/src/zc/resumelb/lb.test 2012-04-23 16:46:28 UTC (rev 125237)
@@ -27,7 +27,7 @@
>>> import zc.resumelb.lb
>>> lb = zc.resumelb.lb.LB([w.addr for w in workers],
- ... zc.resumelb.lb.host_classifier)
+ ... zc.resumelb.lb.host_classifier, variance=4)
Note that the lb provides an interface for changing pool
settings. This is just a link to the pool's update_settings method:
Modified: zc.resumelb/trunk/src/zc/resumelb/pool.test
===================================================================
--- zc.resumelb/trunk/src/zc/resumelb/pool.test 2012-04-23 12:08:39 UTC (rev 125236)
+++ zc.resumelb/trunk/src/zc/resumelb/pool.test 2012-04-23 16:46:28 UTC (rev 125237)
@@ -16,14 +16,15 @@
>>> import zc.resumelb.lb
>>> pool = zc.resumelb.lb.Pool(
- ... variance=2.5, backlog_history=2, unskilled_score=.5)
+ ... variance=1.5, backlog_history=2, unskilled_score=.5)
We specified a number of optional parameters that we'll see in action
later:
variance
How many times the pool mean backlog we'll let a worker's backlog
- rise before we look for another worker. The default is 4.
+ rise above the minimum backlog [#almostminimum]_ before we look for
+ another worker. The default is 1.
backlog_history
The (approximate) number of requests to include in the mean backlog
@@ -60,8 +61,8 @@
>>> pool.new_resume(w1, {})
- >>> pool.get('foo', 0.0)
- w1
+ >>> pool.get('foo', 0.0)
+ w1
This time, we got the one we registered.
@@ -106,7 +107,7 @@
>>> w3 = Worker('w3')
>>> pool.new_resume(w3, {})
-and make some more foo requests:
+and make another foo request:
>>> [pool.get('foo') for i in range(2)]
[w1, w1]
@@ -280,7 +281,7 @@
>>> pool.new_resume(w2, {'bar': 2.0, 'foo': 2.0})
>>> pool.new_resume(w3, {'foo': 3.8})
>>> pool.variance, pool.backlog_history, pool.unskilled_score
- (4.0, 9, 1.0)
+ (1.0, 9, 1.0)
>>> pool.worker_decay, pool.decay # doctest: +ELLIPSIS
(0.944..., 0.981...)
@@ -301,7 +302,7 @@
>>> pool.update_settings({})
>>> pool.variance, pool.backlog_history, pool.unskilled_score
- (4.0, 9, 1.0)
+ (1.0, 9, 1.0)
>>> pool.worker_decay, pool.decay # doctest: +ELLIPSIS
(0.944..., 0.981...)
@@ -316,3 +317,43 @@
... dict(variance='2', backlog_history='7', unskilled_score='1'))
>>> pool.variance, pool.backlog_history, pool.unskilled_score
(2.0, 7, 1.0)
+
+Using new workers
+=================
+
+Under heavy load, we should be able to add a worker and have it get
+used immediately.
+
+ >>> pool.update_settings(dict(variance=1))
+ >>> pool.new_resume(w1, {'bar': 2.0})
+ >>> pool.new_resume(w2, {'bar': 2.0})
+ >>> pool.new_resume(w3, {'bar': 2.0})
+ >>> _ = [pool.get('bar') for i in range(30)]
+
+ >>> pool # doctest: +ELLIPSIS
+ Request classes:
+ bar: w1(2.0,5.96898355541), w2(2.0,5.96898355541), w3(2.0,5.96898355541)
+ foo:
+ Backlogs:
+ overall backlog: 30 Decayed: 16.8930595654 Avg: 5.63101985512
+ 10: [w1, w2, w3]
+
+Now, we'll add a new worker:
+
+ >>> w6 = Worker('w6')
+ >>> pool.new_resume(w6, {})
+
+And wen we make a request, it will go to the new worker:
+
+ >>> pool.get('bar')
+ w6
+
+Note that we used a variance of 1. Unfortunately, if we use a higher
+variance, new individual workers won't get added. However, using so
+low a variance will tend to cause work to spread out over multiple
+workers, rather than being limited to a few.
+
+
+.. [#almostminimum] We use the backlog of the least-recently-used
+ worker as an approximation of the minumun backlog.
+
Modified: zc.resumelb/trunk/src/zc/resumelb/worker.test
===================================================================
--- zc.resumelb/trunk/src/zc/resumelb/worker.test 2012-04-23 12:08:39 UTC (rev 125236)
+++ zc.resumelb/trunk/src/zc/resumelb/worker.test 2012-04-23 16:46:28 UTC (rev 125237)
@@ -774,3 +774,12 @@
>>> read_message(worker_socket)
(0, {'test': 0.875})
+
+Cleanup:
+
+ >>> worker.stop()
+
+File results
+============
+
+Workers support
More information about the checkins
mailing list