1.7 企业架构演进
1.单机mysql的90年代:网站访问量不会太大,单个数据库足够使用。此时网站大多使用静态网页Html,动态交互类型的网站很少。所以服务器没有太大的压力。这时候的产品如早期淘宝 (PHP)、hao123等。随着时代的发展:这种网站的瓶颈就出现了
-
一个是海量数据量,单机是无法存储的。而且在单表的数据超过300万就一定要建立索引的前提下,索引(b+tree)也不能建太多,一台机器的内存撑不住
-
写时锁表,会影响读,访问量过大,读写(读写混合)的压力达到单台数据库极限,使用多台来分摊压力
-
在做产品时根据实际情况从单机开始,之后若出现上面的2中情况后在考虑使用分布式。
-
产品结构:app—>DAL(数据库访问层)—>mysql(单个不同品牌数据库)
早期是一种数据库对应一套数据库语言,后面推出jdbc简化开发人员的对数据库的统一 操作(多驱动操作不同数据库),提供一个(java操作数据库)规范,实现了差异化
之后对jdbc进行分装简化出来的一些框架:mybatis、Hibernate( ORM 框架) 让繁琐的数据库操作变得更加简洁,也让开发者无需花费过多的精力在 SQL 的编写和优化上
2.Memcached(缓存)+MySQL+垂直拆分(业务)
-
后来,随着访问量的上升,几乎大部分使用MySQL架构的网站在数据库上都开始出现了性能问题,web程序再也不仅仅专一在功能上,同时也在追求性能。程序员们开始大量的使用缓存技术来缓解数据库的压力,优化数据库的结构和索引。开始比较流行的是经过文件缓存来缓解数据库压力,可是当访问量继续增大的时候,多台web机器经过文件缓存不能共享,大量的小文件缓存也带了了比较高的IO压力。在这个时候,Memcached就天然的成为一个很是时尚的技术产品
-
Memcached做为一个独立的分布式的缓存服务器,为多个web服务器提供了一个共享的高性能缓存服务,在Memcached服务器上,又发展了根据hash算法来进行多台Memcached缓存服务的扩展,而后又出现了一致性hash来解决增长或减小缓存服务器致使重新hash带来的大量缓存失效的弊端
3.MySQL主从读写分离
-
当数据量很大时,数据库服务器的压力就会增大,性能就会受到挑战。在一个应用中,根据二八原则,百分之二十的操作是写操作,百分之八十的操作是读操作。Memcached只能缓解数据库的读取压力。读写集中在一个数据库上让数据库不堪重负,大部分网站开始使用主从复制技术来达到读写分离,以提升读写性能和读库的可扩展性。Mysql的master-slave模式成为这个时候的网站标配了
-
数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。当数据库的写入,影响了查询的效率时。利用数据库主从同步即数据库将事务性操作导致的变更同步到集群中的从数据库,再通过读写分离可以提升数据库的并发负载能力,提高性能,满足实际生产中对安全性、高可用性、高并发等方面的要求。
-
读写分离的思想是,在执行SQL语句的时候,判断到底是读操作还是写操作,把读操作转向读操作服务器(从服务器,一般是多台);写的操作转到写服务器上(主服务器,一般是一台)。为了保证多台数据库的一致性,需要主从复制。
-
主从复制的实现原理:mysql有bin日志(二进制日志),会记录下所有修改过数据库的sql语句。主从复制的原理就是多台服务器都开启bin日志,然后主服务器会把执行过的sql语句记录到bin日志中,“从服务器”读取这个bin日志,把该日志内容保存到自己的中继日志中,“从服务器”再把中继中记录的sql语句执行一遍。这样就保证了主从服务器的数据一致了。主从复制的实现原理
-
从数据库读取数据,而数据库是存在硬盘上的,存在IO瓶颈,效率低下,所以要减轻数据的压力,就要使用缓存来保证效率。为保证数据一致前期采用缓存,
-
1.在项目代码中(DAO、JDBC、Datasource这几层中都可以实现)使用多数据源,指定当前请求线程使用的数据库进行读写分离.(缺点:当某台数据库宕机,无法检查)
2.使用mycat中间件配置读写分离或者是Sharding-JDBC,优于第一种方式。参见:mycat种间件
- 发展过程:优化产品本身的数据结构和索引(困难)->文件缓存(IO、hdfs)->Memcached(高速缓存插件)
4.分库分表—水平拆封—数据集群
- 数据库方面可以配置读写分离,把读操作和写操作分离出来,最大程度的利用好数据库服务器。单表装不下数据后对数据库进行水平拆分,准备多台数据库中一台负责写内容,然后同步给其他数据库。
- 在Memcached的高速缓存,MySQL的主从复制,读写分离的基础之上,这时MySQL主库的写压力开始出现瓶颈,而数据量的持续猛增,因为MyISAM使用表锁,在高并发下会出现严重的锁问题,大量的高并发MySQL应用开始使用InnoDB引擎代替MyISAM
- 同时,开始流行使用分表分库来缓解写压力和数据增加的扩展问题。这个时候,分表分库成了一个热门技术,是面试的热门问题也是业界讨论的热门技术问题。也就在这个时候,MySQL推出了还不太稳定的表分区,这也给技术实力平常的公司带来压力。虽然MySQL推出了MySQL Cluster集群,但性能也不能很好满足互联网的要求,只是在高可靠性上提供了很大的保证
一般一个集群最少6个节点才能保证基本工作,数据是分片存储,不同节点存储一部分数据,数据在节点内部是一致,所有节点数据汇总后才是整个应用的数据。
- 分库分表的方式有四种,它们分别是:垂直分表、垂直分库、水平分库和水平分表。
垂直分表:可以把一个宽表的字段按照访问频率、是否是大字段的原则拆分为多个表,这样既能使业务清晰,还能提高部分性能。拆分后,尽量从业务角度避免联查,否则性能方面将得不偿失。
垂直分库:可以把多个表按照业务的耦合性来进行分类,分别存放在不同的数据库中,这些库可以分布在不同的服务器,从而使访问压力被分摊在多个服务器,大大提高性能,同时能提高整体架构的业务清晰度,不同的业务库可根据自身情况定制优化方案。但是它需要解决跨库带来的所有复杂问题。
水平分库:可以把一个表的数据(按数据行)分到多个不同的库,每个库只有这个表的部分数据,这些库可以分布在不同的服务器,从而使访问压力被多服务器负载,提升性能。它不仅需要解决跨库带来的问题,还需要解决数据路由的问题。
水平分表:可以把一个表的数据(按数据行)分到多个同一个数据库的多张表中,每个表的数据只有这个表的部分数据,这样做能小幅提升性能,它仅仅作为水平分库的一个补充优化。
-
最后,一般来说,在系统设计阶段就应该根据业务耦合程度来确定用哪种分库分表的方式(方案),在数据量及访问压力不是特别大的情况,首先考虑缓存、读写分离、索引技术等方案。若数据量极大,且连续增长,再考虑分库分表的方案。
-
整个应用变得庞大起来,后端数据处理趋于稳定。归根到底是解决数据库的读、写问题,缓存解决了读的问题,读写分离、分库分表解决了写的问题。
mysql数据库两种引擎:
myisam:表锁,不支持事务,可以压缩。表锁导致表操作效率低下。高并发时问题严重。MYISAM的索引分离,一个文件存储数据结构,一个存储内容
innoDB:行锁+表锁。条件innoDB更新语句如果不走索引会变成表锁,索引失效会导致行锁变成表锁
mysql在读写分离、分库分表技术出现之前推出表分区功能和MySQL Cluster集群,之前比较常用。
5.MySQL的扩展性瓶颈
- MySQL数据库也常常存储一些大文本字段,致使数据库表很是的大,在作数据库恢复的时候就致使很是的慢,不容易快速恢复数据库。好比1000万4KB大小的文本就接近40GB的大小,若是能把这些数据从MySQL省去,MySQL将变得很是的小。关系数据库很强大,可是它并不能很好的应付全部的应用场景。MySQL的扩展性差(须要复杂的技术来实现),大数据下IO压力大,表结构更改困难,正是当前使用MySQL的开发人员面临的问题
- 当前时代,传统的关系型数据库无法处理海量的、各种类型的、变化的数据。如定位,热点、热榜、图片、用户的个人信息,社交网络、用户自己产生的数据,用户日志等爆发式增长的数据,还有大并发IO的情况下变化的热点数据不是持久化到数据库中,否则对数据库的读写压力太大了。这样就需求nosql数据库来处理,如可以存储图片的InfoGrid数据库、存储文件的MongoDB数据库来减轻mysql的压力。
灰度发布,金丝雀发布这种要求平滑发布,所以在构建表时要考虑很多:如对1亿条数据的表加一列。
- 当前互联网项目结构:
1.9 分布式&集群简介
- 分布式(Distributed System):由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。分布式系统是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。因此,网络和分布式系统之间的区别更多在于高层软件(特别是操作系统),而不是硬件。分布式系统可以应用在不同的平台上如:PC,工作站,局域网、广域网等。
- 分布式:多台服务器上面部署不同的服务模块,他们之间通过RPC/RMI之间通信和调用,对外提供服务和组内协作。
- 集群:不同的多台服务器上面部署相同的服务模块,通过分布式调度软件进行统一的调度,对外提供服务和访问。