Redis一致性hash(php版)

PHP实现一致性hash 随着memcache、redis以及其它一些内存K/V数据库的流行,一致性哈希也越来越被开发者所了解。因为这些内存K/V数据库大多不提供分布式支持(本文以redis为例),所以如果要提供多台redis server来提供服务的话,就需要解决如何将数据分散到redis server,并且在增减redis server时如何最大化的不令数据重新分布,这将是本文讨论的范畴。   取模算法   取... 阅读详情
一致性hash的使用在PHP中有三种选择分别是原生的memcache扩展,memcached扩展,还有一个是网上比较流行的flexihash类。前两者都适用于memcache但不适合Redis。

php一致性hash类下载地址:http://code.google.com/p/flexihash/

我们根据flexihash的应该改写了一遍Redis的应用。

下面给出测试源码:

flexihash.php
[php]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <?php  
  2. /** 
  3.  * Flexihash - A simple consistent hashing implementation for PHP. 
  4.  * 
  5.  * The MIT License 
  6.  * 
  7.  * Copyright (c) 2008 Paul Annesley 
  8.  * 
  9.  * Permission is hereby granted, free of charge, to any person obtaining a copy 
  10.  * of this software and associated documentation files (the "Software"), to deal 
  11.  * in the Software without restriction, including without limitation the rights 
  12.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
  13.  * copies of the Software, and to permit persons to whom the Software is 
  14.  * furnished to do so, subject to the following conditions: 
  15.  * 
  16.  * The above copyright notice and this permission notice shall be included in 
  17.  * all copies or substantial portions of the Software. 
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
  20.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
  22.  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
  23.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
  24.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
  25.  * THE SOFTWARE. 
  26.  * 
  27.  * @author Paul Annesley 
  28.  * @link http://paul.annesley.cc/ 
  29.  * @copyright Paul Annesley, 2008 
  30.  * @comment by MyZ (http://blog.youkuaiyun.com/mayongzhan) 
  31.  */  
  32.   
  33. /** 
  34.  * A simple consistent hashing implementation with pluggable hash algorithms. 
  35.  * 
  36.  * @author Paul Annesley 
  37.  * @package Flexihash 
  38.  * @licence http://www.opensource.org/licenses/mit-license.php 
  39.  */  
  40. class flexihash  
  41. {  
  42.   
  43.     /** 
  44.      * The number of positions to hash each target to. 
  45.      * 
  46.      * @var int 
  47.      * @comment 虚拟节点数,解决节点分布不均的问题 
  48.      */  
  49.     private $_replicas = 64;  
  50.   
  51.     /** 
  52.      * The hash algorithm, encapsulated in a Flexihash_Hasher implementation. 
  53.      * @var object Flexihash_Hasher 
  54.      * @comment 使用的hash方法 : md5,crc32 
  55.      */  
  56.     private $_hasher;  
  57.   
  58.     /** 
  59.      * Internal counter for current number of targets. 
  60.      * @var int 
  61.      * @comment 节点记数器 
  62.      */  
  63.     private $_targetCount = 0;  
  64.   
  65.     /** 
  66.      * Internal map of positions (hash outputs) to targets 
  67.      * @var array { position => target, ... } 
  68.      * @comment 位置对应节点,用于lookup中根据位置确定要访问的节点 
  69.      */  
  70.     private $_positionToTarget = array();  
  71.   
  72.     /** 
  73.      * Internal map of targets to lists of positions that target is hashed to. 
  74.      * @var array { target => [ position, position, ... ], ... } 
  75.      * @comment 节点对应位置,用于删除节点 
  76.      */  
  77.     private $_targetToPositions = array();  
  78.   
  79.     /** 
  80.      * Whether the internal map of positions to targets is already sorted. 
  81.      * @var boolean 
  82.      * @comment 是否已排序 
  83.      */  
  84.     private $_positionToTargetSorted = false;  
  85.   
  86.     /** 
  87.      * Constructor 
  88.      * @param object $hasher Flexihash_Hasher 
  89.      * @param int $replicas Amount of positions to hash each target to. 
  90.      * @comment 构造函数,确定要使用的hash方法和需拟节点数,虚拟节点数越多,分布越均匀,但程序的分布式运算越慢 
  91.      */  
  92.     public function __construct(Flexihash_Hasher $hasher = null, $replicas = null)  
  93.     {  
  94.         $this->_hasher = $hasher ? $hasher : new Flexihash_Crc32Hasher();  
  95.         if (!empty($replicas)) $this->_replicas = $replicas;  
  96.     }  
  97.   
  98.     /** 
  99.      * Add a target. 
  100.      * @param string $target 
  101.      * @chainable 
  102.      * @comment 添加节点,根据虚拟节点数,将节点分布到多个虚拟位置上 
  103.      */  
  104.     public function addTarget($target)  
  105.     {  
  106.         if (isset($this->_targetToPositions[$target]))  
  107.         {  
  108.             throw new Flexihash_Exception("Target '$target' already exists.");  
  109.         }  
  110.   
  111.         $this->_targetToPositions[$target] = array();  
  112.   
  113.         // hash the target into multiple positions  
  114.         for ($i = 0; $i < $this->_replicas; $i++)  
  115.         {  
  116.             $position = $this->_hasher->hash($target . $i);  
  117.             $this->_positionToTarget[$position] = $target; // lookup  
  118.             $this->_targetToPositions[$target] []= $position; // target removal  
  119.         }  
  120.   
  121.         $this->_positionToTargetSorted = false;  
  122.         $this->_targetCount++;  
  123.   
  124.         return $this;  
  125.     }  
  126.   
  127.     /** 
  128.      * Add a list of targets. 
  129.      * @param array $targets 
  130.      * @chainable 
  131.      */  
  132.     public function addTargets($targets)  
  133.     {  
  134.         foreach ($targets as $target)  
  135.         {  
  136.             $this->addTarget($target);  
  137.         }  
  138.   
  139.         return $this;  
  140.     }  
  141.   
  142.     /** 
  143.      * Remove a target. 
  144.      * @param string $target 
  145.      * @chainable 
  146.      */  
  147.     public function removeTarget($target)  
  148.     {  
  149.         if (!isset($this->_targetToPositions[$target]))  
  150.         {  
  151.             throw new Flexihash_Exception("Target '$target' does not exist.");  
  152.         }  
  153.   
  154.         foreach ($this->_targetToPositions[$target] as $position)  
  155.         {  
  156.             unset($this->_positionToTarget[$position]);  
  157.         }  
  158.   
  159.         unset($this->_targetToPositions[$target]);  
  160.   
  161.         $this->_targetCount--;  
  162.   
  163.         return $this;  
  164.     }  
  165.   
  166.     /** 
  167.      * A list of all potential targets 
  168.      * @return array 
  169.      */  
  170.     public function getAllTargets()  
  171.     {  
  172.         return array_keys($this->_targetToPositions);  
  173.     }  
  174.   
  175.     /** 
  176.      * Looks up the target for the given resource. 
  177.      * @param string $resource 
  178.      * @return string 
  179.      */  
  180.     public function lookup($resource)  
  181.     {  
  182.         $targets = $this->lookupList($resource, 1);  
  183.         if (empty($targets)) throw new Flexihash_Exception('No targets exist');  
  184.         return $targets[0];  
  185.     }  
  186.   
  187.     /** 
  188.      * Get a list of targets for the resource, in order of precedence. 
  189.      * Up to $requestedCount targets are returned, less if there are fewer in total. 
  190.      * 
  191.      * @param string $resource 
  192.      * @param int $requestedCount The length of the list to return 
  193.      * @return array List of targets 
  194.      * @comment 查找当前的资源对应的节点, 
  195.      *          节点为空则返回空,节点只有一个则返回该节点, 
  196.      *          对当前资源进行hash,对所有的位置进行排序,在有序的位置列上寻找当前资源的位置 
  197.      *          当全部没有找到的时候,将资源的位置确定为有序位置的第一个(形成一个环) 
  198.      *          返回所找到的节点 
  199.      */  
  200.     public function lookupList($resource, $requestedCount)  
  201.     {  
  202.         if (!$requestedCount)  
  203.             throw new Flexihash_Exception('Invalid count requested');  
  204.   
  205.         // handle no targets  
  206.         if (empty($this->_positionToTarget))  
  207.             return array();  
  208.   
  209.         // optimize single target  
  210.         if ($this->_targetCount == 1)  
  211.             return array_unique(array_values($this->_positionToTarget));  
  212.   
  213.         // hash resource to a position  
  214.         $resourcePosition = $this->_hasher->hash($resource);  
  215.   
  216.         $results = array();  
  217.         $collect = false;  
  218.   
  219.         $this->_sortPositionTargets();  
  220.   
  221.         // search values above the resourcePosition  
  222.         foreach ($this->_positionToTarget as $key => $value)  
  223.         {  
  224.             // start collecting targets after passing resource position  
  225.             if (!$collect && $key > $resourcePosition)  
  226.             {  
  227.                 $collect = true;  
  228.             }  
  229.   
  230.             // only collect the first instance of any target  
  231.             if ($collect && !in_array($value, $results))  
  232.             {  
  233.                 $results []= $value;  
  234.             }  
  235.   
  236.             // return when enough results, or list exhausted  
  237.             if (count($results) == $requestedCount || count($results) == $this->_targetCount)  
  238.             {  
  239.                 return $results;  
  240.             }  
  241.         }  
  242.   
  243.         // loop to start - search values below the resourcePosition  
  244.         foreach ($this->_positionToTarget as $key => $value)  
  245.         {  
  246.             if (!in_array($value, $results))  
  247.             {  
  248.                 $results []= $value;  
  249.             }  
  250.   
  251.             // return when enough results, or list exhausted  
  252.             if (count($results) == $requestedCount || count($results) == $this->_targetCount)  
  253.             {  
  254.                 return $results;  
  255.             }  
  256.         }  
  257.   
  258.         // return results after iterating through both "parts"  
  259.         return $results;  
  260.     }  
  261.   
  262.     public function __toString()  
  263.     {  
  264.         return sprintf(  
  265.             '%s{targets:[%s]}',  
  266.             get_class($this),  
  267.             implode(',', $this->getAllTargets())  
  268.         );  
  269.     }  
  270.   
  271.     // ----------------------------------------  
  272.     // private methods  
  273.   
  274.     /** 
  275.      * Sorts the internal mapping (positions to targets) by position 
  276.      */  
  277.     private function _sortPositionTargets()  
  278.     {  
  279.         // sort by key (position) if not already  
  280.         if (!$this->_positionToTargetSorted)  
  281.         {  
  282.             ksort($this->_positionToTarget, SORT_REGULAR);  
  283.             $this->_positionToTargetSorted = true;  
  284.         }  
  285.     }  
  286.   
  287. }  
  288.   
  289.   
  290. /** 
  291.  * Hashes given values into a sortable fixed size address space. 
  292.  * 
  293.  * @author Paul Annesley 
  294.  * @package Flexihash 
  295.  * @licence http://www.opensource.org/licenses/mit-license.php 
  296.  */  
  297. interface Flexihash_Hasher  
  298. {  
  299.   
  300.     /** 
  301.      * Hashes the given string into a 32bit address space. 
  302.      * 
  303.      * Note that the output may be more than 32bits of raw data, for example 
  304.      * hexidecimal characters representing a 32bit value. 
  305.      * 
  306.      * The data must have 0xFFFFFFFF possible values, and be sortable by 
  307.      * PHP sort functions using SORT_REGULAR. 
  308.      * 
  309.      * @param string 
  310.      * @return mixed A sortable format with 0xFFFFFFFF possible values 
  311.      */  
  312.     public function hash($string);  
  313.   
  314. }  
  315.   
  316.   
  317. /** 
  318.  * Uses CRC32 to hash a value into a signed 32bit int address space. 
  319.  * Under 32bit PHP this (safely) overflows into negatives ints. 
  320.  * 
  321.  * @author Paul Annesley 
  322.  * @package Flexihash 
  323.  * @licence http://www.opensource.org/licenses/mit-license.php 
  324.  */  
  325. class Flexihash_Crc32Hasher  
  326.     implements Flexihash_Hasher  
  327. {  
  328.   
  329.     /* (non-phpdoc) 
  330.      * @see Flexihash_Hasher::hash() 
  331.      */  
  332.     public function hash($string)  
  333.     {  
  334.         return crc32($string);  
  335.     }  
  336.   
  337. }  
  338.   
  339.   
  340. /** 
  341.  * Uses CRC32 to hash a value into a 32bit binary string data address space. 
  342.  * 
  343.  * @author Paul Annesley 
  344.  * @package Flexihash 
  345.  * @licence http://www.opensource.org/licenses/mit-license.php 
  346.  */  
  347. class Flexihash_Md5Hasher  
  348.     implements Flexihash_Hasher  
  349. {  
  350.   
  351.     /* (non-phpdoc) 
  352.      * @see Flexihash_Hasher::hash() 
  353.      */  
  354.     public function hash($string)  
  355.     {  
  356.         return substr(md5($string), 0, 8); // 8 hexits = 32bit  
  357.   
  358.         // 4 bytes of binary md5 data could also be used, but  
  359.         // performance seems to be the same.  
  360.     }  
  361.   
  362. }  
  363.   
  364.   
  365. /** 
  366.  * An exception thrown by Flexihash. 
  367.  * 
  368.  * @author Paul Annesley 
  369.  * @package Flexihash 
  370.  * @licence http://www.opensource.org/licenses/mit-license.php 
  371.  */  
  372. class Flexihash_Exception extends Exception  
  373. {  
  374. }  


