分布式入门设计跟实现

分布式入门设计和实现

如何设计实现最基础的分布式应用,我们可以从如下两个ID入手:一个是全球唯一标识,另一个分布式hash散列值。

前一个保证你各个服务器之间产生的不通ID是不重复的,因为它的主要算法是跟时间和MAC地址有关的,后一个决定你

的数据是分发给哪台服务器处理。

 

对GUID不是太理解的可以看如下一段(摘抄自杂志):

UUID含义是通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OSF) 的组织在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部份。UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。如此一来,每个人都可以建立不与其它人冲突的 UUID。在这样的情况下,就不需考虑数据库建立时的名称重复问题。目前最广泛应用的 UUID,即是微软的 Microsoft's Globally Unique Identifiers (GUIDs)。

 

一般我们在分布式系统中用guid做主键,而在列中增加一个 id_hash来保存期hash值。

 

一.guid 如何实现

 

JAVA uitil中采用了统一的实现,参看

 

System.out.println(UUID.randomUUID().toString());

 

 结果

 

1a078dc9-df28-4841-ad7a-00214f8a5ea7

 

 

二.hash值如何实现。

  

/**
	 * 
	 * @param str 需要散列的字符串
	 * @param mode 散列度
	 * @return
	 */
	public static int getStringHashValue(String str,int mode){
		Assert.notNull(str,"the hashString must not be null");
		int val=str.hashCode();
		if(val==Integer.MIN_VALUE) return 0;//处理当hashCode返回MIN_VALUE,abs为负的情况
		return Math.abs(val)%mode;
	};
  System.out.println("the string 'abc' hash value = "+getStringHashValue("abc",mode));
     System.out.println("the string 'abc' hash value = "+getStringHashValue("abc",mode));

 结果:

the string 'abc' hash value = 303
the string 'abc' hash value = 303

 

上面可以看到,满足一致性规则,相同的string产生了相同的hash值,这就保证了相同ID的用户分布到相同的机器上,满足了不同用户数据的隔离。

 

三.不同线程取数据如何隔离

通过hashStart 和 hashEnd 来分段取数据。例如:

 

searchParams.put("hashStart", profile.getHashStart());
searchParams.put("hashEnd", profile.getHashEnd());
searchParams.put("total", threadDataTotalInt);	
searchParams.put("collectType", BillingConstants.COLLECT_TYPE_INC);
List<BillingCollectBean> collects = billingCollectService.getIncCollectBeans(searchParams);

 

 profile.getHashStart()和profile.getHashEnd()通过antx配置,不同的机器配置不同的hash区段。

 

为满足平行扩展,我们最好将这些信息配置在数据库,通过读取数据库,自动取到自己的机器到底该处理哪些区段的纪录,

hash值散列时,mod取值可以根据机器数量和数据数进行设置,最好取的大一点,这样可以保证散列的均匀,同时粒度变的细小也便于控制(如果只有2,那最多可以给两个机器使用)。我们系统目前设置为1000。

 

展开阅读全文

没有更多推荐了,返回首页