散列表的应用

涉及到数据查找比对,首先考虑到使用HashSet。HashSet最大的好处就是实现查找时间复杂度为O(1)。使用HashSet需要解决一个重要问题:冲突问题。对比研究了网上一些字符串哈希函数,发现几乎所有的流行的HashMap都采用了DJB Hash Function,俗称“Times33”算法。Times33的算法很简单,就是对字符串逐字符迭代乘以33,见下面算法原型:hash(i)=33*hash(i-1)+str[i]

使用HashSet需要解决一个重要问题:冲突问题。对比研究了网上一些字符串哈希函数,发现几乎所有的流行的HashMap都采用了DJB Hash Function,俗称“Times33”算法。Times33的算法很简单,就是对字符串逐字符迭代乘以33,见下面算法原型:hash(i)=33*hash(i-1)+str[i]

<?php
// +----------------------------------------------------------------------
// | Perfect Is Shit
// +----------------------------------------------------------------------
// | PHP实现:一致性HASH算法
// +----------------------------------------------------------------------
// | Author: alexander <gt199899@gmail.com>
// +----------------------------------------------------------------------
// | Datetime: 2017-01-11 16:01:36
// +----------------------------------------------------------------------
// | Copyright: Perfect Is Shit
// +---------------------------------------------------------------------- class ConsistentHashing
{
// 圆环
// hash -> 节点
private $_ring = array();
// 所有节点
// 节点 -> hash
public $nodes = array();
// 每个节点的虚拟节点
public $virtual = 64; /**
* 构造
* @param array $nodes 初始化的节点列表
*/
public function __construct($nodes = array())
{
if (!empty($nodes)) {
foreach ($nodes as $value) {
$this->addNode($value);
}
}
} /**
* 获取圆环内容
* @return array $this->_ring
*/
public function getRing()
{
return $this->_ring;
} /**
* time33 函数
* @param string $str
* @return 32位正整数
* @author 大神们
*/
public function time33($str)
{
// hash(i) = hash(i-1) * 33 + str[i]
// $hash = 5381; ## 将hash设置为0,竟然比设置为5381分布效果更好!!!
$hash = 0;
//
$s = md5($str); //相比其它版本,进行了md5加密
$seed = 5;
$len = 32;//加密后长度32
for ($i = 0; $i < $len; $i++) {
// (hash << 5) + hash 相当于 hash * 33
//$hash = sprintf("%u", $hash * 33) + ord($s{$i});
//$hash = ($hash * 33 + ord($s{$i})) & 0x7FFFFFFF;
$hash = ($hash << $seed) + $hash + ord($s{$i});
}
return $hash & 0x7FFFFFFF;
} /**
* 增加节点
* @param string $node 节点名称
* @return object $this
*/
public function addNode($node)
{
if (in_array($node, array_keys($this->nodes))) {
return;
}
for ($i = 1; $i <= $this->virtual; $i++) {
$key = $this->time33($node . '-' . $i);
$this->_ring[$key] = $node;
$this->nodes[$node][] = $key;
}
ksort($this->_ring, SORT_NUMERIC);
return $this;
} /**
* 获取字符串的HASH在圆环上面映射到的节点
* @param string $key
* @return string $node
*/
public function getNode($key)
{
$node = current($this->_ring);
$hash = $this->time33($key);
foreach ($this->_ring as $key => $value) {
if ($hash <= $key) {
$node = $value;
break;
}
}
return $node;
} /**
* 获取映射到特定节点的KEY
* 此方法需手动调用,非特殊情况不建议程序中使用此方法
* @param string $node
* @param string $keyPre
* @return mixed
*/
public function getKey($node, $keyPre = "")
{
if (!in_array($node, array_keys($this->nodes))) {
return false;
}
$result = false;
for ($i = 1; $i <= 10000; $i++) {
$key = $keyPre . md5(rand(1000, 9999));
if ($this->getNode($key) == $node) {
$result = true;
break;
}
}
return $result ? $key : false;
} } $ch_obj = new ConsistentHashing();
$ch_obj->addNode('node_1');
$ch_obj->addNode('node_2');
$ch_obj->addNode('node_3');
$ch_obj->addNode('node_4');
$ch_obj->addNode('node_5');
$ch_obj->addNode('node_6'); // +----------------------------------------------------------------------
// | 查看key映射到的节点
// +----------------------------------------------------------------------
$key1 = "asofiwjamfdalksjfkasasdflasfja";
$key2 = "jaksldfjlasfjsdjfioafaslkjflsadkjfl";
$key3 = "asjldflkjasfsdjflkajkldsjfksajdlflajs";
$key4 = "iowanfasijfmasdnfoas";
$key5 = "pqkisndfhoalnfiewlkl";
$key6 = "qjklasjdifoajfalsjflsa";
echo sprintf("%-50s 映射到节点 %s\n", $key1, $ch_obj->getNode($key1));
echo sprintf("%-50s 映射到节点 %s\n", $key2, $ch_obj->getNode($key2));
echo sprintf("%-50s 映射到节点 %s\n", $key3, $ch_obj->getNode($key3));
echo sprintf("%-50s 映射到节点 %s\n", $key4, $ch_obj->getNode($key4));
echo sprintf("%-50s 映射到节点 %s\n", $key5, $ch_obj->getNode($key5));
echo sprintf("%-50s 映射到节点 %s\n", $key6, $ch_obj->getNode($key6)); // +----------------------------------------------------------------------
// | 查看圆环和节点信息
// +----------------------------------------------------------------------
echo '<pre>';
var_dump($ch_obj->getRing());
var_dump($ch_obj->nodes); // +----------------------------------------------------------------------
// | 获取特定节点的KEY
// +----------------------------------------------------------------------
// $key1 = $ch_obj->getKey('node_1', 'pre_');
// var_dump($key1); // +----------------------------------------------------------------------
// | 测试分布
// +----------------------------------------------------------------------
// $keys = array();
// $rings = array();
// for ($i = 1; $i <= 60000; $i++) {
// $key = sha1(rand(1000000,9999999));
// $node = $ch_obj->getNode($key);
// $rings[$node] = isset($rings[$node]) ? ++$rings[$node] : 1;
// }
// var_dump($rings);

