大数据实时AB测试系统的设计与统计计算
请设计一个基于Flink+Redis/ClickHouse的实时AB测试系统架构。包括:实验分层(Layer)与流量分割(Traffic Split)策略、实时指标计算(转化率/人均时长/ARPU)、统计显著性检验的实时计算(Z-Test/卡方检验)、以及实时实验Dashboard的实现方案。给出一个Flink SQL计算实时转化率差异的示例。
回答
编译有声
实时AB测试系统设计:
1. 系统架构:
客户端请求 → 流量网关(Layer分配)
↓ 随机分配实验组/对照组
客户端上报事件 → Kafka(experiment_events)
↓
Flink实时计算层
├─ 窗口聚合(每1分钟/1小时计算各实验组指标)
├─ 统计检验(Z-test计算p值)
└─ 写入ClickHouse/Redis
↓
Grafana/Business Dashboard实时展示
2. Flink SQL实时转化率计算:
CREATE TABLE experiment_events (
user_id BIGINT,
experiment_id STRING,
variant STRING, -- 'control' 或 'treatment'
layer STRING, -- 实验层
converted INT, -- 1=转化, 0=未转化
event_time TIMESTAMP(3),
WATERMARK FOR event_time AS event_time - INTERVAL '1' SECOND
) WITH (...);
-- 实时聚合转化率
INSERT INTO metrics_result
SELECT
experiment_id,
variant,
window_start,
COUNT(DISTINCT user_id) AS total_users,
SUM(converted) AS conversions,
ROUND(SUM(converted) * 1.0 / NULLIF(COUNT(DISTINCT user_id), 0), 4) AS rate
FROM TABLE(TUMBLE(TABLE experiment_events, DESCRIPTOR(event_time), INTERVAL '1' MINUTE))
GROUP BY experiment_id, variant, window_start, window_end;
3. 统计显著性实时计算(Flink ProcessFunction):
// 计算Z-Score和p值
public class ZTestCalculator extends KeyedProcessFunction<...> {
@Override
public void processElement(MetricsRow row, Context ctx, Collector<Result> out) {
if (row.variant.equals("control")) {
updateControl(row);
} else {
updateTreatment(row);
}
// 有对照组和治疗组数据时计算
if (hasBothGroups()) {
double z = computeZscore(control, treatment);
double p = computePValue(z);
out.collect(new Result(experimentId, z, p,
p < 0.05 ? "SIGNIFICANT" : "NOT_SIGNIFICANT"));
}
}
}
4. 流量分割与分层:
Layer设计:
Layer1: 首页改版实验(50%对照, 50%实验)
Layer2: 推荐算法实验(90%对照, 5%算法A, 5%算法B)
流量分割:
user_id_hash = MD5(user_id + layer_name) → [0, 100)
hash < 50 → control
hash >= 50 → treatment
5. 实时Dashboard指标:
- 各实验组当前转化率和置信区间
- 实时p值变化曲线
- 样本量是否达到最小样本量要求
- SRM检测(样本比例偏差检查)