在微服务设计中,数据库的选型是不可缺少的一环,后台的核心是与数据打交道,在不同的业务场景选择的数据库不一样, 好的数据库选型能够解决业务的性能瓶颈,如果数据库选择不恰当,会使得服务的性能上不去,因此我们需要对一些常用的数据库有一些了解,这样才能因地制宜,发挥系统最好的性能。

常见的数据库分类:

数据库类型数据库名称
关系型数据库Mysql,Oracle,postgresql
内存数据库Redis,Memcache
时序数据库TSDB
文档型数据库MongoDB
分布式数据库TIDB
数据库Neo4J,Infinite Graph,OrientDB
列式存储数据库HBase,ClickHouse,Elasticsearch
文件存储eph,GlusterFS等

可以看出,数据库种类是很多的,每一种应用的领域也不一样,很多大公司还会专门对数据库进行定制,以提高数据存取的性能,下面我们来分析不同业务场景下数据库怎么选择。

关系型数据库选择

系型数据库用的最多的是Mysql,大部分互联网企业都会选用Mysql作为数据存储,主要因为Mysql有如下优点:

  • 成本低,安全,稳定,生态完善

  • 使用简单,方便

  • 使用者多,用来做业务开发,运维比较简单

  • 对于普通业务支持性能很不错

对于请求量,数据量不大的情况下,对Mysql做增删改查的业务性能还是很好的,并且Mysql提供强一致性事务的支持,支持多种事务隔离级别,并且多种存储引擎的选择,使得Mysql在数据库中的地位是非常之高的。但是金无足赤人无完人,在业务扩展到一定规模,Mysql的问题就暴露出来了,主要的问题有:

  • Mysql对OLAP类型查询支持比较弱

  • Mysql是单机数据库,需要开发人员去实现集群部署,维护成本很大

  • 单表数据规模达到亿级别性能会下降

  • 大表加索引很困难,因此很难对大表进行在线优化

Mysql对一些复杂类型的查询支持是很弱的,举个例子,如果我们要做个搜索查询的功能,根据各种指标,范围去数据库中搜索数据,如果业务层通过Mysql去实现,前期数据量小的情况下是没多少问题的,但是如果表中数据量越来越多,或者搜索的条件组合很复杂,那么此时会很慢。因此,复杂查询业务尽量不要使用Mysql。另外如果业务扩大到一定规模,Mysql单表也会变得很大,这个时候性能会受到影响,如果已经不能优化,还需要做分表等扩展措施来解决业务的性能瓶颈。

如果遇到这些情况,目前业界的主流方案除了分区表,分库分表,通过代理中间件进行分表之外,比较热门的就是分布式数据库,分布式数据库最大的特点是能够自由扩展,不要考虑数据量瓶颈的问题。这两年比较流行的是TIDB数据库,TIDB是一个分布式数据库,最大的优点是兼容Mysql协议,并且通过Raft协议保证数据一致性。因此Mysql用户可以很简单的迁移到TIDB来。并且TIDB对一般的OLAP查询支持也比较好,因此数据量大的情况下使用TIDB是一个更好的选择。

内存数据库

内存数据库用的多的是Redis,大多数业务场景都是用做缓存,少部分对数据安全不敏感的场景用来做数据持久化,因为Redis也支持数据持久化。游戏行业以前用Memcache比较多,现在也逐渐向Redis靠拢。由于Redis数据都放到内存中,并且在局域网环境通信的代价也比较廉价,所以Redis的性能非常好,并且Redis支持多种类型的数据结构,在不同业务使用都非常方便。

但是Redis也有着和Mysql相似的问题,单机的Redis会有性能瓶颈,理想情况下单机Redis QPS也只能达到10w,如果请求量非常大的情况下会对业务造成影响,并且Redis是单线程的,虽然单线程能避免context切换的开销,但是并不能利用多核特性,这在高性能应用领域是一个致命打击。集群化部署需要在业务层做哈希来实现负载均衡,如果涉及到增删节点还需要做数据迁移,这段时间也会对业务造成影响。因此,单线程即成就了Redis同时也限制了Redis,因此有不少大公司在实现多线程Redis的项目来解决这个问题。

文档型数据库

