高性能架构
上一篇文章初识架构让我们对架构设计的复杂度考虑有了一定了解,主要有个高可用、高性能、可扩展。但仅仅知道是不够用的,接下来,将从高性能来进行详细分享
1. 高性能数据库
从数据库分享高性能,主要是两个方面分别是:
1.1 读写分离
读写分离的主要原理是将读和写分散到不同的节点上
1.1.1 实现方式
数据库搭建主从模式,一主多从或一主一从。主服务器负责写, 从服务器负责读。从服务器通过复制的方式从主服务器同步数据。
在业务域实现分别有两种方式:
从代码层面实现。主要是代码封装,通过将读写请求分离出,请求不同的数据源
从中间件层实现。如:MysqlProxy 等
1.1.2 带来的问题
读写分离将业务读写的压力分开,但是也带来了一些其他问题,如:
主从复制可能有延时,主从数据间数据不一致问题
将数据的读压力分散开,但是并没有减少数据库的写压力
为了区分度读写操作,需要引入中间件或对代码进行改造
1.2 分库分表
通常在数据表有压力的时候,我们会采取分库分表的策略,将数据分在不同的数据区域,减少数据存储压力。
1.2.1 分库
业务分库:按照业务模块将不同的数据存储到不同的数据库服务器
2.1.1 带来的 d 问题
事务问题: 多库间操作无法在一个事务内完成
成本问题:分库带来服务器数量增加,从而增加成本
数据查询带来复杂问题: 多库不利于 join()操作
1.2.2 分表
分表:单表存储数据过大时,需要对数据进行分表存储,放在不同的表中。分表又分为两种,分别是:垂直分表、水平分表。
垂直分表:把不常用的字段分出去。分表方式如:备注,内容等大字段
水平分表:对单表数据较大的进行分表。分表方式如: ID, 年月
1.2.2.1 分表策略
分表需要把数据分配到不同的表中,这就涉及到了表数据的分配算法。主要的分配算法有:
范围路由:如根据 ID,1~999999,1000000~9999999
Hash 路由:可以根据某些字段,进化 hash 计算,如 hash%表数。
配置路由:新建一张表,配置路由键与表之间的关系。如 log_id,table_num 两列。
1.2.2.2 带来的问题
数据表聚合操作标的麻烦,如:group by,count 等
合适的数据路由策略选择,防止数据不均匀
1.3 优化策略
通常,我们在数据库出现瓶颈压力的时候可能优先考虑的是上述方案,这样其实是不对的。对于数据库方面的优化策略主要是:1、从硬件方面优化。2、SQL 优化。3、增加缓存。4、分库分表。这样优化的如要目的主要是减少代码的改动量,保证业务的稳定性。
2. 高性能 NoSQL
在某些情况下,我们需要根据具体情况选择合适的 NoSQL,具体有如下 NoSQL。
2.1 Key-Value 形式
key-value 形式的 NoSQL 主要解决关系型数据库无法存储数据结构的问题。以 Redis 为代表。
2.2 文档数据库
文档数据库主要解决关系型数据库强 Schema 问题。以 MongoDB 为代表。
2.2.1 优点 & 缺点
优点:1、新增字段简单。 2、对历史数据不会造成影响。 3、容易存储复杂结构数据,如 JSON。
缺点:1、不支持 ACID
2.3 列式数据库
列式数据库主要解决大数据场景下 I/O 问题。以 HBase,clickhouse 为代表
2.3.1 优点 & 缺点
优点:1、数据读取量小,如一行是 4K, 某列可能只有 4Byte,可以减少 I/O。 2、同一列数据高度相似,可以提高压缩比例,易于存储。
缺点:1、对多列数据进行修改,查询多列由于是随机 I/O,相对与行顺序 I/O,性能较差。
2.4 全文搜索引擎
全文搜索引擎主要解决关系型数据库全文搜索性能问题。以 ES 为代表。
1 & 2 小结
关于数据库选择方式,我们需要以需求为导向。根据合适的业务场景选择合适的数据库。主要的考量指标有:数据量、并发量、一致性要求、读写分布、安全、运维等。
3. 高性能缓存架构
在应对一些又计算后得出的数据,或者读多写少的场景,一般存储系统无法应对,我们需要引入缓存。如:Redis,MemCache。接下来主要说一下系统引入缓存架构带来的问题。
3.1 缓存穿透
缓存穿透主要是数据的查询直接落在数据库上导致。造成缓存穿透的主要原因有两点,分别是:
查询数据不存在。
查询数据刚好失效,生成缓存时间较长。
解决策略:
缓存空数据
使用布隆过滤器
3.2 缓存雪崩
缓存雪崩主要是缓存失效,引起系统性能急剧下降。造成雪崩的主要原因是:
新缓存生成耗费时间,多线程同时更新缓存,造成 DB 压力,从而拖动系统西能。
解决策略:
更新锁机制:对缓存的更新进行加锁操作。
后台更新机制: 缓存长久有效,通过后台手动更新或缓存失效,触发后台更新等。
3.3 缓存热点
缓存热点主要是同一时间访问量急剧增大导致,如微博上"爆"点。
解决策略:
多级缓存:通过实时分析,将预热数据存入本地缓存中,然后才是缓存系统
将热点数据进行多副本保存:如 key_1, key_2, key..n 等,分散查询。
4. 单机高性能
增加单机高性能,则可以通过增加进程或线程的方式,我们一般通过增加线程的方式。主要的方式有两种:分别是:
IO 多路复用, Reactor
AIO
5. 高性能负载均衡
通常,负载均衡也是高性能的一块,一个合适的负载均衡,对系统的提升也非常明显。从大往小了说,主要分为三类,分别是:DNS 负载,硬件负载,软件负载。接下来将一一介绍。
5.1 DNS 负载均衡
DNS 负载均衡主要是有 DNS 厂商提供的一种负载均衡算法,其主要逻辑是:通过解析域名,可以返回不同的 IP 地址。如:解析 www.jd.com,上海用户通过 DNS 解析出来的地址可能是:10.23.12.1; 黑龙江用户解析出来的是:60.111.23.55;这样通过不同的 IP,访问就近的地址,加速用户的访问。
5.1.1 优点 & 缺点
DNS 负载的优点主要有:1、直接又 DNS 厂商提供,操作简单,成本低。2、用户访问就近区域,加速用户访问速度。
缺点也比较明细:1、IP 缓存时间长,用户可能更新不及时。
5.2 硬件负载均衡
硬件负载均衡主要是通过硬件层面来进行负载均衡,和交换机,路由器类似。主要代表有 F5,A10。
5.2.1 优点 & 缺点
优点:1、性能强劲,可以支持百万级并发量。 2、支持在网络各层级进行负载,支持多种负载算法。3、支持安全防火。如:DDOS
缺点:1、价格昂贵,一般公司承受不起。2、可以根据业务配置,但是无法进行扩展和定制
5.3 软件负载均衡
软件负载均衡主要是通过软件来进行负载均衡,主要代表有 Nginx(7 层)、LVS(4 层)等。同硬件想比,软件则无法支持那么大的并发量。但也有自己的优点。
5.3.1 优点 & 缺点
优点:1、部署运维简单,都提供部署方法。2、便宜,多加机器就可以部署。3、灵活,可以在网络 7 层或 4 层进行配置,支持扩展。
缺点:1、没有硬件负载那么大并发,如 Nginx 并发:5W/s。2、不支持网络安全防护,如 DDOS 攻击。
5.4 负载均衡算法分类
讲完了负载均衡,那接下来就讲解一下负载均衡算法的分类,主要也分为四大类,分别是:任务平分类、负载均衡类、Hash 算法、性能最优类。接下来一一分析一下。
5.4.1 任务评分类
任务平分类主要是将任务平均分配,实现比较简单,无状态,和机器无关。如:轮询
5.4.2 负载均衡类
这里的负载均衡不是我们理解的负载均衡,而是通过计算出机器的性能,使用情况,如:CPU,IO,网卡连接数等,然后在分配任务。对机器性能做出平衡。防止差的机器接收大量的任务。如:加权轮询,负载最低优先
5.4.3 Hash 类
负载均衡根据任务中的某些信息,进行 hash 计算,将相同 hash 值的任务放在同一个服务器上。这样可以满足某些特定业务需求。如:根据机器 Ip 进行 hash 计算,或者根据 id 进行 hash 计算。
5.4.4 性能最优类
性能最优类和负载均衡类有所不同,性能最优类是站在客户端的角度来看,谁处理任务快,就把任务多分配一些。负载均衡类是站在服务器端的角度来看。
6 总结
以上是总结的关于高性能架构设计时,我们可以考虑的点。在考虑设计时,我们不必拘泥于选择其中一点,而是进行搭配使用。为了满足业务需求,进行最大程度选择组合,这样才可以设计出符合业务的高性能架构。
版权声明: 本文为 InfoQ 作者【编号94530】的原创文章。
原文链接:【http://xie.infoq.cn/article/32dc9605475f12c2e7355310f】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论