Php implementation of memcache distributed [consistent hash algorithm]

Source: Internet
Author: User
Tags crc32
Php implementation of the memcache distributed [consistent hash algorithm] has recently been reading some articles on the distributed architecture. Therefore, we have used php to implement consistent hash, previously, we used the original hash modulo for distributed processing. when a memcache instance is added or deleted during the production process, all data will be invalid. Consistent hash is used to solve this problem, minimize the number of invalid data items. For more information, see google!

Php implementation efficiency is lacking. if it is necessary to be efficient, it is better to write extension.
Tests show that each of the five memcache instances generates 100 virtual nodes, and the set and get1000 times are added, which is five times slower than a single memcache instance set. Therefore, the efficiency is average and needs to be optimized!
Implementation process:

Memcache configures ip + Port + virtual node serial number for hash and uses crc32 to form a closed loop.

Perform crc32 on the key to be operated

Find the nearest virtual node in the virtual node loop using the binary method.

Extract the real memcache ip address and port from the virtual node for single-instance connection

 * @ Copyright Copyright©2003-2012 phpd.cn * @ license */class memcacheHashMap {private $ _ node = array (); private $ _ nodeData = array (); private $ _ keyNode = 0; private $ _ memcache = null; // The number of virtual nodes generated by each physical server [Note: The larger the number of nodes, the better the uniformity of the cache distribution. during the set get operation, it also consumes more resources. 10 physical servers use 200 more reasonable] private $ _ virtualNodeNum = 200; private function _ construct () {/* put the configuration file */$ config = array ('2017. 0.0.1: 100000', '123. 0.0.1: 100000', '123. 0.0.1: 100000', '123. 0.0. ', '2017. 0.0.1: 100'); if (! $ Config) throw new Exception ('cache config Null'); foreach ($ config as $ key => $ value) {for ($ I = 0; $ I <$ this-> _ virtualNodeNum; $ I ++) {$ this-> _ node [sprintf ("% u", crc32 ($ value. '_'. $ I)] = $ value. '_'. $ I ;}} ksort ($ this-> _ node);} private function _ clone () {}/ *** Singleton, ensure that only one instance */static public function getInstance () {static $ memcacheObj = null; if (! Is_object ($ memcacheObj) {$ memcacheObj = new self ();} return $ memcacheObj ;} /*** perform consistent hash based on the key and connect to a physical memcache server * @ param string $ key */private function _ connectMemcache ($ key) {$ this-> _ nodeData = array_keys ($ this-> _ node); $ this-> _ keyNode = sprintf ("% u", crc32 ($ key )); $ nodeKey = $ this-> _ findServerNode (); // if the loop is exceeded, use the binary method to find the nearest node, and then use the start and end of the loop for judgment, obtain the nearest node if ($ this-> _ keyNode> end ($ this-> _ nodeData) {$ This-> _ keyNode-= end ($ this-> _ nodeData); $ nodeKey2 = $ this-> _ findServerNode (); if (abs ($ nodeKey2-$ this-> _ keyNode) <abs ($ nodeKey-$ this-> _ keyNode) $ nodeKey = $ nodeKey2 ;} var_dump ($ this-> _ node [$ nodeKey]); list ($ config, $ num) = explode ('_', $ this-> _ node [$ nodeKey]); if (! $ Config) throw new Exception ('cache 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];} /*** search for the nearest node from the virtual memcache node using the bipartite method * @ param unknown_type $ m * @ param unknown_type $ B */private function _ findServerNode ($ m = 0, $ B = 0) {$ total = count ($ this-> _ nodeData); if ($ total! = 0 & $ B = 0) $ B = $ total-1; if ($ m <$ B) {$ avg = intval ($ m + $ B) /2); if ($ this-> _ nodeData [$ avg] ==$ this-> _ keyNode) return $ this-> _ nodeData [$ avg]; elseif ($ this-> _ keyNode <$ this-> _ nodeData [$ avg] & ($ AVG-1> = 0) return $ this-> _ findServerNode ($ m, $ AVG-1); else return $ this-> _ findServerNode ($ avg + 1, $ B );} if (abs ($ this-> _ nodeData [$ B]-$ this-> _ keyNode) <abs ($ this-> _ nodeData [$ m]-$ this-> _ keyNode) return $ this-> _ nodeData [$ B]; else return $ this-> _ nodeData [$ m];} public function set ($ key, $ value, $ expire = 0) {return $ this-> _ connectMemcache ($ key)-> set ($ key, json_encode ($ value), 0, $ expire);} public function add ($ key, $ value, $ expire = 0) {return $ this-> _ connectMemcache ($ key)-> add ($ key, json_encode ($ value), 0, $ expire );} public function get ($ key) {return json_decode ($ 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 getfor ($ I = 0; $ I <10000; $ I ++) {$ key = md5 (mt_rand (); $ B = memcacheHashMap: getInstance ()-> set ($ key, time (), 10 );} 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; $ I <10000; $ I ++) {$ key = md5 (mt_rand ()); $ B = $ m-> set ($ key, time (), 0, 10);} var_dump (number_format (microtime (true) -$ runData ['In in _ time'], 6 ));

// Test results: the consistent hash distribution efficiency is about five times faster than that of a single native server.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.