文档型数据库比较有名的是MongoDB,MongoDB是非关系型数据库,弱一致性,在4.0版本以上开始支持事务,提供snapshot isolation的事务隔离级别,这个隔离级别和Mysql中的repeatable read隔离级别相同。MongoDB内部采用GridFS做数据落地,对一些文件对象支持比较友好。MongoDB支持多种存储引擎,可以适应不同的场景,并且使用方便,对一致性要求不高的业务场景用的很多,常用来存储一些加工的中间数据,方便去展示, 也有一些公司使用MongoDB做最终数据落地,因此,很多进行数据展示的业务可以使用使用MongoDB,或者查询条件多样并且想提高查询速度的场景也可以使用MongoDB替换Mysql。

MongoDB虽然优点很多,但是也有很多场景是不适应的,刚刚提到过Mysql是弱一致的,因此一些重要数据为了安全性考虑,不建议用MongoDB。并且MongoDB比较吃内存,如果返回大批量数据,会有内存不够直接查询失败的情况,MongoDB对OLAP查询支持很弱,因此比较复杂的查询场景也不建议使用MongoDB。

列式存储数据库

提到列式存储数据库有必要先说一下什么是行式存储,像Mysql这种属于行式存储,当我们查询数据,都是以行为单位在磁盘存储, 然后再内存做字段挑选返回给用户,如果表的字段很多我们只查找一部分字段这样磁盘查找的开销就会很大,在列式存储数据库中,数据存在磁盘以列为单位,我们查询某些字段只需要在对应的列上进行搜寻,这样性能就会提高。

列式存储比较出名的数据库是ClickHouse,ClickHouse是定义为OLAP类型的数据库,专门用来处理数据分析型业务。ClickHouse采取了并行处理机制,所以做分析查询速度非常快,对于一些搜索,分析,数据规模大的查询性能支持非常好,所以这种业务可以采用ClickHouse去做。但是由于ClickHouse专为分析查询而生,因此对于更新删除操作支持并不是怎么好,修改删除都是采取的追加写方式,主要是为了避免随机IO,ClickHouse会在底层异步的去做数据合并,如果需要频繁的对数据源进行修改,那不绝对不要使用ClickHouse。如果需要写入数据,也需要采取批量写入的方式,ClickHouse会对数据进行压缩存储,提高资源利用率。

列式存储另一个比较出名的是Elasticsearch,在一些偏向搜索的场景比较用的比较多,支持倒排索引,并且支持各种聚合运算,查询性能强劲,但是成本相比ClickHouse比较高昂,可以根据业务进行选型,考虑。

时序数据库

时序数据库从字面意思理解来说是关于时间点的数据,时间序列表示的数据,一般在指标采样的场景会用到,可以很直观的看出数据随时间变化,比较著名的有OpenTSDB,时序数据随时间增长,如果数据没有变化重复取上一个值。时序数据库适用于大批量的数据采样分析,常用在批处理,流处理后的数据落地,这些数据经过加工后直接批量写入到OpenTSDB中,供业务层访问,以提高查询性能。美中不足的是如果数据加工错误,纠错成本太大。OpenTSDB底层是用的HBase,HBase特点是对写性能支持比较好,底层也是为了避免随机IO采用追加写的技术。读通过顺序读保证性能,如果是随机读性能会很差,因此OpenTSDB应用场景限制于按时间维度分析数据的场景。

分布式文件存储系统

常用的分布式文件系统有HDFS,Ceph,GlusterFS等,种类非常多,不同的分布式文件存储系统适用不同的场景,每种系统适用的场景不一样,比如有些对大文件支持比较好,有些对中小文件支持比较好。基本上所有分布式文件系统都支持对象存储,块存储,文件存储中的两种以上。分布式文件存储系统常用来存储文件,比如文档,照片,电源,视频这种。不像数据库那种存储一些数据,并且分布式文件系统不支持那种维度查询,这是和数据库的最大区别。

分布式文件存储系统的选型要根据文件的形式,大小,用途去考虑。还需要对参数做大量的调优以得到最佳的性能。传统的本地文件系统文件都是存在磁盘中,而分布式文件系统文件需要存储在其他节点,本地进行访问时还需要经过网络中转的开销,如果文件比较大,带宽就限制了传输的速度。这个时候就需要进行将文件分片进行存储。以GlusterFS为例,GlusterFS的 Distributed Volumes 属于分布式卷,如果需要保证数据安全可以做冗余,GlusterFS支持Replica和纠删码两种数据冗余方式,如果做数据冗余,会影响读写性能。在做选型时,有这两方面考虑,如果追求极致的数据安全,使用Replica Volumes,如果为了性能,也为了安全,使用纠删码的方式,如果追求极致性能,可以考虑分布式卷,但是如果出现机器宕机则会造成数据丢失。

更多干货请关注微信号: 黑客的成长秘籍
在这里插入图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