数据是是一个企业的核心价值,现在每个企业都把数据视为公司核心机密。而数据库是存储数据的地方,在一个系统中的重要性更不言而喻。如何设计一个高性能的数据库系统,直接影响一个系统的存亡。目前常用的架构方案有主备、主从、读写分离、双主等,以及数据库扩容方案分库分表。今天讲一讲企业中常用的方案。
主备架构
主备架构是比较常见的架构方案,中有主库提供读写服务,备份库同步主库数据,当主库故障时系统自动切换至备份库。
优点:读写都操作主库,不存在数据一致性问题。架构相对简单运维成本比较低。
缺点:读写都在主库,很容易产生系统瓶颈。大部分情况下读多写少,读会先成为瓶颈,进而影响写性能。备库只是单纯的备份,资源利用率低。只能通过建立索引和增加缓存的方式提高性能。
主从架构
主从架构也是一种比较常用的架构,一般会一主多从,读写分离进行实现。写数据会在主库上进行操作,然后从库会同步主库数据。读数据只在从库上进行操作,分担了主库的压力。
优点:一般大型系统读多写少,读会成瓶颈,这样的架构分担了主库的压力。索引不用建在主库,可以建在只用于查询的从库上,这样可以提高写的效率。可以通过增加从库来提高读的性能。
缺点:存在单点故障,如果主库挂了,写操作无法进行。从库越多,需要从主库拉取日志的从库端就越多,进而影响主库的性能,并且数据同步完成的时间也会更长。
数据同步一致性问题由于从库拉取主库数据一般通过日志方式,即主库获取日志记录,然后同步到从库上执行。这个过程中可能存在延迟。假如一个用户刚写入一条数据,然后就开始刷新数据列表,这条数据有可能还未同步至从库,造成无法显示在用户端。有以下方案进行解决:
选择读主
首先在写数据的时候同时往缓存里写一份数据,比如根据库 表 业务特征生成一个key放到Cache里并设置超时时间(大于等于主从数据同步时间)。读请求时,同样的方式生成key先去查Cache,再判断是否命中。若命中,则读主库,否则读从库。代价是多了一次缓存读写,基本可以忽略。
同步复制
同步复制等主从同步完成,写请求才返回。这里利用数据库自带的功能,实现比较简单。代价是写请求时延增长,吞吐量降低。
强制读主
比如一些刚刚存储的数据,大概率还没有同步到从库的情况下,可以强制从主库读取。
分库分表方案数据库瓶颈
服务器都有IO和CPU的瓶颈,随着数据库的活跃连接数增加,数据库会达到活跃连接数的阈值。如果一个数据库的列比较多,请求也比较多,这样可以采用垂直分表方案,把数据分开放不同表,这样可以加快读速度。如果网络IO也比较大,就可以采取垂直分库技术,把数据存在在不同的数据库,以加快返回速度。单表数据量太大,查询时扫描的行太多,SQL效率低,CPU率先出现瓶颈,可以采用水平分表方式优化。
水平分库(表)
以字段为依据,按照一定策略(hash、range等),将一个库中的数据拆分到多个库(表)中。每个库或表的结构都是一样的,但是数据是不一致的,所有数据的并集就是全量数据。
如果库只有一张表数据量大性能太低,就考虑水平分表。假如库里的表字段相对比较少,数据量大且服务器运行达到极限,就要考虑水平分库。水平分库(表)主要解决单库(表)数据量太大的问题。
垂直分库(表)
以表为依据,按照业务归属不同,将不同的表字段拆分到不同的库中。每个库(表)结构都不一样,每个库(表)结构也不一样,所有库(表)数据的并集为全量数据。
表的记录并不多,但是字段多,并且热点数据和非热点数据在一起,单行数据所需的存储空间较大。以至于数据库缓存的数据行减少,查询时会去读磁盘数据产生大量的随机读IO,产生IO瓶颈。这个时候就需要垂直分表。随着业务的发展一些公用的配置表、字典表等越来越多,这时可以将这些表拆到单独的库。总之就是根据业务逻辑及运行情况,把数据进行拆分,减少单表字段很多的情况。
,