在互联网应用中,数据爆发式的增长,实际上软件架构的本质就是对数据的维护。对数据的操作可以归纳为三类:读、写和检索。
随着网站的流量越来越大,数据量也爆发式的增长,网站响应越来越慢,服务器经常宕机。传统的关系型数据库已经不能满足流量和数据的爆发式增长。于是根据不同的业务需求,出现了很多不同的数据库。
根据数据库的类型划分。有关系型数据库:mysql,oracle,sqlserver,postgresql等。nosql数据库:mongodb,hbase,cassandra,redis,CouchDB,Riak,Membase等。
根据数据库的用途划分。有缓存数据库:redis,memcached,h2db等,日志数据库:kahadb等。k-v型数据库:leveldb,redis等。
检索型存储中间件有:elasticsearch、solr、Lucene等。
传统的关系型数据库(RDBMS)是用途最广泛也是用的最多的数据库。关系型数据库是强事物一致性(ACID),使用比较早,技术相对成熟,查询可以根据字段,以及表现各个数据对象之间的关系。在CAP理论中实现的是CA。没有P分区性,单点瓶颈是硬伤。
当关系型数据库越来越成为瓶颈时,为解决单点瓶颈牺牲CAP属性中的C,出现了nosql数据库。针对某些特殊的使用场景,出现了非关系型数据库。如:nosql,缓存等。以下针对不同的业务场景阐述各个数据库的特性。
对于数据库的选型,ACID(原子性Atomicity、一致性 Consistency、隔离性 Isolation、持久性Durability)是重要的考虑指标,如果对ACID要求很高,应该选择关系型数据库。其次部分对一致性要求不高的,写并发非常大的可以考虑其他的nosql数据库。但是有的业务并发非常高,对ACID要求也非常高,则对业务数据和数据库进行拆分。
以下对各种业务场景应该如何优化和存储选型。
一、读多写少
在互联网应用中,对于一般的量级,免费的关系型数据库mysql、postgresql是首选。支持事物,稳定性和成熟度比较好。
当访问量越来越大,数据量还不是很大的时候。也就是写不是瓶颈,而读成为主要的瓶颈。一是增加从库分担读的压力,另一个是在数据库和应用系统之间加一层缓存memcache,redis。增加缓存之后,能抗住很多压力,大大降低了数据库的读请求。
二、读多写多
高并发场景中,对数据库的操作往往提现在高并发读和高并发写。当读和写都成为瓶颈时,这时采用的方案有:
1)对数据库进行横向和纵向扩展。按业务划分,把一个数据库实例扩展成多个实例。按数据分片,把单表大数据量,水平分片成多个小表。
2)使用内存表负载压力。常见的内存表有:redis开启aof功能。业务数据要持久化落盘。否则进程一旦重启,内存数据就会丢失。
redis:是有硬盘存储的内存数据库,可以支持Master-Slave复制,其可以提供并发量远高于关系型数据库。支持的数据结构:K-V,K-Sets,K-Queue,K-Hash。可适用于高并发读写业务场景,但局限于其数据结构,不能做复杂查询,只能以Key键值为基础数据结构操作。
memcachedb:是基于memcache添加了BerkeleyDB存储机制和主辅复制而来。支持的数据结构只要K-V结构。可适用于高并发读写业务场景,同样只局限于其数据结构,不能做复杂查询,只能以Key键值为基础数据结构操作。
MongoDB:支持Master-Salve复制,无schema,json结构。字段可以任意扩展,可以建立字段索引和全字段索引。可以对任意字段建立索引查询。数据量越来越大时,是吃内存的大户,数据一致性问题会越来越严重。如果对数据一致性要求不高的读多写多业务,可以考虑使用此数据库存储。
三、读少写多
海量数据的写入。如货车app中的gps路线轨迹数据,每天的写入库的数据量上亿条。如此巨大的写入量用关系型数据库显然是不合适的。关系型数据库虽然可以采用批量导入的方式增强写入能力,但其强制落盘,对磁盘IO是影响主要因素。cassandra和habase其先写内存,异步落盘机制对磁盘IO消耗更低。
Cassandra:java开发,结构简单。其数据采用分片机制,副本备份与容错复制。面向列式存储。内存写入与异步刷盘的机制,使其在写操作远高于读操作场景中,也能轻松应对。
HBASE:支持数十亿行,数百万列。对于海量数据的宽表,面向列式存储,无schema,可任意扩展列。
四、读少写少
在小系统,业务量低、数据量少的系统,对读写操作都比较少,当然是怎么快就怎么来。选用mysql免费数据库是最合适的选择。
五、复杂条件检索
关系型数据库通常使用b+tree索引,非关系型数据库如cassandra使用LSM结构索引。所有的索引多列复杂条件查询的检索效率远远低于索引引擎。
常用开源的搜索引擎有luence,solr,elasticsearch,sphinx等。
solr:查询快,但是更新索引速度偏慢。主要应用于那种对数据的实时性要求不高的业务。
elasticserach:更新速度比solr快,但是查询速度相对solr较慢。主要应用于实时索引查询的业务。
总结:
1)对ACID有强要求业务一般使用的数据存储采用关系型数据库,如mysql,postgresql、oracle、sql server等。
2)读多写少的场景,使用非关系型数据库Cassandra、hbase、MongoDB等。
3)缓解高并发读对数据库造成的读瓶颈,使用缓存:memcached、redis等。
4)复杂的数据检索,使用外置索引:elasticsearch、solr等。