首页
登录 | 注册

面试总结(一)

一.怎样实现限流?

限流特性是指:开关或熔断器在开断故障电流时,对通过自身的故障电流的峰值有一定的限制作用。熔断器的限流作用比开关明显许多,只是开关的的25%,它的意义在于不用过多的考虑线路和其它零配件的极限承受能力,而且还能开断比较大的故障电流,必须配合熔断器开关使用。

很多时候会遇到这种场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务的应用系统。

在面对大流量时,应该如何进行流量控制?

服务接口的流量控制策略:分流、降级、限流等。

限流策略,虽然降低了服务接口的访问频率和并发量,却换取服务接口和业务应用系统的高可用。

限流的方式有:

  1. Nginx前端限流  :   按照一定的规则如帐号、IP、系统调用逻辑等在Nginx层面做限流
  2. 业务应用系统限流    ①客户端限流   ②服务端限流
  3. 数据库限流  : 红线区  , 力保数据库

二.常用的限流算法:

令牌桶算法

1)存放固定令牌的桶,生产令牌的速率固定 
2)当令牌达到上限时候,产生的令牌被丢弃或拒绝 
3)n个请求过来,拿n个令牌,若令牌不足,则请求被决绝或等待

漏桶算法

1)桶容量固定,固定速录流出 
2)桶是空的,不流出 
3)以任意速率流入桶,若超过桶容量,被丢弃

三.MySQL存储引擎中的MyISAM和InnoDB区别

MyISAM是MySQL的默认数据库引擎(5.5版之前)

InnoDB,是MySQL的数据库引擎之一(目前默认)

区别:

1、 存储结构

MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。

2、 存储空间

MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。
InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。

3、 可移植性、备份及恢复

MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。

4、 事务支持

MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。

5、 AUTO_INCREMENT

MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列。

6、 表锁差异

MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。
InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。

7、 全文索引

MyISAM:支持 FULLTEXT类型的全文索引
InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。

8、 表主键

MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。

9、 表的具体行数

MyISAM:保存有表的总行数,如果select count(*) from table;会直接取出出该值。
InnoDB:没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。

10、 CURD操作

MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。

11、 外键

MyISAM:不支持
InnoDB:支持

所以使用InnoDB来替代MyISAM引擎,原因时InnoDB自身很多良好的特点,比如事务支持、存储、过程、视图、行级索等等,

在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。

四.SQL优化

①什么是优化?

  1. 合理安排资源、调整系统参数使MySQL运行更快、更节省资源。
  2. 优化是多方面的,包括查询、更新、服务器等。
  3. 原则:减少系统瓶颈,减少资源占用,增加系统的反应速度。IO次数CPU的运算复杂度

②优化方案:

1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.。

3.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。

4.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描。

5.in和 not in 也要慎用,否则会导致全表扫描。(很多时候用 exists 代替 in 是一个好的选择)

6.下面的查询也将导致全表扫描:select id from t where name like ‘%abc%’

7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。

8.Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。

9.对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。

10.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。

11.尽量避免大事务操作,提高系统并发能力。

12.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

13..如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

五.数据库遇到瓶颈问题:

可以采用四种方式:

1.缓存式的Web应用程序架构:

在Web层和db层之间加一层cache层,主要目的:减少数据库读取负担,提高数据读取速度。

2.实现MySQL数据库异步查询实现:

使用MySQL异步查询,因为需要给所有查询都创建一个新的连接,而MySQL服务端会为每个连接创建一个单独的线程进行处理,如果创建的线程过多,则会造成线程切换引起系统负载过高。Swoole中的异步MySQL其原理是通过MYSQLI_ASYNC模式查询,然后获取mysql连接的socket,加入到epoll事件循环中,当数据库返回结果时会回调指定函数,这个过程是完全异步非阻塞的。

3.MySQL主从读写分离:

MySQL读写分离提升系统性能:

1、主从只负责各自的读和写,极大程度缓解X锁和S锁争用。

2、slave可以配置MyISAM引擎,提升查询性能以及节约系统开销。

3、master直接写是并发的,slave通过主库发送来的binlog恢复数据是异步的。

4、slave可以单独设置一些参数来提升其读的性能。

5、增加冗余,提高可用性。

4.分表分库:

所谓的分表【水平拆分】

分库【垂直拆分】

分库分表的理由策略如下:

1、中间变量=user_id % ( 库数量 * 每个库的表数量 )

2、库=取整(中间变量 / 每个库的表数量)

3、表=中间变量 % 每个库的表数量

数据库经过业务拆分及分库分表,虽然查询性能和并发处理能力提高了。但是原本跨表的事务上升为分布式事务;由于记录被切分到不同的库和不同的表中,难以进行多表关联查询,并且不能不指定路由字段对数据进行查询。且分库分表后需要进一步对系统进行扩容(路由策略变更)将变得非常不方便,需要重新进行数据迁移。

 

 

 



2020 jeepxie.net webmaster#jeepxie.net
10 q. 0.009 s.
京ICP备10005923号