面试问题
一、什么会对mysql的性能造成影响
1.CPU性能
2.内存
InnoDB同时缓存数据和索引到内存中
3.磁盘I/O:当热数据大小远远大于内存大小时,磁盘I/O回制约MySQL性能(大量查询)
4.SQL(语句)脚本
如何提升SQL执行效率
-
避免全表扫描,可以通过建立索引的方式,也可以通过新增有效过滤的方式(<= >= = > < between and 有效过滤)
建立索引的方式:
create index ind_ on table_name(col)
可以给where或order by的列建立索引;尽量避免使用!=或<>,not in(mysql 只会在使用<= >= = > < between and in(在可以使用between and 时就不要使用in,也可以使用exists代替in)时索引才会起作用),or(可以使用 union 代替)
-
优化查询语句
- 在select字句中尽量避免Select *
- where 语句中 比较 的左侧尽量避免使用函数
- 尽量避免使用union all (union all 带有去重的功能)
- 尽量避免给使用distinct,可以使用group by 代替
- 当不需要查询所有数据时,使用limit限制所需要查询的行数
- 尽量避免查询到null,推荐使用not null(无法避免查询时,可在建表时将null转换成一些字符譬如0,1)
使用count(1)代替count(*)
-
使用查询缓存
开启缓存
SET global query_cache_size = 10000; SET global query_cache_type = 1;
-
使用JOIN代替子查询
-
合理使用分区
-
使用批处理的方式减少I/O操作
-
使用临时表优化复杂查询
5.数据库参数(&服务器)配置服务
6.大表操作(对表进行分区或者分表,使用hash函数;建立合适的索引;减少字段的选择;分批次查询,合理使用limit和offset;)
7.大事务操作
二、MySQL的日志文件有哪些
1.binlog(二进制日志):master对数据库的修改已二进制的方式记录在binlog中(创建表,更新数据库,已经对表的增删改),逻辑日志,记录了数据的原始逻辑;大小不固定,可在后面追加,写满后就写下一个
主要用于主从复制,实现主从同步;用于数据库基于时间点的还原
如何实现主从复制:
一台或者多台数据库(slave)对另一台机器上的数据库(master)进行复制,实现数据同步
原理
1.master将改变记录到binlog中
2.slave将binlog改变拷贝到自己的中继日志中
3.slave解析执行自己的中继日志,实现数据的统一
功能:负载均衡,读写分离,数据备份
2.undolog(回滚日志):用户执行的事务或者语句失败了,可以使用undolog对数据经行回滚,将数据恢复到未进行执行前;主要记录的是数据逻辑变化
3.redolog(重做日志):使用WAL技术实现(即先写日志后写磁盘),降低物理页的输出,提升数据库的吞吐
提供了cash_safe的功能,使其在mysql异常重启后也不会丢失数据;物理日志,记录了数据在什么时候进行了什么修改
大小固定,从头开始写,写满之后又从头开始
redolog分为prepare 和commit两阶段;redolog先写入缓存区在溢写进磁盘中
InnoDB会将操作记录到redulog中并将数据更新到内存中,在闲时或者适当的时候,将操作记录写到磁盘中
4.errorlog(错误日志)
5.slowqureylog(慢查询日志):记录查询时间过长或者是没有使用索引的查询语句
6.general log(一般查询日志):记录服务器接收到的每一个查询或命令
7.relay log(中继日志)
三、HDFS的读写流程
HDFS的读流程
-
client向namenode申请需要读取的数据
-
namenode查找元数据是否存在,存在则返回数据所在的datenode的地址,不存在则返回不存在的表示
-
client拿到地址后对datanode申请读取数据
-
datanode接受到namenode的指令后向客户端返回数据
HDFS写流程
-
client端向namenode申请上传文件,namenode查询文件是否存在
-
namenode返回查询结果,如果name返回为不存在则,则下一步
-
client端向NN申请写第一块block的datanode地址
-
NN返回DN地址
-
client根据NN返回的地址向DN写第一块block
-
NN之间建立传输数据的通道,并传输数据
-
数据写完后逐级传输信号,并最终传给client
-
client接受到写完的数据后向NN发起第二块block的书写请求。。。重复直至数据全部写完
-
关闭所有连接
四、HBase的读写流程
HBase的读流程
- Client与zookeeper建立连接,拿到元数据存储的regionserver(即hbase:meta表被那个regionserver管理)
- 连接meta表所在的regionserver,获取你所需要读取表的信息(表名,列簇,列,表存储在那些region上等信息)
- 连接表所在的region server,对数据经行读取(读取顺序是memstore-》blockcache-》HDFS)
- 当读取的数据涉及到多个region是,HBase会在regionserver端将数据经行合并后返回给客户端
HBase的写流程
- Client与zookeeper建立,拿到元数据存储的regionserver(即hbase:meta表被那个regionserver管理)
- 连接meta表所在的region server,从meta表中得到需要写入表的地址及信息
- 与要写入数据的region建立连接,开始写入数据。写入数据时首先将数据写入HLog(HLog存储在HDFS中,即使发生宕机数据也不会丢失)中,然后将数据写入到store模块中的memstore中,当HLog与store模块都写完后,表示数据写入完成
- 当memstore中的数据越来越多时会将数据存放到blockcache中,当blockcache到达一定的阈值时,会将数据flash进HDFS中生成Hfile文件
- 当blockcache不停的刷新,会产生很多小的Hfile文件,当小文件达到一定的阈值时,会触发compaction机制将这些小的HFile会合并成一个大的HFile。
- 当HFile到一定的阈值时,会触发splite机制,将region也分为两个,HMaster会将文件非为两部分分别存储在两个region中,实现负载均衡。原本的HFile文件及region会进行下线处理
五、Yarn资源调度流程
Yarn Job提交流程
- MR提交到client,client向Resource Manager提交资源申请
- RM返回一个Application Id 及所需的资源路径
- client提交job资源
- client资源提交完成后,向RM申请Application Master
- RM将申请初始化成一个task,并将task发送给一个Node Manager
- NM接收到task后,启动AppMaster及container
- 下载client提交的job资源到本地
- AppMaster向RM申请运行Map Task
- NM将接收到的Map Task分发给各个NM
- AppMaster接收到Map Task运行完成的信息后,向RM申请运行Reduce Task的资源
- NM将接收到的Reduce Task分发给各个NM
- 当MR运行结束后向RM申请注销
Yarn资源调度策略
FIFO先进先出策略,根据时间先提交先运行
Capacity Schedule 容器调度器,允许多个组织共享集群资源,再根据组织配置分配集群资源
Fair Schedule 公平调度器,为集群内所有应用平均分配资源
六、redis持久化机制(可生成一个xmind文件)
持久化:利用永久性存储介质将数据进行保存,并且在特定时间可以进行恢复的机制
Redis持久化方式
-
RDB(Redis Data Base):直接将内存数据保存到硬盘
在指定的时间间隔将数据集快照到硬盘中
Redis会创建一个子进程用于持久化,会先创建一个临时文件,持久化结束后,会代替原先的文件。主进程不回经行任何I/O操作,保证了Redis的高效,但是会有丢失最后一次持久化后的数据
-
AOF(Append Of File):以日志的形式保存Redis的所有写操作,文件只执行追加操作,Redis重启后可根据该日志将Redis写操作从头到尾执行一遍达到恢复数据的目的
七、spark问题
Spark常用的RDD算子
Spark常用算子一般分为三种
action算子(触发spark Context提交job作业):foreach、take、count、reduce等
Transformation算子(不触发执行操作,懒执行算子):map,flatMap、reduceByKey,groupBy、groupByKey、distinct、filter等
缓存类算子:cache、persist、checkpoint
cache:懒执行算子,主要作用是将数据持久化到内存中,持久化单位是partition。当application运行结束时,数据也会被删除,相当于persist(memory_only)
persist:懒执行算子,会将数据落地到磁盘,但对用户不可见。持久化单位是partition。存活时间是在application运行结束前。
checkpoint:将数据落地到磁盘中,相当于将数据经行快照,主要用于RDD血缘线过长(切断其血缘关系,省省略重复计算),或者是宽依赖的容错机制,主要是将数据存储到磁盘中。
spark如何实现容错的
1.调度层面:spark会在task及stage分别进行重试。默认是4次
2.血缘关系层面:子RDD是transformation算子基于父RDD生成的,当子RDD丢失时,只需要计算其父RDD所在的分区即可,但由于宽依赖的父RDD与子RDD是多对多的关系,会产生冗余计算,可以使用checkpoint避免
checkpoint,当数据的RDD链太长时,可以在合适的位置使用checkpoint截断,并将数据进行保存,在这个点生成新的RDD,当RDD为宽依赖时,可以使用checkpoint记录快照数据,避免冗余计算。当子RDD数据丢失时,只需要对checkpoint数据经行计算即可。
Spark内存管理
spark内存管理分为两种分别是:静态内存管理和统一内存管理模型
静态内存管理:
Reserved(预留)内存:占storage内存的10%,用于预防OMM
storage内存:占整个内存的60%。用于存储RDD数据及内存广播数据
executor内存:占整个内存的20%。用于缓存shuffle过程中产生的中间数据
other内存:占整个内存的20%。用于存储用户自定义数据结构及spark元数据
统一内存管理模型:是将storage内存与executor内存经行统一管理,占整个内存减去系统预留内存(300M)的60%
Reserved(预留)内存:默认300M,用于预防OOM
storage内存:默认整个内存-预留内存的60%*50%。用于存储RDD数据及内存广播数据
executor内存:默认整个内存-预留内存的60%*50%。用于缓存shuffle过程中产生的中间数据
other内存:默认整个内存-预留内存的40%。用于存储用户自定义数据结构及spark元数据
规则:当内存不足时,会将数据溢写到磁盘中,当storage内存不足时,而executor内存有盈余时,storage内存会占用executor内存,当executor内存也不足时,storage内存会释放占用的executor内存,释放规则时LRU;但当executor占用storage内存后,storage内存不足时,executor不会释放占用的内存