架构师必备:灰度方案汇总
大家好,我是Java烘焙师。本文结合笔者的经验和思考,对灰度方案做个总结,重点介绍AB实验。 灰度在开发流程中非常普遍。先做小流量验证,确认无误后再推全,灰度过程中一旦发现系统异常、或业务指标异常,应立刻回滚。 代码灰度:是最典型的灰度,灰度内做新逻辑,灰度外做旧逻辑 数字id尾号灰度:取id最后2位(百分比)、最后3位(千分比)、最后4位(万分比)等 随机灰度:取一部分随机流量做灰度 A/B实验 下面重点介绍一下A/B实验。 主要目的是为了同时做多个实验,而不是给每个实验均分一部分流量。因为当同时进行的实验变多时,组合数量成倍增加,每个实验分到的流量就很少了。 实验层、实验举例: 要同时支持多个分层实验,核心在于通过哈希算法将每一层的流量打散,用于实现“均匀分流”和“层间正交”,使得流量在各个实验的效果正负抵消,才能得到真实的对比结果。 之所以用murmurhash,而非md5,是因为md5是加密算法,计算开销更大,在AB实验中仅需均匀打散即可,无需担心根据哈希结果反推原文。 实验数据收集流程如下: 代码逻辑开发: 实验开始,后端埋点:sdk发出后端埋点消息 离线统计实验效果: 以下是sql示例,代表从实验曝光后24小时内各个分组的转化率对比。 评估实验结果是否正向、是否显著。了解统计学里的核心概念,能看懂实验报表即可。 用来衡量实验结果是否显著,p值的含义是:假设实验组与对照组没有区别,此时观察到实验有差异的概率。一般要求 在显著的前提下,用来衡量实验结果是否正向,代表业务指标的可能范围分布。 以上就是灰度方案的总结了,欢迎讨论交流。灰度场景
灰度模式
id % 100 < 灰度百分比,则命中灰度ThreadLocalRandom.current().nextInt(100) < 灰度百分比id选取
A/B实验
目的
分层实验
有这几层结构:实验层、实验、分组
哈希算法打散
以下是计算实验层桶号的代码示例,实验桶号同理:import com.google.common.hash.Hashing;
import java.nio.charset.StandardCharsets;
public class ABTestRouter {
/**
* 根据用户ID和实验层ID(实验层ID充当盐的角色),计算桶号 (0-99)
*/
public static int getBucket(String userId, String layerId) {
// 1. 拼接 Key: "layerId:userId"
String key = layerId + ":" + userId;
// 2. 使用 MurmurHash3 (32-bit)
// Guava 的 murmur3_32_fixed 是线程安全的
int hash = Hashing.murmur3_32_fixed()
.hashString(key, StandardCharsets.UTF_8)
.asInt();
// 3. 取模并确保结果为正数
// Math.abs(Integer.MIN_VALUE) 会返回负数,所以推荐使用位运算去除符号位
return (hash & Integer.MAX_VALUE) % 100;
}
public static void main(String[] args) {
String uid = "user_123456";
// 不同层的流量是正交的(打散重新分配)
System.out.println("展示层桶号: " + getBucket(uid, "layer_ui"));
System.out.println("算法层桶号: " + getBucket(uid, "layer_algo"));
}
}
之所以把实验层id作为盐,是因为微小的输入差异都会导致哈希结果相差巨大,实现打散的效果。实验数据收集
业务id, 实验层id, 实验id, 分组id, 桶号, 触发时间
SELECT
e.group_id,
COUNT(DISTINCT e.user_id) as exposed_users,
COUNT(DISTINCT a.user_id) as converted_users,
COUNT(DISTINCT a.user_id) / COUNT(DISTINCT e.user_id) as conversion_rate
FROM exposure_events e
LEFT JOIN action_events a ON e.user_id = a.user_id
AND a.event_time BETWEEN e.event_time AND (e.event_time + INTERVAL 24 HOUR)
WHERE e.experiment_id = 'ui_test_001'
GROUP BY e.group_id;实验报表分析
p值
p < 0.05,也就是说实验结果显著的概率大于95%(1 - 0.05 = 95%)置信区间
比如:实验结果里业务指标提升了1%,95%置信区间在[0.8%, 1.2%],则代表有95%的把握可以把业务指标提升至少0.8%、至多1.2%,效果正向。如果置信区间的下界是负数,就有可能是负向效果了,需要警惕。