flexihash_redis.php
[php]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <?php  
  2. require 'flexihash.php';  
  3. Class FRedis  
  4. {  
  5.     public $hash = null;  
  6.     public $memcache = null;  
  7.     public $connectPool = null;  
  8.     public $timeOut = 3;  
  9.     public $auth = "";  
  10.    
  11.     public function __construct()  
  12.     {  
  13.         $this->hash = new Flexihash();  
  14.     }  
  15.    
  16.     public function addServers( $servers )  
  17.     {  
  18.         foreach ($servers as $server)  
  19.         {  
  20.             $node = $server['host'] . ':' . $server['port'];  
  21.             $this->connectPool[$node] = false;  
  22.             $targets[] = $node;  
  23.         }  
  24.         $this->hash->addTargets( $targets );  
  25.           
  26.     }  
  27.    
  28.     public function hset($hashkey, $valuekey, $value )  
  29.     {  
  30.         $node = $this->hash->lookup( $hashkey, count( $this->connectPool ) );  
  31.         if (!$this->connectPool[$node])  
  32.         {  
  33.             $server = explode( ':', $node );  
  34.             $redis = new Redis();  
  35.             $redis->connect($server[0], $server[1], $this->timeOut);  
  36.             if(!empty($this->auth)){  
  37.                 $redis->auth($this->auth);  
  38.             }  
  39.             $this->connectPool[$node] = $redis;  
  40.   
  41.         }  
  42.         if ($this->connectPool[$node])  
  43.         {  
  44.             $redis = $this->connectPool[$node];  
  45.             if($redis->hset($hashkey,$valuekey,$value)){  
  46.                 return true;  
  47.             }  
  48.         }  
  49.         return false;  
  50.     }  
  51.    
  52.     public function hget( $hashkey, $valuekey )  
  53.     {  
  54.         $node = $this->hash->lookup( $hashkey, count( $this->connectPool ) );  
  55.           
  56.         if (!$this->connectPool[$node])  
  57.         {  
  58.             $server = explode( ':', $node );  
  59.             $redis = new Redis();  
  60.             $redis->connect($server[0], $server[1], $this->timeOut);  
  61.             if(!empty($this->auth)){  
  62.                 $redis->auth($this->auth);  
  63.             }  
  64.             $this->connectPool[$node] = $redis;  
  65.           
  66.         }  
  67.         if ($this->connectPool[$node])  
  68.         {  
  69.             $redis = $this->connectPool[$node];  
  70.             if($value = $redis->hget($hashkey,$valuekey)){  
  71.                 return $value;  
  72.             }  
  73.         }  
  74.         return false;  
  75.     }  
  76. }  

