高性能架构设计——数据库篇

高性能数据库集群的第一种方式是“读写分离”,其本质是将访问压力分散到集群中的多个节点,但是没有分散存储压力;

第二种方式是“分库分表”,既可以分散访问压力,又可以分散存储压力。

一、高性能数据库集群:读写分离

读写分离的基本实现是:

  • 数据库服务器搭建主从集群,一主一从、一主多从都可以。
  • 数据库主机负责读写操作,从机只负责读操作。
  • 数据库主机通过复制将数据同步到从机,每台数据库服务器都存储了所有的业务数据。
  • 业务服务器将写操作发给数据库主机,将读操作发给数据库从机。

两个设计复杂度: 主从复制延迟分配机制

解决主从复制延迟有几种常见的方法:

1. 写操作后的读操作指定发给数据库主服务器

2. 读从机失败后再读一次主机

3. 关键业务读写操作全部指向主机,非关键业务采用读写分离

分配机制

将读写操作区分开来,然后访问不同的数据库服务器,一般有两种方式:程序代码封装和中间件封装。

程序代码封装。示意图:

中间件封装:

中间件封装指的是独立一套系统出来,实现读写操作分离和数据库服务器连接的管理。中间件对业务服务器提供 SQL 兼容的协议,业务服务器无须自己进行读写分离。对于业务服务器来说,访问中间件和访问数据库没有区别,事实上在业务服务器看来,中间件就是一个数据库服务器。其基本架构是:

二、高性能数据库集群:分库分表

 分散存储的方法“分库分表”,其中包括“分库”和“分表”两大类。

1、分库:

业务分库指的是按照业务模块将数据分散到不同的数据库服务器。 通过分库,将业务分别存储在不同的数据库中,从而降低数据库存储压力。

分库后,SQL的join和事务无法使用,不建议初创公司使用。

单台数据库服务器的性能:一般来说,单台数据库服务器能够支撑 10 万用户量量级的业务。

2、分表:

将不同业务数据分散存储到不同的数据库服务器,能够支撑百万甚至千万用户规模的业务,但如果业务继续发展,同一业务的单表数据也会达到单台数据库服务器的处理瓶颈。此时就需要对单表数据进行拆分。

单表数据拆分有两种方式:垂直分表和水平分表。

垂直分表适合将表中某些不常用且占了大量空间的列拆分出去。水平分表适合表行数特别大的表。

水平分表相比垂直分表,会引入更多的复杂性,主要表现在下面几个方面:

水平分表后,某条数据具体属于哪个切分后的子表,需要增加路由算法进行计算。

常见的路由算法有:

  • 范围路由
    •    一般建议分段大小在 100 万至 2000 万之间。
    • 优点是可以随着数据的增加平滑地扩充新的表。缺点是分布不均匀。
  • Hash 路由
    • 选取某个列(或者某几个列组合也可以)的值进行 Hash 运算,然后根据 Hash 结果分散到不同的数据库表中。
    • Hash 路由的优缺点和范围路由基本相反,Hash 路由的优点是表分布比较均匀,缺点是扩充新的表很麻烦,所有数据都要重分布。
  • 配置路由

三、NoSQL

NoSQL 是 SQL 的一个有力补充,NoSQL != No SQL,而是 NoSQL = Not Only SQL。

NoSQL 方案带来的优势,本质上是牺牲 ACID 中的某个或者某几个特性。

常见的 NoSQL 方案分为 4 类。

K-V 存储:解决关系数据库无法存储数据结构的问题,以 Redis 为代表。

文档数据库:解决关系数据库强 schema 约束的问题,以 MongoDB 为代表。

列式数据库:解决关系数据库大数据场景下的 I/O 问题,以 HBase 为代表。

全文搜索引擎:解决关系数据库的全文搜索性能问题,以 Elasticsearch 为代表。

四、高性能缓存架构

  1. 需要经过复杂运算后得出的数据,存储系统无能为力
  2. 读多写少的数据,存储系统有心无力

缓存就是为了弥补存储系统在这些复杂业务场景下的不足,其基本原理是

将可能重复使用的数据放到内存中,一次生成、多次使用,避免每次使用都去访问存储系统。

缓存能够带来性能的大幅提升,以 Memcache 为例,单台 Memcache 服务器简单的 key-value 查询能够达到 TPS 50000 以上,其基本的架构是:

缓存穿透是指缓存没有发挥作用,业务系统虽然去缓存查询数据,但缓存中没有数据,业务系统需要再次去存储系统查询数据。

缓存雪崩是指当缓存失效(过期)后引起系统性能急剧下降的情况。

缓存热点的解决方案就是复制多份缓存副本,将请求分散到多个缓存服务器上,减轻缓存热点导致的单台缓存服务器压力。

原文地址:https://www.cnblogs.com/developer-qin/p/14597029.html