From f07e8830def438cd7b9f674ca8393e63ec0470ca Mon Sep 17 00:00:00 2001 From: wo_cow Date: Fri, 9 Sep 2022 14:46:22 +0800 Subject: [PATCH] ksliprobe optimization: mark no redis connection --- .../ebpf.probe/src/ksliprobe/ksliprobe.bpf.c | 39 ++++++++++++++----- .../ebpf.probe/src/ksliprobe/ksliprobe.c | 13 ++----- .../ebpf.probe/src/ksliprobe/ksliprobe.h | 2 + 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.bpf.c b/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.bpf.c index 8664216f..bf653f0a 100644 --- a/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.bpf.c +++ b/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.bpf.c @@ -23,7 +23,8 @@ #define BPF_F_INDEX_MASK 0xffffffffULL #define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK -#define MAX_CONN_LEN 8192 +#define MAX_CONN_LEN 8192 +#define MAX_CHECK_TIMES 2 #define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0])) @@ -109,7 +110,7 @@ static __always_inline int init_conn_samp_data(struct sock *sk) } #ifndef __PERIOD -#define __PERIOD NS(30) +#define __PERIOD NS(5) #endif static __always_inline void get_args(struct conn_data_t *conn_data) { @@ -245,7 +246,7 @@ static __always_inline int parse_req(struct conn_data_t *conn_data, const unsign err = bpf_probe_read(msg, copy_size & MAX_COMMAND_REQ_SIZE, buf); if (err < 0) { bpf_printk("parse_req read buffer failed.\n"); - return PROTOCOL_UNKNOWN; + return PROTOCOL_NO_REDIS; } // 解析请求中的command,确认协议 @@ -254,7 +255,7 @@ static __always_inline int parse_req(struct conn_data_t *conn_data, const unsign return PROTOCOL_REDIS; } - return PROTOCOL_UNKNOWN; + return PROTOCOL_NO_REDIS; } static __always_inline int periodic_report(u64 ts_nsec, struct conn_data_t *conn_data, struct pt_regs *ctx) @@ -307,7 +308,13 @@ static __always_inline void sample_finished(struct conn_data_t *conn_data, struc csd->status = SAMP_INIT; } -static __always_inline void process_rdwr_msg(u32 tgid, int fd, const char *buf, const unsigned int count, +static __always_inline void mark_no_redis_conn(struct conn_data_t *conn_data) +{ + conn_data->id.protocol = PROTOCOL_NO_REDIS; + bpf_map_delete_elem(&conn_samp_map, &conn_data->sk); +} + +static __always_inline void process_rd_msg(u32 tgid, int fd, const char *buf, const unsigned int count, struct pt_regs *ctx) { struct conn_key_t conn_key = {0}; @@ -342,15 +349,26 @@ static __always_inline void process_rdwr_msg(u32 tgid, int fd, const char *buf, return; } - // 非循环采样每次上报后就返回,等待下次上报周期再采样。这种方式无法获取周期内max sli。 + // 非循环采样每次上报后就返回,等待下次上报周期再采样。这种方式无法获取周期内max sli if (!conn_data->cycle_sampling_flag && reported) return; + // 连接的协议类型未知时,连续3次read报文时解析不出是redis协议,就确认此条连接非redis请求连接,不做采样 + // 一旦确认为redis连接则不会再修改连接的协议类型 enum conn_protocol_t protocol = parse_req(conn_data, count, buf); - if (protocol == PROTOCOL_UNKNOWN) { + if (protocol == PROTOCOL_NO_REDIS) { + if (conn_data->id.protocol == PROTOCOL_UNKNOWN) { + if (conn_data->procotol_check_times >= MAX_CHECK_TIMES) { + mark_no_redis_conn(conn_data); + } else { + conn_data->procotol_check_times++; + } + } return; } - conn_data->id.protocol = protocol; + if (conn_data->id.protocol == PROTOCOL_UNKNOWN) { + conn_data->id.protocol = PROTOCOL_REDIS; + } __builtin_memcpy(&csd->command, conn_data->current.command, MAX_COMMAND_REQ_SIZE); @@ -378,6 +396,9 @@ KPROBE(ksys_read, pt_regs) if (conn_data == (void *)0) return; + if (conn_data->id.protocol == PROTOCOL_NO_REDIS) + return; + if (!conn_data->cycle_sampling_flag) { if (bpf_ktime_get_ns() - conn_data->last_report_ts_nsec < conn_data->report_period) return; @@ -408,7 +429,7 @@ KRETPROBE(ksys_read, pt_regs) fd = (int)PROBE_PARM1(val); buf = (char *)PROBE_PARM2(val); - process_rdwr_msg(tgid, fd, buf, count, ctx); + process_rd_msg(tgid, fd, buf, count, ctx); return; } diff --git a/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.c b/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.c index 06156c5b..b6b33c5e 100644 --- a/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.c +++ b/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.c @@ -100,20 +100,13 @@ static void msg_event_handler(void *ctx, int cpu, void *data, unsigned int size) ser_ip_str, INET6_ADDRSTRLEN); ip_str(msg_evt_data->client_ip_info.family, (unsigned char *)&(msg_evt_data->client_ip_info.ipaddr), cli_ip_str, INET6_ADDRSTRLEN); - switch (msg_evt_data->conn_id.protocol) { - case PROTOCOL_REDIS: - protocol = "REDIS"; - break; - default: - protocol = "unknown"; - break; - } + fprintf(stdout, "|%s|%d|%d|%s|%s|%s|%u|%s|%u|%llu|\n", SLI_TBL_NAME, msg_evt_data->conn_id.tgid, msg_evt_data->conn_id.fd, - protocol, + "REDIS", msg_evt_data->latency.command, ser_ip_str, msg_evt_data->server_ip_info.port, @@ -126,7 +119,7 @@ static void msg_event_handler(void *ctx, int cpu, void *data, unsigned int size) MAX_SLI_TBL_NAME, msg_evt_data->conn_id.tgid, msg_evt_data->conn_id.fd, - protocol, + "REDIS", msg_evt_data->max.command, ser_ip_str, msg_evt_data->server_ip_info.port, diff --git a/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.h b/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.h index 6e547a48..40d2398c 100644 --- a/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.h +++ b/src/probes/extends/ebpf.probe/src/ksliprobe/ksliprobe.h @@ -47,6 +47,7 @@ enum msg_event_rw_t { enum conn_protocol_t { PROTOCOL_UNKNOWN, PROTOCOL_REDIS, + PROTOCOL_NO_REDIS, }; struct ip { @@ -89,6 +90,7 @@ struct conn_data_t { __u64 last_report_ts_nsec; // 上一次上报完成的时间点 __u64 report_period; // 上报周期 char cycle_sampling_flag; + char procotol_check_times; }; struct msg_event_data_t { -- Gitee