一致性Hash类。属于InitPHP框架扩展类,需要通过$this->getLibrary()方法获取
$hash = $this->getLibrary('hash');
$hash = $this->getLibrary('hash');
//添加node节点,10代表虚拟节点个数,虚拟节点数目越大,hash分布越均匀
//为了控制hash效率,将固定节点值存放在hash_table.php文件里面
//类文件中有2个参数可以配置 //private $is_init = 1;
//hash_table初始化-0关闭,1开启,当初始化完毕之后,关闭该功能
//private $filename = 'data/hash_table.php';
//hash_table缓存路径
$hash->add_node(array('192.168.1.1', '192.168.1.2', '192.168.1.3'), 10);
//获取key值对应的一致性hash_table上的node节点 echo $hash->get_node('woshishen');
//输出192.168.1.3,说明该key分布式这个服务器上
echo $hash->get_node('woshishen'); //输出192.168.1.3,说明该key分布式这个服务器上
if (!defined('IS_INITPHP')) exit('Access Denied!');
/*********************************************************************************
* InitPHP 2.1 国产PHP开发框架 扩展类库-一致性HASH
*-------------------------------------------------------------------------------
* 版权所有: CopyRight By initphp.com
* 您可以自由使用该源码,但是在使用过程中,请保留作者信息。尊重他人劳动成果就是尊重自己
*-------------------------------------------------------------------------------
* $Author:zhuli
* $Dtime:2011-10-09
***********************************************************************************/
class hashInit {
private static $hash_table = array(); //hash_table,存放hash对应值
private static $hash_list = array(); //存放值
private $is_init = 1; //hash_table初始化-0关闭,1开启,当初始化完毕之后,关闭该功能
private $filename = 'data/hash_table.php'; //hash_table缓存路径
/**
* 一致性hash:添加节点
* 只有当且仅当开启is_init初始化hash_table的时候
* hash_table文件才会生成
* @param string $node 字符串
* @param string $num 虚拟节点
* @return int
*/
public function add_node($node, $num = 0) {
if ($this->is_init == 1) {
if (is_array($node)) {
foreach ($node as $string) {
$key = $this->hash_md5($string);
self::$hash_table[$this->hash_crc($key)] = array(
$key,
$string
);
$this->add_virtual_node($string, $num);
self::$hash_list[] = $this->hash_crc($key);
}
sort(self::$hash_list);
}
$table = '$hash_table = ' . var_export(self::$hash_table, TRUE) . ';';
$list = '$hash_list = ' . var_export(self::$hash_list, TRUE);
$value = '';
@file_put_contents($this->filename, $value);
}
return true;
}
/**
* 一致性hash:获取hash对应的节点值
* @param string $node 字符串
* @return int
*/
public function get_node($string) {
$key = $this->hash_md5($string);
$key_val = $this->hash_crc($key);
$result = $start = 0;
if (empty(self::$hash_table) && empty(self::$hash_list)) {
include_once($this->filename);
self::$hash_table = $hash_table;
self::$hash_list = $hash_list;
}
foreach (self::$hash_list as $val) {
if ($start == 0) $result = $val;
if ($key_val < $val) {
$result = $val;
break;
}
$start = 1;
}
return self::$hash_table[$result][1];
}
/**
* 一致性hash:生成虚拟节点
* @param string $string 字符串
* @param string $num 虚拟节点
* @return int
*/
public function add_virtual_node($string, $num) {
$num = (int) $num;
if ($num < 1) return false;
for ($i=0; $i<$num; $i++) {
$key = $this->hash_md5($string . '#' . $i);
self::$hash_table[$this->hash_crc($key)] = array($key, $string);
self::$hash_list[] = $this->hash_crc($key);
}
}
/**
* 一致性hash,计算一个字符串的 crc32 多项式
* @param string $string 字符串
* @return int
*/
private function hash_crc($string) {
return crc32($string);
}
/**
* 一致性hash:MD5加密得到KEY值
* @param string $string 字符串
* @return int
*/
private function hash_md5($string) {
return md5($string);
}
}