数据库优化

1.读写分离

1.1 概念

        读写分离主要是为了将数据库的读写操作分散到不同的数据库节点上。这样的化能够小幅度提升写性能,大幅度提升读性能。

        一般情况是一主多从,主数据库用于写,从数据库用于读。

1.2 实现方式

1.2.1 实现步骤

        1.部署多台数据库,选择其中的一台作为主数据库,其他的为从数据库

        2.保证主数据库和从数据库之间的数据是实时同步的,这个过程也就是主从复制

        3.系统将写请求给主数据库,读请求给从数据库

1.2.2 实现方式

        1.代理方式: 在数据库与应用中间加入一个代理层,应用将请求发送给代理层,然后代理层区分读请求还是写请求,在发送给对应的数据库

        2.组件方式:引入第三方组件

1.3 实现原理

        1. 主库将数据库中数据的变化写入到binlog(归档日志)

        2. 从库连接主库

        3. 从库会创建一个I/O线程向主库请求更新的bin log

        4.主库会创建一个bin log dump线程来发送bin log,从库中的I/O线程负责接收

        5.从库的I/O线程将接受的binlog写入relay log(重做日志)中

        6.从库的SQL线程读取relay log(重做日志)同步数据到本地

1.4 主从延迟

1.4.1 概念

        主库写完之后,从库同步需要一定的时间,这个时间差导致了主库和从库的数据不一致性问题

1.4.2 解决方法

        1.强制将读请求路由到主库处理

        2.延迟读取,比如支付成功后,跳到一个支付成功的页面,维持几秒,再读取

1.4.3 出现原因

        1.从库 I/O 线程接收 binlog 的速度跟不上主库写入 binlog 的速度,导致从库 relay log 的数据滞后于主库 binlog 的数据;

        2.从库 SQL 线程执行 relay log 的速度跟不上从库 I/O 线程接收 binlog 的速度,导致从库的数据滞后于从库 relay log 的数据。

2.分库分表

2.1 概念

        分库 就是将数据库中的数据分散到不同的数据库上,可以垂直分库,也可以水平分库。

        垂直分库 就是把单一数据库按照业务进行划分,不同的业务使用不同的数据库,进而将一个数据库的压力分担到多个数据库。

        水平分库 是把同一个表按一定规则拆分到不同的数据库中,每个库可以位于不同的服务器上,这样就实现了水平扩展,解决了单表的存储和性能瓶颈的问题。

        分表 就是对单表的数据进行拆分,可以是垂直拆分,也可以是水平拆分。

        垂直分表 是对数据表列的拆分,把一张列比较多的表拆分为多张表。

举个例子:我们可以将用户信息表中的一些列单独抽出来作为一个表。

        水平分表 是对数据表行的拆分,把一张行比较多的表拆分为多张表,可以解决单一表数据量过大的问题。

2.2 使用场景

  • 单表的数据达到千万级别以上,数据库读写速度比较缓慢。
  • 数据库中的数据占用的空间越来越大,备份时间越来越长。
  • 应用的并发量太大(应该优先考虑其他性能优化方法,而非分库分表)

