PHPhash consistency jump
_ Hasher = $ hasher? $ Hasher: new FlexiHash_Crc32Hasher (); // number of virtual nodes if (! Empty ($ replicas) {$ this-> _ replicas = $ replicas;}/*** add nodes based on the number of virtual nodes, distribute nodes to more virtual locations */public function addTarget ($ target) {if (isset ($ this-> _ targetToPositions [$ target]) {throw new FlexiHash_Exception ("Target $ target already exists. ") ;}$ this-> _ targetToPositions [$ target] = array (); for ($ I = 0; $ I <$ this-> _ replicas; $ I ++) {// hash $ position = $ this-> _ hasher-> hash ($ target. $ I); // The actual node corresponding to the virtual node $ this-> _ PositionToTarget [$ position] = $ target; // virtual node included in the real node $ this-> _ targetToPositions [$ target] [] = $ position ;} $ this-> _ positionToTargetSorted = false; // number of real nodes $ this-> _ targetCount ++; return $ this ;} /*** add multiple nodes **/public function addTargets ($ targets) {foreach ($ targets as $ target) {$ this-> addTarget ($ target );} return $ this;}/*** remove a node **/public function removeTarget ($ target) {if (! Isset ($ this-> _ targetToPositions [$ target]) {throw new FlexiHash_Exception ("target $ target does not exist \ n ");} foreach ($ this-> _ targetToPositions [$ target] as $ position) {unset ($ this-> _ positionToTarget [$ position]);} unset ($ this-> _ targetToPositions [$ target]); $ this-> _ targetCount --; return $ this ;} /*** get all nodes **/public function getAllTargets () {return array_keys ($ this-> _ targetToPositions);}/*** search for hash by key Real node **/public function lookup ($ resource) {$ targets = $ this-> lookupList ($ resource, 1); if (empty ($ targets )) {throw new FlexiHash_Exception ("no targets exist");} return $ targets [0];}/*** find the node where the resource exists ** description: based on the required quantity, returns the node with the value equal to or greater than $ resource hash and the smallest value. if the value does not exist or the number is insufficient, then one or more */public function lookupList ($ resource, $ requestedCount) {if (! $ RequestedCount) {throw new FlexiHash_Exception ('invalid count requested');} if (empty ($ this-> _ positionToTarget) {return array ();} // if ($ this-> _ targetCount = 1) {return array_unique (array_values ($ this-> _ positionToTarget ));} // obtain the value of the current key after hash $ resourcePosition = $ this-> _ hasher-> hash ($ resource); $ results = array (); $ collect = false; $ this-> _ sortPositionTargets (); // The search is equal to or equal to $ resourcePosition. It is large and the smallest number is foreach ($ this-> _ positionToTarget as $ key => $ value) {if (! $ Collect & $ key> $ resourcePosition) {$ collect = true;} if ($ collect &&! In_array ($ value, $ results) {$ results [] = $ value;} // find $ requestedCount or the number is the same as the actual number of nodes if (count ($ results) ==$ requestedCount | count ($ results) =$ this-> _ targetCount) {return $ results ;}// if the quantity is not enough or it is not found, starting from the first one, $ requestedCount-count ($ results) before $ results does not exist ), set to the desired node foreach ($ this-> _ positionToTarget as $ key => $ value) {if (! In_array ($ value, $ results) {$ results [] = $ value;} if (count ($ results) = $ requestedCount | count ($ results) ==$ this-> _ targetCount) {return $ results;}/*** sort by virtual node */private function _ sortPositionTargets () {if (! $ This-> _ positionToTargetSorted) {ksort ($ this-> _ positionToTarget, SORT_REGULAR); $ this-> _ positionToTargetSorted = true ;}}} // end class/*** hash mode */interface FlexiHash_Hasher {public function hash ($ string);} class FlexiHash_Crc32Hasher implements FlexiHash_Hasher {public function hash ($ string) {return sprintf ("% u", crc32 ($ string) ;}} class FlexiHash_Md5Hasher implements FlexiHash_Hasher {public function has H ($ string) {return substr (md5 ($ string), 0, 8 );}} class FlexiHash_Exception extends Exception {}$ runData ['In in _ time'] = microtime (true); for ($ I = 0; $ iaddTargets ($ targetsArray ); $ key = md5 (mt_rand (); $ targets = $ flexiHashObj-> lookup ($ key); // var_dump ($ targets);} echo "consistent hash :"; var_dump (number_format (microtime (true)-$ runData ['In in _ time'], 6); $ runData ['In in _ time'] = microtime (true ); $ m = new Memcache; $ M-> connect ('2017. 0.0.1 ', 11211); for ($ I = 0; $ iset ($ key, time (), 0, 10);} echo "single machine :"; var_dump (number_format (microtime (true)-$ runData ['In in _ time'], 6);?>
2. [Code]Hash consistency of virtual nodes
$ Value) {for ($ I = 0; $ I <$ this-> _ virtualNodeNum; $ I ++) {$ this-> _ node [sprintf ("% u", crc32 ($ value. "#". $ I)] = $ value. "#". $ I ;}// sort ksort ($ this-> _ node); // print_r ($ this-> _ node );} // Singleton mode static public function getInstance () {static $ memcacheObj = null; if (! Is_object ($ memcacheObj) {$ memcacheObj = new self ();} return $ memcacheObj;} private function _ connectMemcache ($ key) {$ this-> _ nodeData = array_keys ($ this-> _ node); // echo "all node: \ n "; // print_r ($ this-> _ nodeData); $ this-> _ keyNode = sprintf ("% u", crc32 ($ key )); // $ this-> _ keyNode = 1803717635; // var_dump ($ this-> _ keyNode ); // Obtain the nearest node corresponding to the key value $ nodeKey = $ this-> _ findServerNode (0, count ($ this-> _ nodeD Ata)-1); // var_dump ($ nodeKey); // echo "$ this-> _ keyNode: search node: $ nodeKey IP: {$ this-> _ node [$ nodeKey]} \ n "; // obtain the corresponding real ip list ($ config, $ num) = explode ("#", $ this-> _ node [$ nodeKey]); if (empty ($ config) {throw new Exception ("serach ip config error");} if (! Isset ($ this-> _ memcache [$ config]) {$ this-> _ memcache [$ config] = new Memcache; list ($ host, $ port) = explode (":", $ config); $ this-> _ memcache [$ config]-> connect ($ host, $ port );} return $ this-> _ memcache [$ config];} /*** query the nearest node from the virtual memcache node using the bipartite method * @ param int $ low start position * @ param int $ high end position */private function _ findServerNode ($ low, $ high) {// The start subscript is smaller than the end subscript if ($ low <$ high) {$ avg = intval ($ low + $ high)/2 ); if ($ this-> _ nodeData [$ avg] =$ this-> _ keyNode) {return $ this-> _ nodeData [$ avg];} elseif ($ this-> _ keyNode <$ this-> _ nodeData [$ avg]) {return $ this-> _ findServerNode ($ low, $ AVG-1 );} else {return $ this-> _ findServerNode ($ avg + 1, $ high) ;}} else if ($ low ==$ high )) {// if ($ low = 0 | $ low = count ($ this-> _ nodeData)-1) {return $ this-> _ nodeData [$ low];} // var_dump ($ low ); if ($ this-> _ nodeData [$ low] <$ this-> _ keyNode) {if (abs ($ this-> _ nodeData [$ low]-$ this-> _ keyNode) <abs ($ this-> _ nodeData [$ low + 1]-$ this-> _ keyNode) {return $ this-> _ nodeData [$ low];} else {return $ this-> _ nodeData [$ low + 1] ;}} else {if (abs ($ this-> _ nodeData [$ low]-$ this-> _ keyNode) <abs ($ this-> _ nodeData [$ low-1]-$ this-> _ keyNode) {return $ this-> _ nodeData [$ low];} else {return $ this-> _ nodeData [$ low-1] ;}} else {if ($ low = 0) & ($ high <0 )) {return $ this-> _ nodeData [$ low];} if (abs ($ this-> _ nodeData [$ low]-$ this-> _ keyNode) <abs ($ this-> _ nodeData [$ high]-$ this-> _ keyNode) {return $ this-> _ nodeData [$ low];} else {return $ this-> _ nodeData [$ high] ;}} public function set ($ key, $ value, $ expire = 0) {// var_dump ($ key); return $ this-> _ connectMemcache ($ key)-> set ($ key, json_encode ($ value), 0, $ expire );} public function add ($ key, $ vakue, $ expire = 0) {return $ this-> _ connectMemcache ($ key)-> add ($ key, json_encode ($ value ), 0, $ expire);} public function get ($ key) {return $ this-> _ connectMemcache ($ key)-> get ($ key, true );} public function delete ($ key) {return $ this-> _ connectMemcache ($ key)-> delete ($ key );}} $ runData ['In in _ time'] = microtime (true); // Test 10 thousand sets plus get for ($ I = 0; $ iset ($ key, TIME (), 10);} echo "consistent hash:"; var_dump (number_format (microtime (true)-$ runData ['In in _ time'], 6 )); $ runData ['In in _ time'] = microtime (true); $ m = new Memcache; $ m-> connect ('2017. 127. 0.0.1 ', 11211); for ($ I = 0; $ iset ($ key, time (), 0, 10);} echo "single machine :"; var_dump (number_format (microtime (true)-$ runData ['In in _ time'], 6 ));