如何理解 SOCKETLAT_READSLOW
我们有一个访问redis的请求,redis有质量监控,每次get的p99时间基本上在1ms左右,但是 SOCKETLAT_READSLOW 有大量的大于100ms的
看代码sock_receive的时候会记录一个时间,然后对比socket_read之间的时间差,不知道我理解的对不对
是的,这种就是是kernel处理好了,应用层读的慢了 一般遇到这个问题的原因主要是:
- 应用容器的CPU限流了,可以关注Pod的cpu throttle情况
- 应用本身的配置或者实现问题,比如java的full gc, 或者线程池满了之类的导致无法及时处理
是的,这种就是是kernel处理好了,应用层读的慢了 一般遇到这个问题的原因主要是:
- 应用容器的CPU限流了,可以关注Pod的cpu throttle情况
- 应用本身的配置或者实现问题,比如java的full gc, 或者线程池满了之类的导致无法及时处理
这个地方的实现应该是有问题,并不是所有的包都会在调用 sock_def_readable 后再调用 tcp_cleanup_rbuf。调用 sock_def_readable 后会记录一个 lastreceive,假如这个时候系统没有再接收新的包,但是可能存在调用 tcp_cleanup_rbuf 的情况,这个时候 latency = now - ski->lastreceive 就会不停的增大。类似以下的代码实现
readTimeout := 2*time.Second
buffer := make([]byte, 512)
for {
err = conn.SetReadDeadline(time.Now().Add(readTimeout)) // timeout
if err != nil {
log.Println("setReadDeadline failed:", err)
}
n, err := conn.Read(buffer)
if err != nil {
log.Println("Read failed:", err)
//break
}
log.Println("count:", n, "msg:", string(buffer))
}
客户端每隔2s就会去进行一次 Read ,但是服务端并没有往 buffer 写数据,这个时候每隔2s就会有一个event,并且 latency 值会不断的累加
int sock_read(struct pt_regs *ctx)
{
struct sock * sk = (struct sock *)PT_REGS_PARM1(ctx);
int copied = (int)PT_REGS_PARM2(ctx);
struct sklat_key_t * ski;
ski = bpf_map_lookup_elem(&insp_sklat_entry, &sk);
if (ski) {
u64 now = bpf_ktime_get_ns();
if (ski->lastreceive > 0) {
u64 latency;
latency = now - ski->lastreceive;
ski->lastreceive = 0;
......
}
每次调用 tcp_cleanup_rbuf 以后增加一个 ski->lastreceive = 0 的操作会不会更好?同理调用 tcp_write_xmit 也是一样的
这个问题没有进展吗?说的有道理啊