1,对balanceCode(一个随机数)简单的取模,select = balanceCode%m;(m为服务器的数量)
2,这时候,假如校验select到的服务器不可用。。。那么。。second = balanceCode%(m-1);
select = second < select ? second : second + 1
效果就是把不可用的服务器屏蔽掉了,并且select也是等概率分布的。。
例如:序列,1,2,3,4,5,6,7,8,9,10,11,12
首先模3
对应的结果是:1,2,0,1,2,0,1,2,0,1,2,0
我们对code模2之后的结果是:1,0,1,0,1,0,1,0,1,0,1,0
最终的结果是:2,0,2,0,1,1,2,0,2,0,1,1
对于第一次选择结果中所有的1号服务器,二次选择的分布为2,0,2,0
同理。。。2号和0号也是一样。。。
原理在于
设某个code模m的结果为b,(0<=b<=m-1),则该code为a*m+b,即除以m时商a余b
那么a*m+b = a*(m-1)+a+b,模m-1的结果等于(a+b)%(m-1)
对于某个定值b,a是随着code以固定周期m递增的,故该结果 c 的序列是以m-1为周期的一个循环,(0<=c<=m-2)
现在的问题就是如何建立一个映射,将结果为b的屏蔽掉,并且让剩下的结果也是周期分布的。。。
方法就是以b为分界点,对结果进行划分,<b的,不管,>=b的+1,这样
若0<=b<=m-2,那么<b的仍然保持原值,映射到[0,b-1],>=b的映射到[b+1,m-1],一共m-1个值
若b = m-1 ,则不可能有>=b的情况,故保持原值,在[0,m-2]区间
= =!