一文简述:如何进行数据库选型及扩展
在数据库的应用中,数据库能承受的性能是我们选择使用数据库时要参考的非常重要的因素。过高或过低的评估都将直接影响业务系统对外能提供的吞吐量,以及后期业务发展所带来的扩容问题。
在关系型数据库中,单表存储的极限在亿级别。特别是 MySQL,单表存储过亿时,数据查询会异常缓慢。而 Redis、MongoDB、HBase 等非关系型数据库,都支持 Sharding 分区功能,数据存储基本不受限制。在 QPS 方面,关系型数据库的极限在万级别,而非关系型数据库,根据集群规模不同,能轻松应对 10 万级别以上的高并发读写需求。
如何进行数据库选型
进行一个数据库的选型,主要需要考虑如下两点:
一是业务侧的背景需求
比如是游戏行业、电商行业还是金融行业,存储的是游戏装备/充值记录,还是电商用户订单/商品信息,又或者是金融交易数据等。业务侧对数据的结构、未来规划及扩展的需求,决定了我们是选择关系型数据库还是非关系型数据库这一大类别方向。
对数据结构、数据表及集合的规划设计,选择适合业务需求的关系型数据库或者非关系型数据库,满足业务对数据增删查改的需求。
需要考虑一些热点数据查询需不需要借助 Key-Value 内存数据库做缓存,从架构上减少数据库压力,提升业务系统的性能效率及稳定性。
在代码连接池方面,设计合理的连接池,连接数不宜过大或过小,以免导致后端数据库连接数不释放等性能问题。
在一些对数据库高并发的场景加入队列的控制,也是有效减轻对数据库直接压力冲击的一种方式。
二是运维侧的架构需求
主要表现在数据库的性能及数据库架构扩展能不能满足对业务侧快速发展迭代在数据库存储、性能、扩展方面的需求。即选择对应数据库技术能不能支撑业务的迭代和快速发展。
存储的数据规模及后期扩展,采用主从还是副本集,又或者是 Sharding 的数据库架构?
出现异常怎么进行快速切换,是需要代码层主动切换 IP,还是数据库结合通过 DNS+LB(负载均衡)+HA(高可用)的技术完成无缝切换?
以下是云数据选型中的几条经验来分享供参考:
云数据库的运维架构层考量及规划:云数据库底层已经通过 DNS+LB(负载均衡)+HA(高可用)的技术保障数据库高可用,增加主从节点、增加 Sharding 都可以在控制台界面一键式操作。
云数据库的硬件及基础环境部署:云数据库已经封装成产品服务,不需要考虑选择什么服务器配置来部署数据库,只需要开通对应规格型号的云数据库即可使用。
云数据库的安装配置及优化:云数据库在参数方面已经优化成最优,不需要手动再去调优对应的数据库配置参数。
云数据库的 SQL 语句优化:云数据库在控制台直接给出慢查询的明细及优化建议。
云数据库的日常备份及恢复:云数据库自带热备及冷备,只需要手动在控制台设置对应的备份策略即可。
而我们更多的是要从业务角度出发选择需要什么样类型的数据库。
需要存储什么类型的业务数据:比如用户数据、交易数据,对数据一致性上要求较高,需要优先考虑关系型数据库。
需要存储什么量级的数据:比如 TB 级别数据,关系型数据库的存储已经很慢了。
需要提供什么访问量级的访问:比如上万的并发请求,关系型数据库性能已经快到极限。
如何进行数据库扩展
在数据库领域中,垂直分区和水平分区是一种纵向、横向的架构扩展手段。纵向垂直分区,针对不同的维度,应用场景大有不同。纵向的垂直拆分,可以针对数据库的库级别拆分,也就是说把数据分别放在不同的数据库中,然后把不同的数据库放在不同的服务器中。我们也可以针对数据库读写操作的纵向垂直拆分,这就是经典主从(读写分离)架构。在主从(读写分离)基础上加上高可用,就是数据库的集群技术应用,本质上也是数据库垂直拆分的应用。而水平拆分就是典型的分布式数据库应用,即把一个表的数据划分到不同的数据库,且两个数据库的表结构一样,且两个数据库同时对外提供访问。
垂直拆库
垂直拆库是在数据库扩展中改造工作量最小的,如果业务调用的库和库之间没有跨库查询等依赖关系,我们可以直接把库放在不同机器上运行,然后改一下代码连接数据库的地址。相反,如果业务查询有跨库查询等依赖关系,业务代码受到限制没办法进行扩展,则需要进行一定的代码业务改造。
主从架构
主从复制的架构,根据应用场景的不同,还可以称之为读写分离或者双机热备。读写分离,主要是指在垂直拆分库中,单个库放在单台机器上,没办法再通过升级配置解决数据库性能问题。所以针对数据库增删查改,我们把对数据的查找放在从库上。把数据的增删改操作即写数据放在主库上,可见读写分离是针对数据库连接操作的垂直拆分。
常见数据库的主从架构中最为常见的实践为:
Oracle 的 Data Guard·
MySQL 的 Replication 主从复制
Redis 的 Replication 主从复制
MongoDB 的 Replication 主从复制
常见的用于读写分离的中间件如下:
MySQL Proxy:MySQL-Proxy 是 MySQL 官方提供的中间件服务,是一个处于 Client 端和 MySQL server 端之间类似代理的程序,它可以监测、分析或改变它们的通信。它使用灵活,没有限制,常见的用途包括:读写分离、负载平衡、故障、查询分析,查询过滤和修改等。
MyCAT:MyCAT 是 MySQL 中间件,能够实现读写分离,前身是阿里大名鼎鼎的 Cobar。由于 Cobar 在开源了一段时间后不了了之,于是 MyCAT 扛起了这面大旗。
Amoeba:Amoeba 算中间件中的早期产品,后端还在使用 JDBC Driver,也能实现读写分离功能。
RDS 读写分离服务:阿里云 RDS 自带读写分离的功能服务,通过 RDS 的读写分离地址,可以使写请求自动转发到主实例,读请求按照设置的权重自动转发到各个只读实例。
读写分离,从架构上来看,核心点是增加一个或者多个从库,通过增加的从库来分担数据库的查询压力。在高并发场景下,增加多个从库能有效解决数据库大量查询的压力,但是没办法解决数据库的写(增删改)压力,这是读写分离的瓶颈点。另外,主从复制的机制,从库会造成短期的数据不一致。主要是因为最新写入的数据只会存储在主库中,想要在备库中读取到新数据就必须先从主库复制过来,这会带来一定的延迟,造成短期的数据不一致。
主主架构
为了解决读写分离写(增删改)的瓶颈点,主主架构是主从架构的扩展应用。不管是在主主架构中还是在主主主架构中,都存在着两个主库对某个表同时写入的场景,从而插入的数据在主从同步的时候可能出现主键冲突。为了解决此问题,在两个主库中需要自定义主键自增规则,避免主从同步 ID 重复的问题,如 MySQL 通过 auto_increment_increment 参数自定义自增偏移。
在生产应用中,不推荐同时在主库中写入。即主主实现无缝迁移,不是为了均衡写压力。它的目的是高可用,而不是负载均衡。特别是主主主的架构,更是不推荐在生产环境中应用。
集群架构
数据库的集群,主要是解决主从架构的高可用问题,也不存在主从延时导致从库短暂数据不一致的问题。数据库集群仅解决了主从架构的高可用问题,并没有解决主库面对高并发写、大数据存储的问题。所以数据库集群技术并不是数据库分片 Sharding 技术。
水平拆表
面对 TB、PB 大数据存储及读写场景,垂直拆库、甚至主从读写分离已经明显显得力不从心。水平拆表可以将同一数据表中的记录通过特定的算法进行分离,分别保存在不同的数据表中,从而可以部署在不同的数据库服务器上,来应对大数据存储及读写的场景。但同时水平拆分会带来另外一个问题,就是如果有 join 关联查询,将会导致拆分后的表关联统计变得非常麻烦。
业务层拆表
在业务层面把存储在单个表中的数据分区拆分存放在不同的服务器的数据表中,不过这种方式对业务代码改造较大,而且分区拆分后,join 等操作非常困难。
数据库层拆表
Oracle、MySQL 等关系型数据库的高级特性中,都自带分区表的功能,即将数据按照一个较粗的粒度分在不同的表中。与业务层水平分区拆表不同的是,数据库自带的高级特性分区表只能把表拆分到同台机器的同个数据库中,并不能拆分到不同机器的不同数据库中。
Sharing 拆表
数据库分布式 Sharing 技术是水平分区拆表应用中最为经典最为成熟的应用实践,当前主流的 Sharing 主要分为两大类。一类是通过分布式 Sharding 中间件实现水平分区拆表,另一类即通过非关系型数据库 NoSQL 实现水平分区拆表。Redis、MongoDB、列数据库都属于非关系型数据库(NoSQL),分片 Sharding 技术都是它们自带的经典成熟特性。
写在最后,数据库是 IT 基础设施里面的重中之重,它承载了企业所有的业务数据与管理数据。随着国际关系的不断发展,国产化,开源化已渐渐成为我国数据库的发展新方向。数据库的选型首要因素就是要选择一款使用量很大的产品,不要选冷门!其次就是要结合业务类型,企业自身特点,成本等因素来考虑。
版权声明: 本文为 InfoQ 作者【穿过生命散发芬芳】的原创文章。
原文链接:【http://xie.infoq.cn/article/7f12ace81386bece5dfeaa0ba】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论