zoukankan      html  css  js  c++  java
  • Memcached取模算法

    最容易想到的算法是取模算法,即 N 个节点要,从 0->N-1 编号. key 对 N 取模,余 i,则 key 落在第 i 台服务器上.

    余数分布式的缺陷

    假设有 8 台服务器, 运行中,突然 down 一台, 则求余的底数变成 7
    后果:

    key0%8==0, key0%7 ==0 hits ….

    key6%8==6, key6%7== 6 hits
    key7%8==7, key7%7==0 miss
    key9%8==1, key9%7 == 2 miss

    key55%8 ==7 key55%7 == 6 miss

    取模命中率为(1 / N),所以: 服务器越多, 则 down 机的后果越严重!

    <?php
    

    class Residual
    {
    protected (nodeS</span> =<span style="color: #000000;"> []; </span><span style="color: #0000ff;">protected</span> <span style="color: #800080;">)nodeNum = 0;

    </span><span style="color: #008000;">//</span><span style="color: #008000;">需要将字符串转换为正整数</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> strToInt(<span style="color: #800080;">$str</span><span style="color: #000000;">)
    {
        </span><span style="color: #0000ff;">return</span> <span style="color: #008080;">sprintf</span>('%u', <span style="color: #008080;">crc32</span>(<span style="color: #800080;">$str</span><span style="color: #000000;">));
    }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">通过key找到对应服务器</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> findServer(<span style="color: #800080;">$key</span><span style="color: #000000;">)
    {
        </span><span style="color: #800080;">$point</span> = <span style="color: #800080;">$this</span>-&gt;strToInt(<span style="color: #800080;">$key</span><span style="color: #000000;">);
        </span><span style="color: #800080;">$nodeSCount</span> = <span style="color: #008080;">count</span>(<span style="color: #800080;">$this</span>-&gt;<span style="color: #000000;">nodeS);
    
        </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$nodeSCount</span> &gt; 0<span style="color: #000000;">) {
    
            </span><span style="color: #800080;">$node</span> = <span style="color: #800080;">$point</span> % <span style="color: #800080;">$nodeSCount</span><span style="color: #000000;">;
            </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$node</span><span style="color: #000000;">;
    
    
        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
            </span><span style="color: #0000ff;">return</span> '没有服务器'<span style="color: #000000;">;
        }
    
    
    }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">添加服务器</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> addServer(<span style="color: #800080;">$node</span><span style="color: #000000;">)
    {
    
        </span><span style="color: #800080;">$this</span>-&gt;nodeS[] = <span style="color: #800080;">$node</span><span style="color: #000000;">;
        </span><span style="color: #800080;">$this</span>-&gt;nodeNum += 1<span style="color: #000000;">;
    }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">移除服务器</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> removeServer(<span style="color: #800080;">$node</span><span style="color: #000000;">)
    {
        </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$this</span>-&gt;nodeS <span style="color: #0000ff;">as</span> <span style="color: #800080;">$k</span> =&gt; <span style="color: #800080;">$v</span><span style="color: #000000;">) {
            </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$v</span> == <span style="color: #800080;">$node</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>-&gt;nodeS[<span style="color: #800080;">$k</span><span style="color: #000000;">]);
                </span><span style="color: #800080;">$this</span>-&gt;nodeNum -= 1<span style="color: #000000;">;
                </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;
            }
        }
        </span><span style="color: #800080;">$this</span>-&gt;nodeS = <span style="color: #008080;">array_merge</span>(<span style="color: #800080;">$this</span>-&gt;<span style="color: #000000;">nodeS);
    
    }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">获取服务器列表</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getServerList()
    {
        </span><span style="color: #008080;">var_dump</span>(<span style="color: #800080;">$this</span>-&gt;<span style="color: #000000;">nodeS);
        </span><span style="color: #008080;">var_dump</span>(<span style="color: #800080;">$this</span>-&gt;<span style="color: #000000;">nodeNum);
    }
    

    }

    (Residual</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Residual(); </span><span style="color: #800080;">)Residual->addServer(['host' => '10.16.134.65', 'port' => '11211']);
    (Residual</span>-&gt;addServer(['host' =&gt; '10.16.134.65', 'port' =&gt; '11212'<span style="color: #000000;">]); </span><span style="color: #800080;">)Residual->addServer(['host' => '10.16.134.65', 'port' => '11213']);
    $Residual->getServerList();

    for ((i</span> = 1; <span style="color: #800080;">)i <= 10; (i</span>++<span style="color: #000000;">) { </span><span style="color: #800080;">)key = 'key__num_' . (i</span><span style="color: #000000;">; </span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">)Residual->findServer((key</span><span style="color: #000000;">); </span><span style="color: #0000ff;">echo</span> '&lt;br&gt;'<span style="color: #000000;">; } </span><span style="color: #800080;">)Residual->removeServer(['host' => '10.16.134.65', 'port' => '11212']);
    $Residual->getServerList();

     

  • 相关阅读:
    ssh免密码登录
    nginx做负载均衡+keepalived(做主备)
    centos之Too many open files问题-修改linux最大文件句柄数
    redis-JedisPoolConfig配置
    Hadoop端口说明
    hadoop 2.5 安装部署
    Java集合框架 10 连问,你有被问过吗?
    Dubbo面试八连问,这些你都能答上来吗?
    面试官:关于Java性能优化,你有什么技巧
    Docker从入门到掉坑(三):容器太多,操作好麻烦
  • 原文地址:https://www.cnblogs.com/yhq-qhh/p/10139952.html
Copyright © 2011-2022 走看看