php 实现一致性hash 算法 memcache的更多相关文章

  1. memcache的一致性hash算法使用

    一.概述 1.我们的memcache客户端(这里我看的spymemcache的源码),使用了一致性hash算法ketama进行数据存储节点的选择.与常规的hash算法思路不同,只是对我们要存储数据的k ...

  2. Nginx+Memcache+一致性hash算法 实现页面分布式缓存(转)

    网站响应速度优化包括集群架构中很多方面的瓶颈因素,这里所说的将页面静态化.实现分布式高速缓存就是其中的一个很好的解决方案... 1)先来看看Nginx负载均衡 Nginx负载均衡依赖自带的 ngx_h ...

  3. 对一致性Hash算法,Java代码实现的深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...

  4. 一致性hash算法简介与代码实现

    一.简介: 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 1.平衡性(Balance) 2.单调性(Monotonicity) 3.分散性(Spread) 4.负 ...

  5. Java实现一致性Hash算法深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中”一致性Hash算法”部分,对于为什么要使用一致性Hash算法和一致性Hash算法的算法原 ...

  6. 对一致性Hash算法及java实现(转)

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...

  7. 对一致性Hash算法,Java代码实现的深入研究(转)

    转载:http://www.cnblogs.com/xrq730/p/5186728.html 一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读 ...

  8. 【转载】对一致性Hash算法,Java代码实现的深入研究

    原文地址:http://www.cnblogs.com/xrq730/p/5186728.html 一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细 ...

  9. 一致性hash算法在memcached中的使用

    一.概述 1.我们的memcacheclient(这里我看的spymemcache的源代码).使用了一致性hash算法ketama进行数据存储节点的选择.与常规的hash算法思路不同.仅仅是对我们要存 ...

随机推荐

  1. css冲刺

    CSS知识点及面试题 1.一般与文本相关的属性都可以继承text-/font-/line- 2.background属性1)background-repeat:repeat/repeat-x/repe ...

  2. canvas/CSS仪表盘效果

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. IIS7常见错误及解决方法

    IIS7常见错误及解决方法   问题一:HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效.  详细错误信息模块 IIS We ...

  4. ReactNative如何在JS中引用原生自定义控件(rn变化太快,网上很多教程有坑,这个我研究后可用,特意分享)

    直接写一个Demo例子,有相关功底的肯定明白,会对特别的地方进行提醒,本文基于https://blog.csdn.net/lintcgirl/article/details/53489490,但是按此 ...

  5. 对于eclipse building workspaces 慢的问题,解决方法

    在项目根目录中有个.project文件,将其中的: <buildCommand> <name>org.eclipse.wst.jsdt.core.javascriptValid ...

  6. Compiler Error: Function call with parameters that may be unsafe

    如下的代码: #include <stdio.h> #include <string> #include <algorithm> #include <cass ...

  7. docker pureftpd

    pureftpd: image: vimagick/pure-ftpd ports: - "21:21" volumes: - ./data/ftpuser:/home/ftpus ...

  8. Keras运行速度越来越慢的问题

    Keras运行迭代一定代数以后,速度越来越慢,经检查是因为在循环迭代过程中增加了新的计算节点,导致计算节点越来越多,内存被占用完,速度变慢.判断是否在循环迭代过程中增加了新的计算节点,可以用下面的语句 ...

  9. SpringBoot2.0小程序支付功能实现weixin-java-pay

    SpringBoot2.0小程序支付功能实现weixin-java-pay WxJava - 微信开发 Java SDK(开发工具包); 支持包括微信支付.开放平台.公众号.企业微信/企业号.小程序等 ...

  10. 每天一个linux命令:free

    1.命令简介 free (free) 命令可以显示Linux系统中空闲的.已用的物理内存及swap内存,及被内核使用的buffer. 2.用法 free [-b | -k | -m | -g | -h ...