1.技术负责人,服务服务开发工程师3撰写时间(组图)
优采云 发布时间: 2021-08-10 07:191.技术负责人,服务服务开发工程师3撰写时间(组图)
1 概览
在持续2个月的持续优化过程中,采集系统(kafka中的一个话题)的数据处理能力从2.500万增加到10万,基本满足了下一个高峰的要求.
在所有日志中,广告日志和作品日志是最大的,所以本次优化也是针对这两个方面进行了优化。
广告日志接口TPS从之前的不到1k/s升级到2.1w/s,提升了20倍。
工作日志界面的TPS从之前的不到1k/s提升到了1.4w/s,提升了13倍。
在数据采集的优化过程中,设计了很多地方,包括代码优化、框架优化、服务优化。现在记录显着提高吞吐率的优化点。
2 面向对象
技术负责人,后端服务开发工程师
3 写作时间
2020 年 4 月 3 日
4 技术框架图
arti1.png
5 后端日志ETL程序LogServer的优化
广告日志接口TPS从之前的不到1k/s提升到2.1w/s,提升了近20倍。
工作日志界面的TPS从之前的不到1k/s提升到了1.4w/s,提升了13倍。
1.广告日志界面压测结果部分截图
arti2.png
2.Works 日志界面压测结果部分截图
arti3.png
以下 TPS 提升为粗略值。
5.1 删除代码中不必要的打印日志
例如
System.out.println
System.out.println
logger.info
TPS 1k -> 3k
5.2 关闭logback.xml文件中的打印日志
例如
TPS 3k -> 5k
5.3 获取kafka相关loggers的代码优化
例如
之前的代码
public synchronized static Logger getLogger(String topic) {
Logger logger = loggers.get(topic);
try {
if (logger == null) {
logger = LoggerFactory.getLogger(topic);
loggers.put(topic, logger);
}
return logger;
}
优化代码
public static Logger getLogger(String topic) {
if (logger == null) {
synchronized(KafkaLoggerFactory.class){
if(logger == null){
logger = LoggerFactory.getLogger(topic);
loggers.put(topic, logger);
}
}
}
}
TPS 5k -> 9k
5.4 简化流量广告逻辑
以前的做法:
广告数据作为普通日志数据处理,会经过所有的日志判断逻辑,最后验证后发送给Kafka,数据没问题。整个逻辑链比较长。
目前的做法:
先看代码
ip: String ip = request.getIp();
collection.put("ip", ip);
// 国家、地区、城市: collection.putAll(Constant.getRegionInfo(ip));
server_host: collection.put("srh", Constant.serverHost);
server_time: collection.put("s_t", System.currentTimeMillis());
if( "traffic_view".equals(collection.get("product")) ){
parseAdRecord(collection);
return Constant.RESPONSE_CODE_NORMAL;
}
...
public void parseAdRecord(Map collection){
try {
collection = Constant.clearAdCollection(collection);
log2kafka(Constant.eventTopic, JSONObject.toJSONString(collection));
} catch (Exception e) {
e.printStackTrace();
}
}
从上面的代码可以看出,广告的逻辑是分开处理的,整个链接要短很多。总共大约有 3 个步骤:
1 所需的公共字段处理
2 判断是否为广告日志
3 向 kafka 发送广告日志
TPS 9k -> 1.2w
5.5 精简广告日志中的字段
HDFS 上的广告日志中的 85 个字段现在减少到大约 45 个。虽然这一步并没有太多地提高 LogServer 的吞吐量。但它几乎可以使 Kafka 的吞吐量翻倍。
5.6 升级和简化依赖 首先,移除所有非必要的maven依赖,将依赖数量从217个减少到51个。升级maven依赖到更新的版本。删除了部分依赖,调整了相关类。例如 StringUtils.isEmpty() 已经从 spring 类中移除
org.springframework.util.StringUtils
调整为commons-lang3包中的mons.lang3.StringUtils
org.apache.commons
commons-lang3
3.10
6 服务器硬件级别
从之前的 4 核 8G 服务器迁移到 8 核 16G 服务器。
并对服务器内核参数做了如下优化:
net.core.somaxconn = 10240
net.core.netdev_max_backlog =262144
net.ipv4.tcp_keepalive_intvl = 5
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 60999
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
1.2w -> 2w
7 前端SDK优化
Kafka写压测试后,日志大小为1024字节时,QPS接近2048的两倍。
arti4.png
1 减少前端上报的日志字段数量,删除暂时不用的字段。前端SDK上报的日志字段从71个字段删除到48个字段,减少了32%的字段数。
2 不再上报不必要的日志,主要是修改前端日志上报的逻辑。
8 对 Nginx 的优化:
Nginx 的优化主要有两个方面:
服务器层面的优化,比如上面第5条Nginx本身的配置优化,增加了ip反刷机制8.1对部分Nginx配置的优化。
Worker_connections 已从 20480 增加到 102400,增加了 5 倍。提升之后,nginx的吞吐量从2w/s提升到了3.5w/s。设置时最好根据业务和服务器的性能进行压力测试。
worker_processes 默认为1,官方推荐和cpu的核数一样,或者直接设置为auto。有人建议将其设置为 cpu 内核数的 2 倍。从我的测试情况来看,不会有明显的提升,也可能是场景覆盖有限。
worker_cpu_affinity Nginx 默认不启用多核 cpu 的使用。可以通过worker_cpu_affinity让nginx使用多核cpu,将worker绑定到指定线程,提高nginx的性能。
multi_accept 默认情况下,Nginx 不启用 multi_accept。 multi_accept 允许 nginx 工作进程接受尽可能多的请求。它的作用是让工作进程一次性接受*敏*感*词*队列中的所有请求,然后进行处理。如果multi_accept的值设置为off,那么worker进程必须一一接受*敏*感*词*队列中的请求。
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
worker_connections 102400;
multi_accept on;
优化后QPS从10000左右提升到3.5万。
8.2 ip 防刷
在conf/module/中定义了一个黑名单文件:
map $http_x_forwarded_for $ip_action{
default 0;
~123\.123\.29 1;
}
在nginx.conf中添加ip过滤配置:
location /log.gif {
if ($ip_action) {
return 403;
}
proxy_pass http://big-da/log-server/push;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 128k;
client_body_buffer_size 32k;
proxy_connect_timeout 5;
proxy_send_timeout 5;
proxy_read_timeout 5;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
如果是黑名单中的ip,则直接拒绝请求。
9 Kafka 的优化
1.将所有重要topic的Replication从1改为2,以保证Kafka一个节点故障时topic也能正常工作。
arti5.png
2.为每个节点的kafka设置一个专用的SSD硬盘。
ic 分区数根据业务需要设置。我们已经设置了 6 个分区。
3.在生产者端使用snappy压缩格式编写Kafka
4.生产者端合理设置batch.size
batch.size 用于控制生产者在将消息发送到 Kafka 之前需要积累多少自己的数据。默认16kB,经过测试,在32kB的情况下,吞吐量和压力测试都在可接受的范围内。
5.在生产者端合理设置linger.ms
默认没有设置,只要有数据就立即发送。 linger.ms可以设置为100,当流量比较大时,可以减少发送请求的次数,从而提高吞吐量。
6.升级版,kafka从0.10升级到2.2.1