常见优化方式(持续更新)
数据探查 从业务或者历史数据层面减少数据量是最有效优化。
数据读写
1、结构化处理,统一查询,逻辑处理,数据保存。避免逻辑中耦合查询导致重复查询
常用的池化操作
2、批量操作,减少网络RTT,减少网络 I/O,多次网络io 涉及到内核到用户态的多次切换 。如果开启压缩的话,压缩比例较高效果较好。如pipline,批量查询,批量写入
3、多线程或者异步rpc,当不能批量查询批量写入的话,可以开启多线程处理,或者异步rpc并行,以降低执行时间,前提是,下游(其他方,存储介质 qps能扛得住)
4、多级缓存,堆,redis,数据库+ 布隆过滤器。如果qps很大基本都是内存操作了。如倒排索引,redis底层实现。
多路复用,mmap,零copy,通过顺序写减少随机写。
数据处理
1、批处理,串行改并行,多线程处理。要使用动态线程池调参。
2、开多线程导致 cpu过高,负载均衡,加机器,进行分发。
3、同步改异步,保留主要操作同步,非必要操作异步。改成异步就要考虑任务管理机制,待处理,处理中,处理完成,失败重试,幂等。
4、预处理,异构数据源(空间换时间)。避免查询的时候做复杂的处理进而影响速度
5、逻辑复杂度,刷题leetcode吧
读 1、多级缓存+布隆过滤器 2、结构化查询 写 1、预写 2、0copy 读写 : 1、批量, 2、异步io 数据处理 1、预处理 2、批处理 3、多线程,负载 4、异步化 5、时间复杂度
JVM 优化
1、调整参数,选择合适的优化器。
2、避免创建大量创建占用空间很大的临时对象。 如果查询数据库查所有的字段。对象大小一定,但是值暂用空间 避免无效日志打印,序列化出来的对象比原来的对象还大。且日志打印,需要io,io耗时。最好改成异步日志。
数据库优化
innodb选择索引的方式也是根据磁盘io和cpu的
减少数据量(结转,分表,分库)。减少磁盘io,减少cpu。
减少磁盘io:走覆盖索引,避免回表。
减少cpu:不走索引排序,走内存排序。逻辑处理较少的数据量
按需查询,避免使buffer pool失效
排查问题疑难杂症
服务端处理很快,但调用方处理很快。
- 未及时处理缓冲区数据。应用节点JAVA GC导致Stw,应用程序线程池耗尽,应用程序oom。没时间处理缓冲区数据,机器关闭链接但未处理缓冲区数据(同步阻塞),异步回调线程池耗尽。
- 客户端与服务端网络异常,确认ping回包延时,网络重传、丢包等
- 读写超时时间设置的过短
服务端本身很慢
- 服务端处理很慢(如redis大key)
- 服务端实例挂了,(如redis 对于 迁移、合并、扩容会有小短时间的超时,尤其在服务端实例存储数据较多情况时)
自己的一些思考
前端定位,渲染,交互优化体验,简单计算,校验。 不适合做复杂的逻辑