但是,这种算法相对于取模方式也有一个缺陷:当server数量很少时,很可能他们在环中的分布不是特别均匀 , 进而导致cache不能均匀分布到所有的server上 。
如图,一共有3台server – 1,2,4 。命中4的几率远远高于1和2 。
为解决这个问题,需要使用虚拟节点的思想:为每个物理节点(server)在环上分配100~200个点,这样环上的节点较多,就能抑制分布不均匀 。
当为cache定位目标server时,如果定位到虚拟节点上,就表示cache真正的存储位置是在该虚拟节点代表的实际物理server上 。
另外,如果每个实际server的负载能力不同,可以赋予不同的权重,根据权重分配不同数量的虚拟节点 。
// 采用有序map来模拟环
this.consistentBuckets = new TreeMap();
MessageDigest md5 = MD5.get();//用MD5来计算key和server的hash值
// 计算总权重
if ( this.totalWeightfor ( int i = 0; ithis.weights.length; i++ )
this.totalWeight += ( this.weights[i] == null ) ? 1 : this.weights[i];
} else if ( this.weights == null ) {
this.totalWeight = this.servers.length;
}
// 为每个server分配虚拟节点
for ( int i = 0; iservers.length; i++ ) {
// 计算当前server的权重
int thisWeight = 1;
if ( this.weights != nullthis.weights[i] != null )
thisWeight = this.weights[i];
// factor用来控制每个server分配的虚拟节点数量
// 权重都相同时 , factor=40
// 权重不同时,factor=40*server总数*该server权重所占的百分比
// 总的来说 , 权重越大,factor越大,可以分配越多的虚拟节点
double factor = Math.floor( ((double)(40 * this.servers.length * thisWeight)) / (double)this.totalWeight );
for ( long j = 0; jfactor; j++ ) {
// 每个server有factor个hash值
// 使用server的域名或IP加上编号来计算hash值
// 比如server - "172.45.155.25:11111"就有factor个数据用来生成hash值:
// 172.45.155.25:11111-1, 172.45.155.25:11111-2, ..., 172.45.155.25:11111-factor
byte[] d = md5.digest( ( servers[i] + "-" + j ).getBytes() );
// 每个hash值生成4个虚拟节点
for ( int h = 0 ; h4; h++ ) {
Long k =
((long)(d[3+h*4]0xFF)24)
| ((long)(d[2+h*4]0xFF)16)
| ((long)(d[1+h*4]0xFF)8 )
| ((long)(d[0+h*4]0xFF));
// 在环上保存节点
consistentBuckets.put( k, servers[i] );
}
}
// 每个server一共分配4*factor个虚拟节点
}
// 采用有序map来模拟环
this.consistentBuckets = new TreeMap();
MessageDigest md5 = MD5.get();//用MD5来计算key和server的hash值
// 计算总权重
if ( this.totalWeightfor ( int i = 0; ithis.weights.length; i++ )
this.totalWeight += ( this.weights[i] == null ) ? 1 : this.weights[i];
} else if ( this.weights == null ) {
this.totalWeight = this.servers.length;
}
// 为每个server分配虚拟节点
for ( int i = 0; iservers.length; i++ ) {
// 计算当前server的权重
int thisWeight = 1;
if ( this.weights != nullthis.weights[i] != null )
thisWeight = this.weights[i];
// factor用来控制每个server分配的虚拟节点数量
// 权重都相同时,factor=40
// 权重不同时,factor=40*server总数*该server权重所占的百分比
// 总的来说 , 权重越大,factor越大,可以分配越多的虚拟节点
double factor = Math.floor( ((double)(40 * this.servers.length * thisWeight)) / (double)this.totalWeight );
for ( long j = 0; jfactor; j++ ) {
// 每个server有factor个hash值
// 使用server的域名或IP加上编号来计算hash值
// 比如server - "172.45.155.25:11111"就有factor个数据用来生成hash值:
【php分布式数据库 php分布式部署】
推荐阅读
- 企鹅直播用什么直播伴侣,企鹅直播配置
- 包含拍视频的什么青蛙的词条
- visualc.net程序设计教程,visualcnet程序设计教程第3版课后答案
- erp系统切换仓库要注意什么,erp系统更换
- mysql怎么自加 ht3528h8dg5l
- 模拟经营游戏排名,模拟类经营游戏
- 如何提取所有的ppt图片,如何提取出ppt中所有图片
- java代码的超链接 java html的超链接标签
- 电视分屏怎么取消,电视分屏怎么取消