高性能
2022-09-22 14:58:38 2 举报
AI智能生成
每个程序员都有一个成为架构师的梦想,高性能架构基本上是为了支撑大数据量和高并发的业务场景
作者其他创作
大纲/内容
数据库集群
读写分离
原理:将数据库读写操作分散到不同的节点上
实现方案
数据库服务器搭建主从集群
数据库主机负责读写操作,从机负责读操作
数据库主机通过复制将数据同步到从机,每台数据库服务器都存储了所有的业务数据
业务服务器将写操作发给数据库主机,将读操作发给从数据库主机
复杂度
主从复制延迟
带来的问题
如果业务服务器将数据写入到数据库主服务器后立刻进行读取,此时读操作访问的是从机,主机还没有把数据同步到从机,导致读取的数据是旧数据,业务上就可能出现问题
解决方案
写操作后的读操作指定发给数据库主服务器
读从机失败后再读一次主机
关键业务读写操作全部指向主机,非关键业务采用读写分离
分配机制
程序代码封装
实现简单,可以根据业务做较多定制化的功能
每个编程语言都需要实现一次,无法通用
故障情况下,如果主从发生切换,则可能需要所有系统都修改配置并重启
中间件封装
支持多种编程语言
数据库中间件要支持完整的SQL语法和数据库服务器的协议,实现比较复杂,细节特别多
目前开源的数据库中间件
MyCat:社区维护,基于阿里Cobar二次开发,Java语言开发
Gaea:小米开源,Go语言开发
MySQL Router:MySQL官方推出
Atlas:360团队基于mysql proxy 把lua用C改写
Kingshard:金山软件开源,Go语言开发
ShardingSphere
待解决的问题:因读写分离分散了数据库读写操作的压力,并没有分散存储压力
数据量太大,读写的性能会下降,即使有索引,索引也会变得很大,性能同样会下降
数据文件会变得很大,数据库备份和恢复需要耗费很长时间
分库分表
分库
业务分库指的是按照业务模块将数据分散到不同的数据库服务器
虽然业务分库能够分散存储和访问压力,同时带来了新的问题
join问题
业务分库后,原本在用一个数据库中表分散到不同数据库中,导致无法使用SQL的join查询
事务问题
原本在同一个数据库中不同表可以在同一个事务中修改,业务分库后,表分散到不同的数据库中,无法通过事务统一修改
成本问题
业务分库同时也带来了成本的增加
分表
将不同业务数据分散存储到不同的数据库服务器,能够支撑百万甚至千万用户规模的业务,但如果业务继续发展,同一业务的单表数据也会达到单台数据库服务器的处理瓶颈。
垂直分表
垂直切分,就是表记录数相同但包含不同的列
垂直分表适合将表中某些不常用且占了大量空间的列拆分出去
垂直分表引入的复杂性主要体现在表操作的数量要增加
水平分表
水平切分,就是表的列相同但包含不同的行数据
复杂度
路由
范围路由
Hash路由
配置路由
join操作
count 操作
order by 操作
实现方法
程序代码封装
中间件封装
关于读写分离,分库分表的决策
做硬件优化,例如从机械硬盘改成使用固态硬盘,当然固态硬盘不适合服务器使用,只是举个例子
先做数据库服务器的调优操作,例如增加索引,MySQL有很多的参数调整
引入缓存技术,例如Redis,减少数据库压力
程序与数据库表优化,重构,例如根据业务逻辑对程序逻辑做优化,减少不必要的查询
在这些操作都不能大幅度优化性能的情况下,不能满足将来的发展,再考虑分库分表,也要有预估性
NoSql
关系型数据库的缺点
关系数据库存储的是行记录,无法存储数据结构
关系数据库的schema扩展很不方便
关系数据库在大数据场景下I/O较高
关系数据库的全文搜索功能比较弱
常见的NoSql方案
K-V存储
解决关系数据库无法存储数据结构的问题,以Redis为代表
文档数据库
解决关系数据库强schema约束的问题,以MongoDB为代表
文档数据库的no-schema特性,给业务开发带来了几个明显的优势
新增字段简单
历史数据不会出错
可以很容易存储复杂数据
缺点
不支持事务
无法实现关系数据库的join操作
列式数据库
解决关系数据库大数据场景下的I/O问题,以HBase为代表
一般将列式存储应用在离线的大数据分析和统计场景中,因为这种场景主要是针对部分列单列进行操作,且数据写入后就无须再更新删除。
优势
业务同时读取多个列时效率高,因为这些列都是按行存储在一起的,一次磁盘操作就能够把一行数据中的各个列都读取到内存中。
能够一次性完成对一行中的多个列的写操作,保证了针对行数据写操作的原子性和一致性;否则如果采用列存储,可能会出现某次写操作,有的列成功了,有的列失败了,导致数据不一致。
典型的场景就是海量数据进行统计
除了节省I/O,列式存储还具备更高的存储压缩比,能够节省更多的存储空间。
劣势
典型的场景是需要频繁地更新多个列
列式存储高压缩率在更新场景下也会成为劣势,因为更新时需要将存储数据解压后更新,然后再压缩,最后写入磁盘。
全文搜索引擎
解决关系数据库的全文搜索性能问题,以Elasticsearch为代表
全文搜索引擎的技术原理被称为“倒排索引”(Inverted index),也常被称为反向索引,是一种索引方法,其基本原理是建立单词到文档的索引。 之所以被称为“倒排”索引,是和“正排“索引相对的,“正排索引”的基本原理是建立文档到单词的索引。
缓存
虽然我们可以通过各种手段来提升存储系统的性能,但在某些复杂的业务场景下,单纯依靠存储系统的性能提升不够的,典型的场景有
需要经过复杂运算后得出的数据,存储系统无能为力
读多写少的数据,存储系统有心无力
引入缓存后带来的复杂性
缓存穿透
缓存穿透是指缓存没有发挥作用,业务系统虽然去缓存查询数据,但缓存中没有数据,业务系统需要再次去存储系统查询数据
通常情况下有下列情况会造成缓存穿透
被访问的数据确实不存在
缓存数据生成耗费大量时间或者资源
缓存雪崩
缓存雪崩是指当缓存失效(过期)后引起系统性能急剧下降的情况
缓存雪崩的常见解决方法
更新锁机制
后台更新机制
双Key策略
缓存热点
虽然缓存系统本身的性能比较高,但对于一些特别热点的数据,如果大部分甚至所有的业务请求都命中同一份缓存数据,则这份数据所在的缓存服务器的压力也很大
缓存热点的解决方案
复制多份缓存副本,将请求分散到多个缓存服务器上,减轻缓存热点导致的单台缓存服务器压力。
负载均衡
DNS负载均衡
一般用来实现地理级别的均衡
DNS负载均衡的本质是DNS解析同一个域名可以返回不同的IP地址
优点
简单、成本低
负载均衡工作交由DNS服务器处理,无须自己开发或维护
就近访问,提升访问速度
DNS解析时可以根据请求来源IP解析成距离用户最近的服务器地址,可以加快访问速度,改善性能
缺点
更新不及时
DNS缓存的时间比较长,修改DNS配置后,由于缓存的原因
扩展性差
DNS负载均衡的控制权在域名商那里,无法根据业务特点针对其做更多的定制化功能和扩展性
分配策略比较简单
DNS负载均衡支持的算法少,不能区分服务器的差异;也无法感知后端服务器的状态
硬件负载均衡
F5、A10
优点
功能强大
全面支持各层级的负载均衡,支持全面的负载均衡算法,支持全局负载均衡
性能强大
硬件负载均衡可支持100万以上的并发
稳定性高
商用硬件负载均衡,经过了良好的严格测试,经过大规模使用,稳定性高
支持安全防护
硬件均衡设备除具备负载均衡功能外,还具备防火墙、防DDoS攻击等安全功能
缺点
价格昂贵
扩展能力差
软件负载均衡
Nginx
7层负载均衡协议
一般的Linux服务器的Nginx大概能到5万/秒
LVS
4层负载均衡
可达到80万/秒
优点
简单
便宜
灵活
缺点
性能一般
功能没有硬件负载均衡那么强大
一般不具备防火墙和防DDoS攻击等安全功能
单服务器高性能
PPC与TPC
高性能架构设计主要集中在两方面
尽量提升单服务器的性能,将单服务器的性能发挥到极致
如果单服务器无法支撑性能,设计服务器集群方案
单服务器高性能的关键之一就是服务器采取的并发模型
服务器如何管理连接
服务器如何处理请求
操作系统的I/O模型及进程模型
I/O模型:阻塞、非阻塞、同步、异步
进程模型:单进程、多进程、多线程
PPC
定义:是指每次有新的连接就新建一个进程去专门处理这个连接的请求,这是传统的UNIX网络服务器所采用的模型
TPC
定义:是指每次有新的连接就新建一个线程去专门处理这个连接的请求
与进程相比,线程更轻量级,创建线程的消耗比进程要少得多;同时多线程是共享进程内存空间的,线程通信相比进程通信更简单。
TPC实际上是解决或者弱化了PPC fork代价高的问题和父子进程通信复杂的问题。
优点:实现简单
缺点:无法支撑高并发的场景
Reactor与Proactor
Reactor
I/O多路复用结合线程池,完美地解决了PPC和TPC的问题,前辈们给它取了一个很牛的名字:Reactor,中文是“反应堆”,是“事件反应”的意思
Reactor模式的核心组成部分包括Reactor和处理资源池(进程池或线程池),其中 Reactor负责监听和分配事件,处理资源池 负责处理事件
0 条评论
下一页