From a07b5b03a6a597d89afd3f943ca0bc834b3dd944 Mon Sep 17 00:00:00 2001 From: lixicai <1210922622@qq.com> Date: Mon, 3 Apr 2023 23:18:17 +0800 Subject: [PATCH] =?UTF-8?q?2023=E5=B9=B44=E6=9C=883=E6=97=A523:18:16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MySQL性能调优与架构设计.md | 116 +++++++++++++++++- 简历.md | 178 ++++++++++++++++++++++++++++ 2 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 简历.md diff --git a/MySQL性能调优与架构设计.md b/MySQL性能调优与架构设计.md index 5c77792..90ce492 100644 --- a/MySQL性能调优与架构设计.md +++ b/MySQL性能调优与架构设计.md @@ -190,7 +190,7 @@ MySQL 通过查询优化器去判断用什么索引,或者全表扫描 - 索引列的类型尽量小 - 索引列的选择:(索引的选择性/离散性)不重复的索引值和【总数(n)】的比值越高则查询效率越高( 1/n ~ 1 ) -​ 可以这样查询:select count(distinct name)/count(*) from person; --查询name列的离散度,最佳为1,最差为1/n + 可以这样查询:select count(distinct name)/count(*) from person; --查询name列的离散度,最佳为1,最差为1/n - 前缀索引:针对blob,text很长的varchar字段,mysql不支持他们的全部长度,需要建立前缀索引。 @@ -242,4 +242,116 @@ MySQL 通过查询优化器去判断用什么索引,或者全表扫描 - 架构调优(性价比高) - 系统设计:数据不合适:es、MQ、redis、读写分离、安全 \ No newline at end of file + 系统设计:数据不合适:es、MQ、redis、读写分离、安全 + +## 什么慢查询(查询性能优化) + +> 查询慢需考虑的点: + +- 请求了不需要的数据? + - 查询不需要的记录 分页的时候注意 + - 总取出全部的列 不要写select * + - 重复查询相同的数据 热点数据多用缓存 +- 是否在扫描额外的记录? + - 相应时间 服务时间(执行sql)+排队时间(等锁,等IO) + - 扫描的行为和返回的行数 + - 扫描的行数和访问类型 + +> 查询优化:(慢查询):慢查询是指查询时间比较高的查询 + +> 慢查询的核心原因:数据量过大——》方案:减少数据的访问量 + +​ 举例: select * from order_exp limit 10000,20; -- 查询的结果只有20行数据,但是mysql不仅仅处理20条数据,而是访问和处理10020条数据。 + +> SQL整体优化 + +​ 1.使用覆盖索引 + +​ 2.数据表结构,统计汇总,报表,汇总信息(汇总表) + +​ 3.重写复杂的查询SQL + +> 慢查询配置 + +​ mysql记录所有超过slow_query_time秒阈值的语句 + +​ show variables like 'slow_query_log' -- 查看慢查询开关 + +​ show variables like 'slow_query_time' -- 慢查询记录的时间 + +​ show variables like '%slow_query_log_file%' --记录慢查询的日志文件的存放位置 + +​ show variables like '%log_queries_not_using_indexes%' -- 没有用到索引的语句是否要记录到日志来。 + +​ set GLOBAL show_query_long=1 -- 开启慢查询记录 + +​ Rows_examined: 扫描行数,Rows_sent:结果行数,Query_time:查询时间 Lock_time:拿锁的时间。 + +> 慢查询分析工具 + +​ 慢查询文件工具,mysqldumpslow命令 , mysql的bin路径下。 + +​ 例子 -s(排序) r(通过sql返回的行数) -t(倒序) 10(展示十条):mysqldumpslow -s r -t 10 centosvm-slow.log + +## 执行计划 + +> 什么是执行计划 + +执行计划的语句 + +​ 在SQL查询的前面加上explain关键字就行。比如:explain select * from order_exp; + +> 执行计划详解 + +id、 select_type、 parations、 type、 possible_keys、 key、 key_len、 ref、 rows、 filtered、 Extra + +问题:explain select * from s1 where id in (select id from s2)中 id有两个都是1 + +这是因为语句被优化成了 select s1.* from s1 left join s2 on s1.id=s2.id所以只有一个查询id + +问题:explain select * from s1 union select * from s2;中有一个id是null的记录 + +这是因为union需要用临时表去重。 + +select_type:通过某个小查询的select_type属性,就知道了这个小查询中在大查询中扮演一个什么角色 + +​ simple:简单的select查询,不使用union查询 + +​ primary:最外层的select查询即主查询 + +​ union:union中的第二个或随后的select查询,不依赖于外部查询的结果集 + +​ union result: union结果集 + +​ subquery: 子查询中的第一个select查询,不依赖于外部查询的结果集 + +​ dependent union : union中的第二个或随后的select查询,依赖于外部查询的结果集 + +​ dependenct subquery:子查询中的一个select查询依赖于外部查询的结果集 + +​ derived:用于from子句里有子查询的情况。MySQL会递归执行这些子查询,把结果放到临时表里 + +partitions + +​ 和分区表有关,一般的都为null + +type:执行计划的一条记录就代表 MySQL对某个表的执行查询时的访问方法、访问类型,其中type列就表面了这个访问方法/访问类型是个什么东西,是较为重要的一个指标,结果值从最好的排到最坏的依次是:system、const、eq_ref、ref(通过二级索引的等值查询一般是ref)、fulltext(全文索引)、ref_or_null(当where条件如:order_no='abc' or order_no is null)、index_merge(索引合并,并不是用到了两个索引,而是合并),unique_subquery()、range(范围查询)、index、ALL + +key:如果是null就是ALL全表扫描,key如果是PRIMARY就是主键,如果有多个索引则为索引合并但并不是用到两个索引。 + +key_len:表示当优化器决定的某个索引时候用的最大长度字节。使用复合索引的时候,可以用于计算出复合索引用了多少个字段 + +utf-8编码每个字符用3个字节。 + +ref: + +rows: 预估扫描行数 + +filtered: 预估 rows中有百分之多少的记录满足条件 + +Extra:对总的一个概括,如用到了where条件去查询,Using where。如用到了索引,Using index; + +> 驱动表和被驱动表 + +如果一个是ALL另一个是eq_ref,则eq_ref是驱动表,驱动表可以理解为先查的表 + diff --git a/简历.md b/简历.md new file mode 100644 index 0000000..f09eb6c --- /dev/null +++ b/简历.md @@ -0,0 +1,178 @@ +姓名:李希才 性别:男 年龄:27岁 邮箱:1210922622@qq.com + +籍贯:湖南 学历:本科 学校:湖南工业大学 电话:17716772730 + + + + + + + + + +1. 看面试突击课,明确要做的事情,预估面试内容,面试流程,强准备面试逐字稿。 +2. 收集常见的面试问题,收集简历中的重点知识,收集岗位描述的重点。 +3. 排优先级,整理答案 +4. 对着镜头回答问题。 +5. 面试后简历润色,先学如何写简历。 + + + + + +1.整理百万级订单导出 + +2.排查jvm,mysql调优 + +3. + +个人简介: + +我叫李希才,年龄27,学的是软件工程专业 + +上面是我基本信息,接下来向您说下我最近的一个项目和一个我自己觉得还满意的一个项目。 + +最近一次工作经验是在一家创业型公司担任一个web漏洞扫描的产品的后端开发,这个项目的价值是主要是为政企和一些军事提供国产化的web漏洞扫描能力。这个项目是我从12月进公司后立刻启动的,我的角色是负责这个项目的全部后端代码。这个项目的结构是通过一个开源的web扫描框架zap将其saas化和定制化。接下来我要说的是这个项目的重点和难点,考虑到您可能没有接触过这个业务,所以在说这个之前我首先要简单阐述下zap也就是国外的这个web扫描框架的原理和功能,web扫描的主要功能是:输入站点,zap会爬取该站点的所有资源【通过点击页面的特定html标签来实现】,并且通过网络代理拦截的方式对请求和响应做分析,看是否存在安全问题,爬取完站点后,zap能够将这个站点所有的请求整理起来形成站点树【站点树是指的以网站域名为根节点,后面的path根据斜杠依次为子节点的树】这个概念如果你不关心可以跳过,并且进入主动扫描阶段,这个阶段会将之前的请求全部拷贝一遍,通过修改成带有攻击性的参数来进行扫描。以上扫描功能的概况,回过来介绍对zap进行saas化和定制化的重点和难点。这个项目首先面临的问题是,这个zap之前没有人了解它的原理,包括上述我说的这些也是我后面通过自己打断点跟踪总结得来的。在经历了半个多月左右的时间我大概摸清楚了这个zap项目的代码和流程,我遇到的主要问题是由于zap是一个桌面应用,它没有考虑saas相关的数据隔离问题,所有的数据信息仅仅满足于桌面的展示提供的api也没有对数据或者操作进行数据跟踪的管理。同时zap对于网站的登录没有提供友好定制化的api服务。因此需要对源码进行大刀阔斧的修改。这个项目目前我说的问题都已解决,目前项目的阶段是核心功能开发完毕,正在进行一些系统型的管理功能开发。 + +接下来将的项目是一个订单导出的项目,也就是简历中的第一个项目。这个项目最开始是以一些线上的订单导出问题引起的:订单导出的单量数目不对,订单重复导出,订单导出慢,大单量订单导出的失败等等问题。我首先排查的是订单重复导出的问题,因为这个很容易联想到幻读,经过查看代码发现却是是没有加事务导致的。于是在这里我加了事务,随即又出现了性能问题。我想到了分治算法,但是这个不能直接用的因为订单的数据是变动的所以如果将导出的条件分而治之,那必定还会出现订单数据问题。后序我通过分析流程,推演,组合各个优势研究出了一套既能保证数据量正确,又能保证导出效率的流程,通过参考mysql处理幻读的方案,即mvcc对事务进行数据的版本控制,在每次导出前先将订单的id存储在一张运行时表中,这张表的职责相当于对导出的订单id做了一个快照,这样幻读的问题就解决了。在第二阶段通过对运行时表的读取,通过订单id再对订单导出即可。在后序的两周内我迅速开发出一款简易版,中间有一些小插曲,如apache poi出现了oom,通过灰度检测,达到了百万级订单导出的效果,但还是有导出速度过慢的问题,通过arthas和日志跟踪的技术定位制作快照耗时较长占到整个导出的百分之60,通过日志分析发现是深分页导致,项目中虽然也有分页的切片方法但是只能更具时间来切分,如果遇到了抖音这种瞬时单量较高的店铺还是会有深分页的问题,所以我改用了流式查询的方式也就是jdbc中的fetch方法,当然读写也是分离的,这点在一开始我就考虑到了。通过流式查询的方式性能有极大的提升,从之前的100万一个半小时达到了100万20分钟的程度。另外的就是一些业务的优化了,在订单导出这个冗长复杂的链路中有大部分服务调用,我全部合理的将其改为异步调用等等。整个项目做了2个月从发现问题到定位问题,再到设计方案,推动项目,我较强的主人翁意识,有自己的节奏和思路,能够主导事情的发展。 + + + +接下来我介绍一下我从业的心路历程,我在毕业后是在一家民营企业工作,由于下班一直在学习各种技术,所以在公司工作能力比较突出,同时为人还行所以被一个前同事内推到了光云科技,我也是在这家公司得到了不错的发展,在这之前我的一个重心是在技术上的,到了光云后通过和同时的相处我慢慢发掘到了自己的一些除了技术需要深耕的点,这也是我一直在修炼的东西,第一个就是习惯,因为我看到了我们在长沙的主管是一个有跟多好习惯的人,比如说早起,精力充沛,有专注力。这些我能够感觉到这些好的习惯对人生和工作的用处是很大的,如果我没有好的专注力,我不可能研究的怎么深,如果我作息不规律,或者晚起迟到我能感觉到我的工作不在状态,我也慢慢的有一种感觉就是我如果晚上没有休息好对白天的思考是有阻碍的,这点其实我高中是知道的,但是工作后重拾专注力才重新被发现。所以我现在的一个阶段除了修炼技术外,还有一个重要的点就是修身修心,修得好习惯。早起,早睡,几乎每天工作都做计划,面对任务缓启动,深度工作,已经很少有哪一天没有深度工作了,感觉现在生活的很充实。我从2022年年初就开始了好习惯的修炼现在我能够很好的管理自己的精力。以上是我对我自己从业的一些阶段性心路历程总结吧,从对技术的探求,到对自己工作心法,生活习惯的一个探求。 + + + +事务特性:原子性,一致性,隔离性,持久性 + +隔离级别:读未提交,读已提交,可重复读,串行化 + +隔离级别要解决的问题:脏读,不可重复度,幻读 + +mysql如何解决幻读:幻读是指,在同一个事务中,进行两次查询,第一次查询的数据和第二次查询的数据不一致,注意这里仅仅只是说数据不一致。并没有说结果。如何解决幻读,mysql通过mvcc机制也就是多版本控制的方式对数据进行快照,保证同一个事务前后查询的数据是一致的,这里的重点是幻读的理解,注意是查询的数据不一致,mvcc保证了同一个事务,数据是一致的,用的都是这个事务开启时的快照。这里会有一个问题。因为是用的快照,所以如果在这里使用更新操作就还是会出现并发问题,如果要解决并发问题,则需要加排它锁或者将事务调为串行化。 + + + + + +jvm排查逻辑: + +我一般会先dump,因为最确定最权威的一定是dump.hprof文件,但是dump比较慢,分析也比较慢,那就要根据经验去排查。首先我会看日志,看看当前这个机器最后打印了哪些日志,看看有哪些线程打印日志,然后如果jvm还在跑,也就是没有报oom前,或者是有多台机器,目前只有一台挂了,作为备用的机器,我用arthas看一下,看下它top5的线程,线程名是什么业务,然后如果有感觉了,就去看代码,如果还没有感觉,那可能是提交了新的代码没有充分测试就上去了,我就去看下最近git提交的mr有哪些,如果一般到这里就会发现一些可疑的,如果还没有发现,那只有一种可能,一种可能是代码却是是老代码,最近才触发,这个不急,看dump日志,因为一般到这一步多多少少看出一些问题的。以上是定位。定位完成后就分析分析 + + + +由于zap是一个桌面的应用,其提供的api是不具备管理功能的,对数据是没有域的划分的,开启一个扫描你想要通过api拿到他的所有请求是拿不到的,所以这就需要你去对消息和数据进行链路跟踪,况且zap扫描的id每次启动都要清零,所以如果直接用zap的id的话数据将会紊乱,所以需要一个比较好的数据链路追踪方案, + + + + + +1. 看面试突击课,明确要做的事情,预估面试内容,面试流程,强准备面试逐字稿。 +2. 收集常见的面试问题,收集简历中的重点知识,收集岗位描述的重点。 +3. 排优先级,整理答案 +4. 对着镜头回答问题。 +5. 面试后简历润色,先学如何写简历。 + + + +面试: + +​ 面试中最怕的是:两个人或者多个人都不说话。面试的正常节奏应该是面试者去说而面试官去听,如果一场面试中1小时问了10个问题,那么这场面试不会是好的。 + +1.如何进行自我介绍? + +​ 包含几个层面: + +​ 【基本情况】:姓名,年龄,学校和专业 + +​ 【最近一段时间的工作经验】:(一个最熟悉,技术栈最丰富的,互联网行业的经验项目),当前项目的价值,用到的技术体系,在当前项目中承担的主要职责,和自己解决的项目的主要问题凸显出技术实力 + +​ 【说一下对面试这一家公司的了解】: 企业背调,展示态度 + +​ 【面试官,上面就是我的个人简介,您看您有什么想了解的】 + +2.如何陈述自己的项目? + +​ 【不要把所有的项目都说以便,这样显得没有重点,拿一个最近,最熟练的项目进行表述】 + +​ 记住逻辑性和条理性---总分总 + +​ 1.先表述当前项目的核心价值,包括核心的功能 + +​ 2.说明当前项目中你参与的核心技术模块,职责描述,技能栈(项目架构),(自带a4纸和笔,画框架) + +​ 3.描述项目开发过程中存在的技术问题,以及你的技术解决思路和方案。(不要说方案是问领导,问同事,一定是自己解决的) + +​ 4.()根据情境来进行添加:我之前了解咱们公司用到的也是当前的技术,用到的也是此行业解决方案,您能和我说一下我们公司的一些技术和解决方案吗? + +​ 5.面试官,上面就是我对自己项目经验的简单介绍,您看你有什么想问的? + +3.如何回答自己会的问题? + +​ 1.回答问题的时候要注意总分的思想。 + +​ 为什么需要主从复制,解决了什么问题? + +​ 2.分步骤来说明实现的机制 + +​ 1.首先,第二,第三,延迟问题,怎么解决(带出你之前的实际工作经验,项目挂钩【设计简历】),关联技术,读写分离,分表分离。否则给人的感觉知识不成体系,碎片化。 + +​ 2.面试官,我已经回答完了,刚刚的是我对于我这个知识的理解,您看下哪里有问题,可以帮我指点下。 + + + +4.如何回答自己不会的问题? + +​ 分两种情况 + +​ 1.有一点了解,或者接触过类似的 + +​ 不好意思,这东西我没有接触过,但是我了解一个类似的技术。 + +​ 2.一点都不会,没听说过 + +​ 不好意思,这东西我没有听说过,但是我相信能够很快学会,如果公司有需要的话。您能告诉我,在咱们公司的技术体系中是怎么使用的吗?切记,不要不会装会。 + + + +5.如何谈薪资? + +​ 比预估的多一点,然后和Hr聊薪水,首先谈22k,然后hr会压薪水,你要问他能给多少。 + + + +--- + +我叫李希才,毕业自湖南工业大学软件工程专业,毕业从业软件开发4年 + +接下来我介绍一下我最近的一个项目和我之前我做过的一个有代表性的项目,另外我再说一下我从业的一个心路历程 +摘要: +1.web扫描,为政企提供web扫描能力 +2.我在项目中担任的角色 +3.项目遇到的问题和难点,首先说一些web扫描的一个原理流程,分阶段 + 1.介绍zap的原理 + 2.一开始不了解代码 + 3.桌面级应用转为saas运用,需要数据跟踪 + 4.定制化的登录 + +1.订单导出项目,大单量客户使用订单导出功能出现订单导出重复,订单数据不对,订单排序不对,订单导出慢,导出失败等种种问题 +2.我在项目中担任的角色,最开始我是作为一个bug去修复他的后来组长发现我对这个导出研究的比较深就全给我了,在订单导出重复和订单数据不对这个问题是很熟悉的幻读问题。后序的一些并发性问题发现这个功能并没有这么简单我去拉动会议组织人去弄了一个项目 +3.下面我介绍下项目一些大的阶段遇到的问题和难点 + 1.我首先是按照幻读去处理将隔离级别设置为可重复读,这里因为是循环分页的,所以没有一个统筹的rr级别的事务,另外限制单量。 + 2.这个虽然解决了解决了重复,但是对于百万级别的订单是需要导出上百次的。 + + 3.我想到了分治算法,但是由于需要考虑到数据的变动,所以是不能直接用 + 4.后来我通过参考mysql的mvcc对事务的数据做版本控制,研究出了一套非常契合的流程:流程如下【首先做一个只含有订单id的事务快照,然后再对订单id分批导出】 + 5.这个流程能很好的解决数据变动的问题,也就是幻读的问题。 + 6.在经历了一周左右的时间我开发出来了一个半自动的版本,其中有一些小插曲,比如导出oom,在开发环境中确保解决后,我上到了灰度环境 + 7.新的问题又出现了,导出的数据虽然是正确的,但是效率依然很低,百万订单需要导出1个半小时。 + 8.我通过arthas结合日志埋点,排查到在这个流程中,制作快照用了将近20分钟,甚至更久 + 9.通过分析我发现是深分页的问题,虽然我对时间做了切片,但是由于某些店铺的特征,如直播带货这种瞬时单量极大的,那么还是会有深分页的问题。 + 10.我通过采用jdbc fetch方法来进行流式查询,将其快照缩短到了5分钟,当然写快照和读快照也是读写分离的,另外通过分治算法,将快照切割为多个部分导出多个订单Excel文件。 + 11.因为在导出这个流程中有很多的业务请求,我将其比较大头,耗时长的改为了异步的方式 + 12.另外还有一个问题,这个问题又经过了一个月的抽离将服务起来了,因为老项目的代码耦合性过高。 + +我的心路历程:我最开始是进入一家小公司,由于工作技术能力比较突出然被同事推荐到了光云科技,在这里我除了技术我更多的学习到了做事的方法和态度,或者说个人的习惯,意识到了习惯的重要性,好的作息好的习惯能够带来专注力和深度工作的能力,让我能够深入到业务中去不厌其烦的去调试和代码获得业务知识,我慢慢奉承了一句话,答案都在代码中,我现在修炼的是我的专注力,我能够缓启动深工作,在处理项目管理方面的问题我奉承识别主要冲突解决主要冲突的原则对项目进行阶段性的划分。 +以上是我对自己的一个全部介绍,面试官。 + 事务特性:原子性,一致性,隔离性,持久性 + 隔离级别:读未提交,读已提交,可重复读,串行化 + 隔离级别要解决的问题:脏读,不可重复度,幻读