FRedis_test.php
[php]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <?php  
  2. require_once 'flexihash_redis.php';  
  3. $st = microtime( true );  
  4. $fredis = new FRedis();  
  5. $tt_server_pool = array(  
  6.     '0' => array(  
  7.         'host' => '192.168.75.128',  
  8.         'port' => '6379',  
  9.     ),  
  10.     '1' => array(  
  11.         'host' => '192.168.75.130',  
  12.         'port' => '6379',  
  13.     ),  
  14. );  
  15. $fredis->addServers( $tt_server_pool );  
  16.   
  17. for($i=0;$i<10;$i++){  
  18.     for($k=0;$k<10;$k++){  
  19.         $fredis->hset("hashkey:".$i,"valuekey".$k,md5($i*$k));  
  20.     }  
  21. }  
  22.   
  23. $et = microtime( true ) - $st;  
  24. echo "time used:" . $et."<br/>";  
  25. echo $fredis->hget("hashkey:0","valuekey9");  

Redis版哈希函数类:

[php]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <?php  
  2. class UniqueHashService{  
  3.     private static $len; //64位  
  4.     private static $loop = 1; //循环次数  
  5.     private $prefix = '';  
  6.       
  7.     public function __construct() {  
  8.         if(empty(self::$len)){  
  9.             self::$len = abs(1 << 0x3f); //左移63位  
  10.         }  
  11.           
  12.     }  
  13.       
  14.     /** 
  15.      * 获取字符串的哈希值 
  16.      */  
  17.     public function hashing($key){  
  18.         return abs((('0x'.hash('crc32',$key).hash('crc32b',$key)) + 0)) % self::$len;  
  19.     }  
  20.       
  21.     /** 
  22.      * 获取到redis hash 的键名 
  23.      * @param type $str 
  24.      */  
  25.     public function getRedisKey($str, $prefix){  
  26.         //前缀  
  27.         $this->prefix = $prefix;  
  28.           
  29.         $hstr = $this->hashing($str);    //获取一个字符串的哈希值  
  30.           
  31.         //如果字符串长度小于6,往字符串左侧填充0,填充至6位长度。  
  32.         if(strlen($hstr) < 6){  
  33.             $hstr = str_pad($hstr, 6, '0', STR_PAD_LEFT);  
  34.         }  
  35.         $kbin = $this->str2Bin($hstr);  //计算hash key的二进制,$hstr的二进制  
  36.           
  37.         $karr = explode(' ', $kbin);  
  38.           
  39.         //数组长度  
  40.         $kcount = count($karr);  
  41.           
  42.         $kcount_mid = ceil($kcount/2);  
  43.           
  44.         $redis_key = $this->prefix; //排重表前缀  
  45.           
  46.         //循环次数  
  47.         $i = 0;  
  48.         while(1){  
  49.             if($i > self::$loop){  
  50.                 break;  
  51.             }  
  52.               
  53.             //组装redis键  
  54.             $redis_key .= ':'.$this->returnHashKey($karr[$i]);  
  55.             $redis_key .= ':'.$this->returnHashKey($karr[$kcount_mid+$i]);  
  56.             $redis_key .= ':'.$this->returnHashKey($karr[$kcount-1-$i]);  
  57.               
  58.             ++$i;  
  59.         }  
  60.           
  61.         return $redis_key;  
  62.     }  
  63.       
  64.     /** 
  65.      * 截取二进制字符串中的一部分 
  66.      * @param type $sbin 
  67.      * @return type 
  68.      */  
  69.     private function returnHashKey($sbin){  
  70.         return substr($sbin, -2, 2);  
  71.     }  
  72.       
  73.     /** 
  74.      * 把给定的字符串中的每个字符转为二进制,并以空格连接每个二进制字符串并返回。 
  75.      * @param string $hstr 
  76.      * @return type 
  77.      */  
  78.     private function str2Bin($str){  
  79.         //把字符串拆分成数组,每个字符为数组中的一个元素。  
  80.         $arr = str_split($str);  
  81.           
  82.         //把数组中的每个字符转成二进制  
  83.         foreach($arr as &$v){  
  84.             $tmp = unpack('H*', $v);        //把字符解包为16进制  
  85.             $v = base_convert($tmp[1],16,2);//把16进制转为2进制  
  86.             unset($tmp);  
  87.         }  
  88.           
  89.         //把二进制字符串数组以空格连接在一起并返回  
  90.         $bin = join(' ',$arr);  
  91.         unset($arr);  
  92.         return $bin;  
  93.     }  
  94.       
  95.     /** 
  96.      * 把$this->str2Bin 处理过的字符串还原 
  97.      * @param string $bin 二进制字符串 
  98.      * @return type 
  99.      */  
  100.     private function bin2Str($bin){  
  101.         //把字符串拆分成数组,以空拆分。  
  102.         $arr = explode(' ', $bin);  
  103.           
  104.         foreach($arr as &$v){  
  105.             $tmp = base_convert($v, 2, 16);     //二进制转换成16进制  
  106.             $v = pack('H'.strlen($tmp), $tmp);  //把16进制打包成二进制字符串  
  107.             unset($tmp);  
  108.         }  
  109.           
  110.         return join('', $arr);  
  111.     }  
  112. }  
一致性哈希(php版) 一致性哈希算法的php版,希望能帮到phper了解一致性哈希 立即下载

相关推荐

针对so层不固定位置的动态加密,怎么解决?(面试题)

Android逆向之破解某应用加密算法(动态调试so和hook so代码):so 代码动态解密后才执行,我们可以在解密完成后获取解密后的代码或数据。Android逆向之旅—动态方式破解apk进阶篇(IDA调试so源码)如果你有更具体的加密场景,欢迎提供更多信息,我可以给出更详细的方案!某些 so 在运行时生成密钥,解密后再用。某APP密码加密算法分析。

SXXYNHHXX的博客 927

一致性哈希 php redis,使用一致性哈希实现Redis分布式部署

1要解决的问题:像Memcache以及其它一些内存K/V数据库一样,Redis本身不提供分布式支持,所以在部署多台Redis服务器时,就需要解决如何把数据分散到各个服务器的问题,并且在服务器数量变化时,能做到最大程度的不令数据重新分布。通常使用的分布式方法是根据所要存储数据的键的hash值与服务器数量N,按 hash % N 取模的算法来将数据分布到各个服务器。该算法的优点是足够简单,而且数据分布...

weixin_39632467的博客 169

unity人物刚体移动_Unity3D实现2D人物移动-总结篇

背景最近研究Unity3d,2d寻路的实现。所以又一次涉及到了角色坐标位移的问题。系统的对于角色鼠标点击移动这个简单问题进行整理和总结。本来就是一个简单的几何问题,结果发现已经有两个小坑,顺便填上,这里做下总结。实现需求:通过鼠标点击,控制2d角色移动,就是点哪里,角色向移动到哪里问题分解:按照时间进行动画分解,鼠标输入(动画开始)、平移(动画进行)、移动结束(动画结束)前提:这里前面的文章基本解...

weixin_39610366的博客 1277

PHP: 深入了解一致性哈希

为什么80%的码农都做不了架构师?>>> ...

weixin_34087503的博客 270

MATLAB实战:手把手教你搭建构网逆变器同步稳定性仿真模型(附避坑指南)

本文详细介绍了如何在MATLAB/Simulink平台上搭建构网逆变器同步稳定性仿真模型,涵盖从基础模块配置到虚拟同步机控制实现的完整流程。针对电力电子工程师常见的控制参数整定困难、仿真结果偏差等问题,提供了LCL滤波器谐振抑制、虚拟惯量优化等关键技术解决方案,并附有避坑指南和工程实践技巧,助力研究者高效完成仿真建模。

weixin_29051193的博客 298

ESP32小车DIY:从零搭建无线遥控智能车(附完整代码与避坑指南)

