• 一致性哈希的替代算法 shard 可反解vsid php版


    
    
     1 /**
     2  * Linux 系统 根据共享内存块获取一个增长的整型
     3  */
     4 function getNxtValFromSharedMemory()
     5 {
     6     $string_seed = 'global_sharedmemory_' . $_SERVER['SERVER_ADDR'] . '_key';
     7 
     8     $sem = $shm = null;
     9     $retry_times = 1;
    10     do
    11     {
    12         //获取一个系统共享内存生成的id resource资源
    13         $sem = sem_get($string_seed, 1, 0777);
    14         $shm = shm_attach($string_seed, 128, 0777);
    15 
    16         if (is_resource($sem) && is_resource($shm)) {
    17             break;
    18         }
    19 
    20         $cmd = "ipcrm -M 0x00000000; ipcrm -S 0x00000000; ipcrm -M {$string_seed} ; ipcrm -S {$string_seed}";
    21         $last_line = exec($cmd, $output, $retval);
    22         //var_dump($last_line, $cmd, $output, $retval);
    23 
    24         if ($retval !== 0)
    25         {
    26             die('System cannot create sem/shm resource by php');
    27         }
    28     } while($retry_times-- > 0);
    29     if(!sem_acquire($sem))
    30     {
    31         die('System sem error');
    32     }
    33 
    34     $next_value = false;
    35     if (shm_has_var($shm, $string_seed))
    36     {
    37         $next_value = shm_get_var($shm, $string_seed) + 1;
    38         shm_put_var($shm, $string_seed, $next_value);
    39     }
    40     else
    41     {
    42         $next_value = 1;
    43         shm_put_var($shm, $serial_key, $next_value);
    44     }
    45 
    46     shm_detach($shm);
    47     sem_release($sem);
    48     return $next_value;
    49 
    50 }
    
    

    //求二进制
    1
    $tr = 5672264790966273; 2 $res_2 = ''; 3 do 4 { 5 6 $res_2 = $tr%2 . $res_2; 7 $tr = $tr/2; 8 9 }while($tr > 1); 10 11 echo $res_2; 12 13 exit;
    14 $ntime = microtime(true); 15 echo "1、"; 16 echo $ntime; 17 echo "<hr>"; 18 19 $time_sig = intval($ntime * 1000); 20 echo "2、"; 21 echo $time_sig; 22 echo "<hr>";
    //这里需要服务器虚节点id
    23 $vsid = 4097; 24 $auto_inc_sig = getNxtValFromSharedMemory(); 25 26 $serial_id = $time_sig << 12 | $vsid; 27 echo "3、"; 28 echo $serial_id; 29 echo "<hr>"; 30 31 $serial_id = $serial_id << 10 | ($auto_inc_sig % 1024); 32 echo "4、"; 33 echo $serial_id; 34 echo "<hr>"; 35 36 $s_r = $serial_id >> 10; 37 echo "5、"; 38 echo $s_r; 39 echo "<hr>"; 40 41 //这行 42 $vsid = $s_r & (0xFFF); 43 echo "6、"; 44 echo $vsid; 45 exit;
     1 /**
     2  * 从新格式全局序列ID反解出虚拟shard编号
     3  */
     4 function extractVSID($serialId)
     5 {
     6     if(!$serialId || !is_numeric($serialId))
     7         return false;
     8     else
     9         $serialId = (int)$serialId;
    10 
    11     return $serialId >> 10 & (0xFFF);
    12 }
     1 /**
     2  * 生成一个序列ID
     3  *
     4  * 格式:(42B microtime) + (12B vsid) + (10B autoinc)
     5  */
     6 function makeSerialId($vsid)
     7 {
     8     $vsid_max = 4095;
     9     $vsid_min = 1;
    10     if(!is_numeric($vsid) || $vsid < $vsid_min || $vsid > $vsid_max)
    11         return false;
    12     else
    13         $vsid = (int)$vsid;
    14 
    15 
    16     $auto_inc_sig = getNextValueByShareMemory();
    17     if(empty($auto_inc_sig))
    18         return false;
    19 
    20     $ntime = microtime(true);
    21     $time_sig = intval($ntime * 1000);
    22     $serial_id = $time_sig << 12 | $vsid;
    23     $serial_id = $serial_id << 10 | ($auto_inc_sig % 1024);
    24     return (string)$serial_id;
    25 }

    容易出现id冲突,待解决

     1 /**
     2  * 通过本机共享内存件来生成一个auto_increment序列
     3  */
     4 function getNextValueByShareMemory()
     5 {
     6     $addr = '127.0.0.1';
     7     if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
     8         $addr = $_SERVER['HTTP_X_FORWARDED_FOR'];
     9     elseif(!empty($_SERVER['SERVER_ADDR']))
    10         $addr = $_SERVER['SERVER_ADDR'];
    11 
    12     $skey = 'global_serial_generator_seed_'.$addr;
    13     $ikey = crc32($skey);
    14 
    15     $sem = $shm = null;
    16     $retry_times = 1;
    17     do
    18     {
    19         $sem = sem_get($ikey, 1, 0777);
    20         $shm = shm_attach($ikey, 128, 0777);
    21         if(is_resource($sem) && is_resource($shm))
    22             break;
    23 
    24         $cmd = "ipcrm -M 0x00000000; ipcrm -S 0x00000000; ipcrm -M {$ikey} ; ipcrm -S {$ikey}";
    25         $last_line = exec($cmd, $output, $retval);
    26     }while($retry_times-- > 0);
    27 
    28     if(!sem_acquire($sem))
    29         return false;
    30 
    31     $next_value = false;
    32     if(shm_has_var($shm, $ikey))
    33         shm_put_var($shm, $ikey, $next_value=shm_get_var($shm, $ikey)+1);
    34     else
    35         shm_put_var($shm, $ikey, $next_value=1);
    36 
    37     $shm && shm_detach($shm);
    38     $sem && sem_release($sem);
    39     return $next_value;
    40 }
  • 相关阅读:
    photoshop--图像大小(分辨率和宽高)
    Arduino--单向倾斜开关
    禁止google浏览器http链接强制跳转为https
    属性缓存_使用ConcurrentDictionary替代Hashtable对多线程的对象缓存处理
    .Net(windows服务器)清理缓存数据的几个方法
    【西天取经】(升级.net5)用了一整天才把项目从.netcoreapp3.1升级到.net5(转载)
    在Debian 9 vim中启用鼠标复制粘贴
    将数据批量插入SQL Server
    shell 脚本中 在grep -E '($wo|$ni|$ta)' 这里面用变量
    kubernetes 重启的几种方法
  • 原文地址:https://www.cnblogs.com/the-moving-ear/p/3431141.html
Copyright © 2020-2023  润新知