在默认情况下,系统会采集所有追踪(Tracing)的数据。但是如果系统比较复杂,采集的端点比较多的时候,对存储压力比较大,这个时候我们可以搞个采样策略配置,只存储部分的调用链路信息。比如:50%。
设置采样率的时候并不会影响相关指标的计算(metrics还是全量聚合的,例如步长3s,不管3s内有多少事件都是只有一条数据)。
相关指标的计算还是使用完整的数据计算的。
采样前,每天携带几十亿干货。
采样后,不行了萎靡不振。
简单随机采样
周期性完整采样
基于条件的采样
上面几种进行组合互补
例如配置60,即采样时按照随机采样,采样率为60%。
public static boolean sample(int samplePercentage) {
// ThreadLocalRandom.current().nextInt()
// 返回介于零(含)和指定界限(不含)之间的伪随机int值。
return ThreadLocalRandom.current().nextInt(100) < samplePercentage;
}
例如配置3s内只采集5千个事件指标数据,超出的直接就不要了。
摘抄Skywalking原始代码:https://github.com/apache/skywalking-java/blob/main/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/sampling/SamplingService.java
抽出关键点如下:
// 采样数
private volatile AtomicInteger samplingFactorHolder;
// 定时 清理重置上次采样数
private volatile ScheduledFuture<?> scheduledFuture;
// 3秒
private int stepTime = 3;
// 5000
private int samplingRate = 5000;
// 初始化方法
init(){
this.resetSamplingFactor();
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(
new DefaultNamedThreadFactory("SamplingService"));
scheduledFuture = service.scheduleAtFixedRate(new RunnableWithExceptionProtection(
this::resetSamplingFactor, t -> LOGGER.error("unexpected exception.", t)), 0, stepTime, TimeUnit.SECONDS);
}
// 重置采样点
private void resetSamplingFactor() {
samplingFactorHolder = new AtomicInteger(0);
}
public boolean trySampling() {
int factor = samplingFactorHolder.get();
if (factor < samplingRate {
return samplingFactorHolder.compareAndSet(factor, factor + 1);
} else {
return false;
}
}
例如配置大于多少耗时的采集,只采集大于300ms的事件,采集响应HttpCode为400-600,采集B可用区的等。
这里没有上面好讲的,根据自己业务实际进行判断即可。