本文详细介绍了如何从零开始DIY一台基于ESP32的无线遥控智能小车。内容涵盖核心硬件选型、电路设计、低延迟ESP-NOW无线通信协议的配置与实战,以及双电机差速控制算法与PWM调速的实现。文章提供了完整的代码示例和关键的避坑指南,旨在帮助开发者快速构建稳定可靠的智能车平台,并为进一步的功能扩展奠定基础。

gamma的博客 471

PHP简单实现Memcache或者Redis一致性Hash分布式集群算法

&lt;?php/* PHP简单实现Memcache或者Redis一致性Hash分布式集群算法*/class Consistent{ protected $position = array(); protected $server; // 统一的Hash算法 public function hash($str){ return sprintf("%u"...

贤冰的博客 616

zemax双透镜公差分析

蒙特卡罗分析: 评估公差的整体影响,模拟过程中产生一系列随机的lens,满足指定的公差,然后再按照标准评估。公差分析,就是在设计了一个理想的系统后,想看看实际生产过程中如果产生公差(误差),系统会坏到什么程度,也就是光学性能受到多大影响。反灵敏度分析:分别对每个公差在性能方面的一个给定的最小允许减少量来计算公差,也就是限制了系统性能的变化,和灵敏度分析方向相反。灵敏度分析对每个公差单独求值,分别计算每个公差操作数的最大、最小、标准值(如上图)所有设计上可能的公差都列出来了。注意要固定透镜的口径。

fendoudecheng的博客 3207

一致性hash算法

转载自:http://blog.youkuaiyun.com/lovingprince/article/details/4645448               http://blog.youkuaiyun.com/caigen1988/article/details/7708806               http://blog.youkuaiyun.com/cywosp/article/details/23397179

ZERO 1143

OpenClaw实战四|内容创作全流程AI助理:自动撰稿+智能剪辑+多平台发布,一人顶一个内容团队

AI替代的是「写稿、剪辑、发布」这种流水线工作,真正让你解放出来,去做选题、创意、人设、变现这些高价值的事。OpenClaw这套内容创作全流程AI助理,最大的价值不是「帮你发内容」,而是让一个人,拥有一个内容团队的产能。不管是个人博主、小团队,还是企业新媒体,都能用零代码的方式,快速搭建属于自己的自动化内容矩阵。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 589

MATLAB地理数据处理 25:植被物候提取及分析模型优化(Savitzky-Golay)

之前我写过一篇使用Savitzky-Golay处理遥感数据,获取地面物候信息的MATLAB代码,但是发现存在一些问题:对物候开始期和物候结束期的阈值设定都为相同值,但是有些研究中,需要根据不同的环境条件,设置不同的物候阈值,所以对其进行相应的修改。

amyniez的博客,欢迎交流讨论 2233

何为一致性哈希?一致性哈希和哈希有什么区别?一文深入理解一致性哈希

一致性哈希的原理

Hanson的博客 8155

如何使用Google Maps API爬取地理数据:详细教程与Python实现

Google Maps API 是一组服务的集合,允许开发者访问地图、地点、路线等地理信息。:将地址转换为地理坐标,或将地理坐标转换为地址。:计算两点之间的行车路线、步行路线等。Places API:获取附近的地点、商店、餐馆等。:计算多个地点之间的距离和时间。在接下来的代码中,我们将结合这些 API,展示如何获取并处理地理数据。本文详细介绍了如何使用 Google Maps API 获取地理数据,涵盖了从地址转经纬度、获取地点详情、计算路线、计算多个地点的距离与时间等多个功能。

2201_76125261的博客 733

php简单一致性hash,PHP一致性hash

PHP提供了两种比较两个变量的方法:松散比较使用== or !=: 两个变量都具有“相同的值”。严格比较=== or !==: 两个变量都具有“相同的类型和相同的值”。类型杂耍真实陈述var_dump('0010e2' == '1e3'); # truevar_dump('0xABCdef' == ' 0xABCdef'); # true PHP 5.0 /...

weixin_28921621的博客 233

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

推荐一个Php中常用的一致性哈希的算法类Flexihash程序包

例如我们业务中会涉及到很多Redis数据存储,开始的时候redis服务器并不多,也就是使用了最简单的方式通过在业务代码里对key进行hash计算再和存储实例个数进行对比进行分别存放,后来业务量加大增加到了60多个redis实例进行数据存储,这时如何保证这些数据比较均匀地分配到这些redis中,以及如何避免在这期间发生增加服务器或减少服务器时尽量不要导致原已存储的数据进行挪动就变得非常重要,因为如果有服务器出异常需要下架或者新增服务器时如果大面积的缓存数据命中失败,会导致大量的数据库读取等请求压力。

本博客记录了从2014年以来在工作学习中遇到的技术问题、解决方法以及部分个人人生经历、经验等内容。 1117

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

hash一致性算法 php,一致性hash算法--负载均衡

有没有好奇过redis、memcache等是怎么实现集群负载均衡的呢?其实他们都是通过一致性hash算法实现节点调度的。讲一致性hash算法前,先简述一下求余hash算法:hash(object)%N一个缓存服务器宕机了,这样所有映射到这台服务器的对象都会失效,我们需要把属于该服务器中的缓存移除,这时候缓存服务器是 N-1 台,映射公式变成了 hash(object)%(N-1) ;由于QPS升...

weixin_39908758的博客 130

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

php 一致性hash,redis有多少hash槽

Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。...

weixin_36269709的博客 102

redis一致性哈希算法

一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。      一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 1、平衡性(B

花花公子 1113

PHP一致性Hash

随着memcache、Redis以及其它一些内存K/V数据库的流行,一致性哈希也越来越被开发者所了解。因为这些内存K/V数据库大多不提供分布式支持(本文以redis为例),所以如果要提供多台redis server来提供服务的话,就需要解决如何将数据分散到redis server,并且在增减redis server时如何最大化的不令数据重新分布,这将是本文讨论的范畴。 取模算法

妄笑伊的博客 948

Redis的哈希(Hash)数据类型到底是干什么的?

【代码】Redis的哈希(Hash)数据类型到底是干什么的?

长风破浪会有时的博客 1117

一致性哈希算法

转载声明 这篇文章是直接参考张洋的博客,我重写一遍也是边做边进行更深入的理解,参考链接:http://blog.codinglabs.org/articles/consistent-hashing.html 摘要 本文将会从实际应用场景出发,介绍一致性哈希算法(Consistent Hashing)及其在分布式系统中的应用。首先,本文会描述一个在日常开发中经常会遇到的问题场景,借此介

小一的专栏 3196

hash crc32_一致性hash算法--负载均衡

有没有好奇过redis、memcache等是怎么实现集群负载均衡的呢?其实他们都是通过一致性hash算法实现节点调度的。讲一致性hash算法前,先简述一下求余hash算法:hash(object)%N一个缓存服务器宕机了,这样所有映射到这台服务器的对象都会失效,我们需要把属于该服务器中的缓存移除,这时候缓存服务器是 N-1 台,映射公式变成了 hash(object)%(N-1) ;由于QPS升高...

weixin_39716703的博客 179

PHP 一致性Hash

一致性HASH 好久没有写文章了,最近忙着公司的事情,也一拖再拖。这篇一致性hash是很久之前就有的一篇算法,记录一下,这周写个基于该算法的Redis中间件。 HASH算法的精髓就在于打散原本杂乱无序的一堆节点,并排序,同时使之首尾相连,形成闭环,总有一个节点是目标节点,最坏情况下是又回到第一个节点 这个算法有性能问题,因为PHP是解释性语言,每次查找一个key都初始化这个环,最好...

dieshi0963的博客 184
上一篇: 白话阿里巴巴之Java开发规约
下一篇: Redis集群解决方案
csdn265
博客等级 码龄11年 109粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值