一,简介

高性能架构设计主要集中在两个方面:

  1. 尽量提升单服务的性能,将单服务的性能发挥到极致。
  2. 如果单服务无法支撑性能,则需设计服务集群方案。

高性能从系统角度角度可以分为:存储高性能和计算高性能

 

二,存储高性能

我们先看一下存储高性能,从关系型数据库,NoSql数据库,缓存三块来提高存储的性能。

1,关系型数据库可以通过读写分离和分库分表的方式提升存储性能。

2,如果因为关系型数据库本身的限制,无法满足业务需求,可以选择合适的NoSql类型数据库。

3,针对高并发的读操作时,可以考虑使用缓存的方案提升系统的性能。

 

三,关系型数据库

单台数据库服务器的性能优化就是硬件扩容和硬件升级,升级内存,升级硬盘,升级cpu,或者直接换小型机,大型机等。但这种方式的升级成本昂贵,而且性能的提升也容易达到瓶颈。随着互联网业务的发展,越来越多数据,单个数据库服务器已经难以满足业务需要,如果继续使用关系型数据库,就必须考虑数据库集群的方式来提升性能。

数据库集群的方案一般有两种:读写分离和分库分表。

 

四,读写分离

将数据库的读写操作分散到不同的节点上。

1,数据库服务器搭建主从集群,一主一从或一主多从。

2,数据库集群的主机负责读写操作,从机只负责读操作。

3,主机通过数据库自带的复制技术,将数据同步到从机,每台数据库服务器都存储所有的业务数据。

4,业务服务器将写操作发给数据库主机,将读操作发给数据库从机。

主从和主备的区别:备机仅仅提供备份功能,不提供访问功能,从机是可以提供读数据的功能。

 

五,分库分表

读写分离的方案,主要是针对业务逻辑上,读压力远大于写压力的时候。但对于那些写压力也很大业务,使用读写分离的方法提升的性能十分有限。

分库:

按照业务模块将数据分散到不同的数据库服务器。例如,一个简单的电商网站,包括用户,商品,订单三个业务模块,我们可以将用户数据,商品数据,订单数据分开放到三台不同的数据库服务器上。

分表:

单表数据拆分有两种方式:垂直分表和水平分表。

垂直分表适合将表中某些不常用且占了大量空间的列拆分出去。带来的问题就是,原来只需要查询一次的,现在需要查询两次。

水平分表适合表行数特别大的表,如果单表行数超过5000万行就必须进行分表,这个数字可以作为参考,但并不是绝对标准,关键还是要看表的访问性能。

 

六,NoSql

关系型数据库存在问题:

a,只能存储行记录,无法存储数据结构。

b,表结构schema的扩展不方便。

c,大数据量下的I/O会很高,只是针对某一列进行计算,也会读取整行数据

d,全文搜索比较弱,只能使用like进行整表扫描匹配,性能非常低。

常见的NoSQL方案:

1,K-V存储:解决关系数据库无法存储数据结构问题,以Redis为代表。

2,文档数据库:解决关系数据库强schema约束的问题,以MongoDB为代表。

3,列式数据库:解决关系数据库大数据场景下的I/O问题,以HBase为代表。

4,全文搜索引擎:解决关系数据库的全文搜索性能问题,以Elasticsearch为代表。

 

七,缓存

在某些复杂的业务场景下,单纯依靠存储系统的性能提升不够的:

1,需要经过复杂运算后得出的数据,存储系统无能为力。

2,读多写少的数据,存储系统有心无力。

缓存的基本原理就是将可能重复使用的数据放在内存中,一次生成,多次使用,避免每次使用都去访问存储系统。

缓存穿透:缓存没有发挥作用,业务系统需要再次去存储系统中查数据。

1,存储数据不存在,解决方法:如果查询存储系统的数据没有找到,则直接设置一个默认值并存储在缓存中,这样第二次读取缓存时就会获取默认值。

2,缓存数据生成耗费大量时间或资源,例如分页计算,缓存的页面数据,一般只缓存前几页。

缓存雪崩:指定缓存失效(过期)后引起系统性能急剧下降的情况。

对于一个高并发的业务系统来说,几百毫秒内可能接到几百上千请求。由于旧的缓存已经清除,新的缓存还未生成,并且处理这些请求的线程都不知道另外有一个线程正在生成缓存,因此所有的请求都会失去重新生成缓存,都会去访问存储系统,从而对存储系统造成很大的性能压力。

解决方案:(1)更新锁,对缓存更新操作进行加锁保护,保证只有一个线程能够进行缓存更新。(2)后台更新,由后台线程来更新缓存,而不是由业务线程来更新缓存。后台线程定时读取更新或者使用消息队列由业务线程通知。

缓存热点:对于一些特别热点的数据,如果大部分甚至所有的业务请求都命中同一份缓存数据,则这份数据所在的缓存服务器的压力也很大。例如:明星微博宣告一件事。

解决方案:就是复制多份缓存,将请求分散到多个缓存服务器上,减轻缓存热点导致的单台缓存服务器压力。

 

参照:《从零开始学架构》