2.3 分片算法    

  • 哈希分片:求指定分片键的哈希,然后根据哈希值确定数据应被放置在哪个表中。哈希分片比较适合随机读写的场景,不太适合经常需要范围查询的场景。哈希分片可以使每个表的数据分布相对均匀,但对动态伸缩(例如新增一个表或者库)不友好。
  • 范围分片:按照特定的范围区间(比如时间区间、ID 区间)来分配数据,比如 将 id1~299999 的记录分到第一个表, 300000~599999 的分到第二个表。范围分片适合需要经常进行范围查找且数据分布均匀的场景,不太适合随机读写的场景(数据未被分散,容易出现热点数据的问题)。
  • 映射表分片:使用一个单独的表(称为映射表)来存储分片键和分片位置的对应关系。映射表分片策略可以支持任何类型的分片算法,如哈希分片、范围分片等。映射表分片策略是可以灵活地调整分片规则,不需要修改应用程序代码或重新分布数据。不过,这种方式需要维护额外的表,还增加了查询的开销和复杂度。
  • 一致性哈希分片:将哈希空间组织成一个环形结构,将分片键和节点(数据库或表)都映射到这个环上,然后根据顺时针的规则确定数据或请求应该分配到哪个节点上,解决了传统哈希对动态伸缩不友好的问题。
  • 地理位置分片:很多 NewSQL 数据库都支持地理位置分片算法,也就是根据地理位置(如城市、地域)来分配数据。
  • 融合算法分片:灵活组合多种分片算法,比如将哈希分片和范围分片组合。

 2.4 分片键选择  

  • 具有共性,即能够覆盖绝大多数的查询场景,尽量减少单次查询所涉及的分片数量,降低数据库压力;
  • 具有离散性,即能够将数据均匀地分散到各个分片上,避免数据倾斜和热点问题;
  • 具有稳定性,即分片键的值不会发生变化,避免数据迁移和一致性问题;
  • 具有扩展性,即能够支持分片的动态增加和减少,避免数据重新分片的开销。

3.数据冷热分离

3.1 概念

        数据冷热分离是指根据数据的访问频率和业务重要性,将数据分为冷数据和热数据,冷数据一般存储在存储在低成本、低性能的介质中,热数据高性能存储介质中。

3.2 冷数据和热数据

有两个常见的区分方法:

  1. 时间维度区分:按照数据的创建时间、更新时间、过期时间等,将一定时间段内的数据视为热数据,超过该时间段的数据视为冷数据。例如,订单系统可以将 1 年前的订单数据作为冷数据,1 年内的订单数据作为热数据。这种方法适用于数据的访问频率和时间有较强的相关性的场景。
  2. 访问频率区分:将高频访问的数据视为热数据,低频访问的数据视为冷数据。例如,内容系统可以将浏览量非常低的文章作为冷数据,浏览量较高的文章作为热数据。这种方法需要记录数据的访问频率,成本较高,适合访问频率和数据本身有较强的相关性的场景。

3.3 冷热分离优缺点

  • 优点:热数据的查询性能得到优化(用户的绝大部分操作体验会更好)、节约成本(可以冷热数据的不同存储需求,选择对应的数据库类型和硬件配置,比如将热数据放在 SSD 上,将冷数据放在 HDD 上)
  • 缺点:系统复杂性和风险增加(需要分离冷热数据,数据错误的风险增加)、统计效率低(统计的时候可能需要用到冷库的数据)。

3.4 冷数据迁移

  • 业务层代码实现:当有对数据进行写操作时,触发冷热分离的逻辑,判断数据是冷数据还是热数据,冷数据就入冷库,热数据就入热库。这种方案会影响性能且冷热数据的判断逻辑不太好确定,还需要修改业务层代码,因此一般不会使用。
  • 任务调度:可以利用 xxl-job 或者其他分布式任务调度平台定时去扫描数据库,找出满足冷数据条件的数据,然后批量地将其复制到冷库中,并从热库中删除。这种方法修改的代码非常少,非常适合按照时间区分冷热数据的场景。
  • 监听数据库的变更日志 binlog :将满足冷数据条件的数据从 binlog 中提取出来,然后复制到冷库中,并从热库中删除。这种方法可以不用修改代码,但不适合按照时间维度区分冷热数据的场景。

3.5 冷数据存储        

        冷数据的存储要求主要是容量大,成本低,可靠性高,访问速度可以适当牺牲。

        冷数据存储方案:

                中小厂:直接使用 MySQL/PostgreSQL 即可(不改变数据库选型和项目当前使用的数据库保持一致),比如新增一张表来存储某个业务的冷数据或者使用单独的冷库来存放冷数据(涉及跨库查询,增加了系统复杂性和维护难度)

                大厂:Hbase(常用)、RocksDB、Doris、Cassandra

        

你可能感兴趣的:(数据库)