MENU

高性能&高可靠

2024 年 10 月 25 日 • 访问: 367 次 • 系统架构设计

高性能

高性能是指系统能够在有限的资源下,以较快的速度响应用户的请求。高性能的实现需要考虑到系统的架构设计、算法优化、资源利用等方面。

负载均衡(Load Balance)

参考资料
负载均衡原理及算法详解
什么是一致性哈希?

Q: 什么是负载均衡?

A:负载均衡指的是将用户请求分摊到不同的服务器上处理,以提高系统整体的并发处理能力以及可靠性。负载均衡服务可以有由专门的软件或者硬件来完成

Q:常见的负载均衡算法有哪些?你对一致性哈希算法有了解吗?

A:

  • 随机法:简单暴力,大家的权重都一样,通过随机算法到一台服务器上
  • 普通轮询法和加权轮询:普通轮询,依次对将请求分配到每个服务器上,而加权轮询则是对硬件配置较高的节点设置更高的权重,让其承担更多的请求
  • 普通哈希:将请求的参数信息通过哈希函数转换成一个哈希值,然后根据哈希值来决定请求被哪一台服务器处理。
  • 一致性哈希:常规哈希法在服务器数量变化时,哈希值会重新落在不同的服务器上,这明显违背了使用哈希法的本意。而一致性哈希法的核心思想是将数据和节点都映射到一个哈希环上(均使用2^32进行取模运算),然后根据哈希值的顺序来确定数据属于哪个节点。当服务器增加或删除时,只影响该服务器的哈希,而不会导致整个服务集群的哈希键值重新分布。

数据库

图解MySQL介绍

Q: 在实际工作中就有没有遇到过慢SQL的情况,你是如何对SQL进行调优的,分享一下你的经历?

A:使用SQL Explain语句分析慢SQL,分析SQL执行计划对SQL进行调优。

我曾经遇到过这样一个问题。现在我们有三张表hostold_agentnew_agent,我们需要合并old_agentnew_agent这两张表,然后与host表做一个左连接,我们很容易想到如下的SQL实现,并且我们很聪明给agent_id、agent_uuid和instance_id字段都加了索引,但是结果发现SQL运行很慢。

select agent_id, agent_version, agent_status, agent_type from host
left join (
    select agent_uuid as agent_id, agent_version, agent_status, agent_type from old_agent
    union
    select agent_id, agent_version, agent_status, agent_type from new_agent
) as agent
on agent.agent_id = host.agent_uuid or agent.agent_id = host.instance_id

使用Explain语句分析之后发现,由于old_agentnew_agent两张表union之后的agent表是一张临时表,所以导致了索引失效,在left join的时候走了全表扫描,所以导致查询速度很慢。解决方法就是讲left join内移到语句内部,old_agentnew_agent各自进行left join操作之后,再进行union操作,这样可以保证left join的时候索引不会失效。

优化后的语句是这样子的

select agent_id, agent_version, agent_status, agent_type from (
    select agent_id, agent_version, agent_status, agent_type from host 
    left join new_agent on new_agent.agent_id = host.instance_id
    union 
    select agent_uuid as agent_id, agent_version, agent_status, agent_type from host 
    left join old_agent on old_agent.agent_uuid = host.agent_uuid
) as union_table

Q: 你知道哪些SQL索引失效的场景?

A: 网上的参考资料中包含的索引失效的场景应该没有包含全部的场景,具体还是需要经验的积累

参考资料:
15个必知的Mysql索引失效场景,别再踩坑了

  1. 涉及到临时表的创建(我自己遇到的例子),特别注意子查询的场景
  2. 联合索引不满足最左匹配原则
  3. 使用了select *
  4. 索引列参与运算
  5. 索引列参使用了函数
  6. 错误的Like使用
  7. 类型隐式转换
  8. 使用OR操作:在使用or关键字时,切记两个条件都要添加索引,否则会导致索引失效
  9. 两列做比较:两列数据做比较,即便两列都创建了索引,索引也会失效
  10. 不等于比较:查询条件使用不等进行比较时,需要慎重,普通索引会查询结果集占比较大时索引会失效
  11. is not null:查询条件使用is null时正常走索引,使用is not null时,不走索引
  12. not in和not exists:查询条件使用not in时,如果是主键则走索引,如果是普通索引,则索引失效
  13. order by导致索引失效:当查询条件涉及到order by、limit等条件时,是否走索引情况比较复杂,而且与Mysql版本有关,通常普通索引,如果未使用limit,则不会走索引。order by多个索引字段时,可能不会走索引。其他情况,建议在使用时进行expain验证
  14. 参数不同导致索引失效

Q: 关系型数据库MySQL底层的索引是用什么数据结构实现的?为什么使用这种数据结构呢?

小林Coding索引相关知识点整理

A: 使用了B+树的数据结构

为什么 MySQL InnoDB 选择 B+tree 作为索引的数据结构?B+Tree 相比于 B 树、二叉树或 Hash 索引结构的优势在哪儿?

  1. B+Tree vs B Tree: B+Tree 只在叶子节点存储数据,而 B 树 的非叶子节点也要存储数据,所以 B+Tree 的单个节点的数据量更小(B+树的树形结构更加矮胖,层数更少,但是宽度更宽),在相同的磁盘 I/O 次数下,就能查询更多的节点。另外,B+Tree 叶子节点采用的是双链表连接,适合 MySQL 中常见的基于范围的顺序查找,而 B 树无法做到这一点。
  2. B+Tree vs 二叉树: 对于有 N 个叶子节点的 B+Tree,其搜索复杂度为O(logdN),其中 d 表示节点允许的最大子节点个数为 d 个。在实际的应用当中, d 值是大于100的,这样就保证了,即使数据达到千万级别时,B+Tree 的高度依然维持在 3~4 层左右,也就是说一次数据查询操作只需要做 3~4 次的磁盘 I/O 操作就能查询到目标数据。而二叉树的每个父节点的儿子节点个数只能是 2 个,意味着其搜索复杂度为 O(logN),这已经比 B+Tree 高出不少,因此二叉树检索到目标数据所经历的磁盘 I/O 次数要更多。
  3. B+Tree vs Hash: Hash 在做等值查询的时候效率贼快,搜索复杂度为 O(1)。但是 Hash 表不适合做范围查询,它更适合做等值的查询,这也是 B+Tree 索引要比 Hash 表索引有着更广泛的适用场景的原因。

Q: 数据库的事务是什么,能简单描述一下吗?

A: 默认是单条SQL作为单个事务提交执行,但我们可以通过注解@Transaction或者setAutoCommit(false)来配置多条SQL的执行作为一个完整的事务,比如说多人之间的转钱对应多条SQL,只有每一条SQL都执行成功,才算是一个完整的事务执行成功,如果中间存在某条SQL执行失败则进行回滚。

高可靠

产品能在生命周期内长期保障业务无故障运行,具备快速恢复和自我管理的能力,提供可预期的、一致的服务。

最后编辑于: 2024 年 10 月 28 日
返回文章列表 打赏
本页链接的二维码
打赏二维码
添加新评论