一致性hash算法原理与php实例

  1. 一致性哈希算法原理
     首先将所有哈希值空间组成一个虚拟的圆环。
     其次我们将所有载体(服务器或者数据表)使用某个hash算法,这样就可以找到载体在圆环上的位置。
     接下来对要定位的数据使用与载体相同的hash算法,计算出数据在圆环上的位置,然后顺时针去行走到的第一个载体就是其应该定位到的载体。
    在这里插入图片描述

如果,删除一个载体,那么需要定位的数据会落到,被删除的载体前面的那个载体上。如图:
在这里插入图片描述

如果,增加一个载体,效果如图:
在这里插入图片描述

相比于hash算法取模运算,一致性hash算法的好处在于,在增加或减少载体的时候,hash只是将该载体前的载体。

如果载体过少,可能会出现数据严重偏移的情况,这种情况我们可以设置多个虚拟节点,每个虚拟节点会对应相应的载体。比如载体1A,载体1B,载体1C,载体2A,载体2B,载体2C,载体3A,载体3B,载体3C,载体4A,载体4B,载体4C。
我们可以将数据定位到这些虚拟节点上,然后,找到虚拟节点所对应的载体。即可定位到数据所在的载体。

  1. php代码实现
<?php

/**
 * 具体一致性哈希算法实现
 *
 */

class Hashrealize{
	//载体列表
	public $carrierList = array();
	//节点列表
	public $virtualNodeList = array();
	//每个载体虚拟节点数量
	public $virtualNumber = 5;

	/**
	 * hash算法
	 */
	
	private function hashAlgorithm($key){
		$string = md5($key); 
		return sprintf('%u', crc32($string));
	}

	/**
	 * 查找节点
	 */
	public  function lookNode($key){
		$string = $this->hashAlgorithm($key);
		$carrier = '';
		foreach($this->virtualNodeList as $hashStringVirtual =>$val){
			if($string < $hashStringVirtual){
				$carrier = $val;
				break;
			}
		}

		return $carrier;
	}

	/**
	 * 添加载体
	 */
	public function addCarrier($carrier){
		if(!$this->carrierList[$carrier]){
			$hashString = $this->hashAlgorithm($carrier);
			for($i=0;$i<$this->virtualNumber;$i++){
				$hashStringVirtual = $this->hashAlgorithm($carrier.'_'.$i);
				$this->virtualNodeList[$hashStringVirtual] = $carrier;
				$this->carrierList[$carrier][] = $hashStringVirtual;
			}
			ksort($this->virtualNodeList,SORT_NUMERIC);
		}
		if($this->carrierList[$carrier]){
			return true;
		}else{
			return false;
		}
	}

	/**
	 * 移除载体
	 */
	public function removeCarrier($carrier){
		if($this->carrierList[$carrier]){
			foreach($this->virtualNodeList[$carrier] as $key =>$val){
				unset($this->virtualNodeList[$carrier][$key]);
			}
			unset($this->carrierList[$carrier]);			
		}
	}
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值