随着互联网的高速发展,带来了海量数据存储的问题,比如像物联网行业,每个智能终端每天进行数据采集和上报,每天能够产几千万甚至上亿的数据。在互联网电商行业,或者一些O2O平台,每天也能产生上千万的订单数据,这些量级的数据在传统的关系型数据库中已经无法支撑了,那么如何解决海量数据存储和计算等问题,在业内引入了分布式存储和分布式计算等解决方案,特别是NoSql的生态,我在前面讲过的k-v数据库、文档数据库、图形数据库等,都是比较主流的分布式数据库解决方案。
即便如此,关系型数据库仍然有它不可替代的特性,所以关系型数据库仍然是核心业务的基础数据平台,因此关系型数据库必然会面临数据量日益增长带来的海量数据处理问题。
Mysql数据库海量数据带来的性能问题
目前几乎所有的互联网公司都是采用mysql这个开源数据库,根据阿里巴巴的《Java开发手册》上提到的,当单表行数超过W行或者单表数据容量超过2G时,就会对查询性能产生较大影响,这个时候建议对表进行优化。
其实W数据只是一个折中的值,具体的数据量和数据库服务器配置以及mysql配置有关,因为Mysql为了提升性能,会把表的索引装载到内存,innodb_buffr_pool_siz足够的情况下,mysql能把全部数据加载进内存,查询不会有问题。
但是,当单表数据库到达某个量级的上限时,导致内存无法存储其索引,使得之后的SQL查询会产生磁盘IO,从而导致性能下降。当然,这个还有具体的表结构的设计有关,最终导致的问题都是内存限制,这里,增加硬件配置,可能会带来立竿见影的性能提升。
innodb_buffr_pool_siz包含数据缓存、索引缓存等。
Mysql常见的优化手段
当然,我们首先要进行的优化是基于Mysql本身的优化,常见的优化手段有:
增加索引,索引是直观也是最快速优化检索效率的方式。基于Sql语句的优化,比如最左匹配原则,用索引字段查询、降低sql语句的复杂度等表的合理设计,比如符合三范式、或者为了一定的效率破坏三范式设计等数据库参数优化,比如并发连接数、数据刷盘策略、调整缓存大小数据库服务器硬件升级mysql大家主从复制方案,实现读写分离
这些常见的优化手段,在数据量较小的情况下效果非常好,但是数据量到达一定瓶颈时,常规的优化手段已经解决不了实际问题,那怎么办呢?
大数据表优化方案
对于大数据表的优化最直观的方式就是减少单表数据量,所以常见的解决方案是:
分库分表,大表拆小表。
冷热数据分离,所谓的冷热数据,其实就是根据访问频次来划分的,访问频次较多的数据是热数据,访问频次少的数据是冷数据。冷热数据分离就是把这两类数据分离到不同的表中,从而减少热数据表的大小。
其实在很多地方大家都能看到类似的实现,比如去一些网站查询订单或者交易记录,默认只允许查询1到3个月,3个月之前的数据,基本上大家都很少关心,访问频次较少,所以可以把3个月之前的数据保存到冷库中。
历史数据归档,简单来说就是把时间比较久远的数据分离出来存档,保证实时库的数据的有效生命周期。
其实这些解决方案都是属于偏业务类的方案,并不完全是技术上的方案,所以在实施的时候,需要根据业务的特性来选择合适的方式。
详解分库分表
分库分表是非常常见针对单个数据表数据量过大的优化方式,它的核心思想是把一个大的数据表拆分成多个小的数据表,这个过程也叫(数据分片),它的本质其实有点类似于传统数据库中的分区表,比如mysql和oracl都支持分区表机制。
分库分表是一种水平扩展手段,每个分片上包含原来总的数据集的一个子集。这种分而治之的思想在技术中很常见,比如多CPU、分布式架构、分布式缓存等等,像前面我们讲disclustr集群时,slot槽的分配就是一种数据分片的思想。
如图6-1所示,数据库分库分表一般有两种实现方式:
水平拆分,基于表或字段划分,表结构不同,有单库的分表,也有多库的分库。垂直拆分,基于数据划分,表结构相同,数据不同,也有同库的水平切分和多库的切分。
文章配图图6-1
垂直拆分
垂直拆分有两种,一种是单库的垂直拆分,另一种是多个数据库的垂直拆分。
单库垂直分表
单个表的字段数量建议控制在20~50个之间,之所以建议做这个限制,是因为如果字段加上数据累计的长度超过一个阈值后,数据就不是存储在一个页上,就会产生分页的问题,而这个问题会导致查询性能下降。
所以如果当某些业务表的字段过多时,我们一般会拆去垂直拆分的方式,把一个表的字段拆分成多个表,如图6-2所示,把一个订单表垂直拆分成一个订单主表和一个订单明细表。
文章配图图6-2
在Innodb引擎中,单表字段最大限制为
参考: