用一致性Hash环实现灰度测试

用一致性Hash环实现灰度测试

概述

公司新提的一个需求,需要用到灰度测试,30%的用户看到的新逻辑,70%用户还是旧的,刚开始想到ip取余,用户id取余,发现取余误差会很大,用于灰度测试是不可取的。而且怎么才算100%?因为一直有新用户,还有未登录的用户,而且老用户也不一定会登录,所以100%只是一个范围,没有具体数值的。

实现方式

在网上看了一下灰度测试常用的手段,发现一致性Hash环挺符合的。正常都是用于负载服务器的,由于需求急,就不配置负载了,直接1套代码2个逻辑(很不规范哈),30%的用户看到新逻辑,剩下70%还是旧的。

class GrayScaleTest {

    // 10台服务器(模拟10个服务器)
    private $servers = [
        'server1',
        'server2',
        'server3',
        'server4',
        'server5',
        'server6',
        'server7',
        'server8',
        'server9',
        'server10',
    ];

    private $hashRing = [];

    public function __construct()
    {
        $this->hashRing = $this->buildHashRing();
    }

    // 构建一致性哈希环
    private function buildHashRing()
    {
        // 虚拟节点个数,可以根据实际情况调整(虚拟节点的数量越多,哈希环的分布就越均匀,负载也可以更加平衡,虚拟节点的增加会增加计算和存储的开销。)
        $replicas = 500;

        // 生成虚拟节点
        foreach ($this->servers as $server)
        {
            for ($i = 0; $i < $replicas; $i++)
            {
                $hash = $this->hash($server . ':' . $i);
                $this->hashRing[$hash] = $server;
            }
        }
        return $this->hashRing;
    }
    
	// 生成hash值
    private function hash($str)
    {
        //return sprintf("%u", crc32(mhash(MHASH_MURMURHASH3, $str)));
        return crc32($str);
    }

	// 获取用户id在那个服务器上
    public function getServer($userid)
    {
        // 计算用户ID的哈希值
        $hash = $this->hash($userid);

        // 查找虚拟节点
        $virtualNodes = array_keys($this->hashRing);

        // hash值排序
        sort($virtualNodes);
		
		// 循环比较,看在哪个区间
        foreach ($virtualNodes as $virtualNode)
        {
            if ($hash <= $virtualNode)
            {
                return $this->hashRing[$virtualNode];
            }
        }

        return end($this->servers);

    }

	// 30%的灰度
    public function isInGrayScale($userid)
    {
        $server = $this->getServer($userid);

        // 前3台服务器进行灰度测试
        if (in_array($server, array_slice($this->servers, 0, 3)))
        {
            return true;
        }

        return false;
    }



}

随机生成1000个id,进行测试,发现都在30%左右(存在误差的),还是可以接受的。

500虚拟节点
第一次:276/1000
第二次:269/1000
第三次:280/1000
第四次:277/1000
第五次:264/1000

1000虚拟节点
第一次:278/1000
第二次:282/1000
第三次:269/1000
第四次:270/1000
第五次:302/1000

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值