系统架构设计师—数据库基础篇—数据库优化技术

news/2025/3/10 21:31:29/

文章目录

  • 集中式数据库
    • 反规范化设计
      • 分类
      • 保证数据的一致性方法
  • 分布式数据库
    • 主从复制
      • 基本过程
        • binlog的同步模式
        • MySQL的同步模式
    • 读写分离
    • 分表
    • 分库
  • 分布式缓存技术-Redis
    • 数据类型
    • 读写数据的基本步骤
      • 读数据
      • 写数据
    • 过期策略
      • 惰性删除
      • 定期删除
      • 内存淘汰机制
    • 持久化
    • 缓存异常问题
      • 缓存穿透
      • 缓存雪崩
        • redis故障
        • 大量key同时过期
      • 缓存击穿
    • 集群
    • 切片

集中式数据库

反规范化设计

优点:

  • 避免进行表之间的连接操作,可以提高数据操作的性能。

缺点:

  • 数据的重复存储,浪费磁盘空间。
  • 会产生数据不一致性问题。

分类

类型说明作用
增加冗余列指在多个表中具有相同的列。在查询时避免连接操作。
增加派生列增加的列可用通过表中其他数据计算生成。在查询时减少计算量,从而加快查询速度。
重新组表如果许多用户需要查看两个表连接出来的结果数据,则把这两个表重新组成一个表来减少连接而提高性能。在查询时减少连接,从而加快查询速度。
水平分割表按记录进行分割,把数据放到多个独立的表中。主要用于表数据规模很大、表中数据相对独立或数据需要存放到多个介质上使用的场景。
垂直分割表对表进行分割,将主键与部分列放到一个表中,主键与其他列放到另一个表中。在查询时减少I/O次数,以提高查询效率。

保证数据的一致性方法

  1. 触发器
  2. 事务机制保证(适用于单体数据库中)
  3. 应用保证(适用于异构数据库之间)
  4. 批处理脚本()

分布式数据库

主从复制

主从复制,建立一个和主数据库完全一样的数据库环境,称为从数据库

  • 做数据的热备:作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
  • 架构的扩展:业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个及其的I/O性能。
  • 读写分离:使数据库能支持更大的并发。

基本过程

主从数据库之间通过 binary log(二进制日志,一般称 binlog)进行数据的同步。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

binlog的同步模式
基于SQL语句的复制基于行的复制混合复制
基本流程每一条写语句都会记录在binlog中,进而同步到从库的relaylog中,被从库的SQL线程取出来,回放执行。不记录SQL语句,只记录了哪个记录更新前和更新后的数据。对于有绑定本地特性、评估可能造成主从不一致的SQL语句,则自动选用ROW;其他的选则STATEMENT。
优点binlog的日志量比较少。可以保证主从之间数据绝对相同。binlog的日志量尽可能少,主从之间数据尽可能相同。
缺点同步的SQL语句如果含有绑定本地变量的函数、关键字时,可能造成主从不一致的情况。如:时区。单条SQL批量更新数据的情况,会产生大量日志。受限于评估算法,如未快速支持某种新特性,可能产生主从数据不一致的问题。
MySQL的同步模式
一致性可用性典型框架/系统
全同步复制技术主库等待所有从库都同步完毕,才返回客户端。MySQL
半同步复制技术主课等待至少一个从库同步完毕,则返回客户端较强较弱MySQL、Zookeeper、Redis、Oracle
异步复制技术主库不等待从库同步,执行完客户端提交的事务后就返回客户端。MySQL、Redis、Oracle

读写分离

读写分离,设置不同的主/从数据库分别负责不同的操作。

通过角色分担的策略,分别提升读写性能,有效减少数据并发操作的延迟。

分表

分表,也叫分片,解决并发能力、I/O性能提升。
将一张大表分成若干小表,业务同时访问多个表。
分表是重在单个实例内部,一张表拆分称多个表。

  • 垂直切分
  • 水平切分

分库

分库,将原本存放在一个实例上众多分类的数据(表),分开存放到不同的实例上。有利于差异化管理。

分布式缓存技术-Redis

Redis用作缓存组件时,其基于内存的读写特性,比基于磁盘读写的数据库性能要高很多,适合缓存高频热点的数据,来提高读性能。这样可以降低厎数据库服务器的查询请求,提高系统性能。

数据类型

类型说明适用场景
string基本类型。可用于缓存层或计数器,如视频播放量、文章浏览量等。
hash代替string类型,节省空间。描述用户信息较为方便
set无序集合,每个值不能重复。可用于去重、抽奖、初始化用户池等。
zset有序集合,每个元素有一个分数。如首页推荐10个最热门的帖子。
list双向链表结构,可以模拟栈、队列等形式。可用于回复评论、点赞。
pub/sub发布/订阅可以用作消息队列,生产者将消息投送给某个key为主题的队列,消费者监听并得到消息的推送.

读写数据的基本步骤

读数据

  1. 根据key读缓存。
  2. 读取成功则直接返回。
  3. 若key不在缓存中时,根据key读数据库
  4. 读取成功后写缓存。
  5. 成功返回。

写数据

  1. 根据key写数据库
  2. 成功后更新缓存key值。
  3. 成功返回。

过期策略

惰性删除

查询key时,才对key进行检测,如果已经达到过期时间,则删除。
缺点:如果这些过期的key没有被访问,那么就一直无法被删除,一直占用内存。

定期删除

redis每隔一段时间对数据库做一次检查,删除里面的过期key。由于不可能对所有key去做轮询来删除,所有redis会每次随机取一些key去做检查和删除。

内存淘汰机制

淘汰机制说明
volatile-lru从已设置过期时间的key中,移出最近最少使用的key进行淘汰。
volatile-lfu从已设置过期时间的key中,移出最不经常使用的进行淘汰。
volatile-random从已设置过期时间的key中随机选择key淘汰。
volatile-ttl从已设置过期时间的key中,移出将要过期的key。
allkeys-lru从所有key中选择最近最少使用的进行淘汰。
allkeys-lfu从所有key中选择最不经常使用的进行淘汰。
allkeys-random从所有key中随机选择key进行淘汰。

持久化

RDB内存快照(RedisDataBase)AOF日志(Append Only File)
说明把当前内存中的数据集快照写入磁盘(数据库中所有键值对数据)。恢复时,是将快照文件直接读取到内存里。通过持续不断地保存Redis服务器所执行的更新命令来记录数据库状态,类似mysql的binlog。恢复数据时,需要从头开始回放更新命令。
磁盘刷新频率
文件大小
数据恢复效率
数据安全

缓存异常问题

缓存穿透

访问的key在redis中不存在。

原因:

  1. 恶意攻击,造成大量访问Redis中不存在的key。
  2. 大量请求访问数据库里有但redis没有的key。

解决方案:

  • 针对来源是比较少的请求来源ip,主动限制访问次数,或者拉入黑名单。
  • 应用程序检查key的合法性,提前拒绝不合法的请求。
  • 使用布隆过滤器。
  • 预热redis,运行一个批处理脚本,将可能会大量访问的数据预先加载到redis,业务再开张。
  • 在最前端进行流量控制,逐步释放进来的请求。给出一段时间,让redis逐步加载热数据。
  • 如果数据库里也没有的key,也要在redis中设置key,使其值为null或空。

缓存雪崩

Redis的key是已存在的,但同时失效了。

redis故障

如宕机、网络抖动

解决方案:

  • 使用主从复制提高可用性,使用cluster集群方案降低故障时的影响范围。
  • 如果出现故障,则可以采取服务降级、熔断、限流等措施。
大量key同时过期

采取了相同的过期时间,例如在同一时刻设置了大量的key,但过期时间都是5分钟。

解决方案:

  • 过期时间加上一个随机值,使得众多key均匀过期。

缓存击穿

少量热点key缓存时间失效。

原因:

  • 热点的key设置了太短的过期时间。

如:秒杀业务下的“库存数量”。

解决方案:

  • 设置较长的过期时间。非常重要的key则设置永久有效。但需要解决好与数据库中的key的一致性问题。
  • 使用分布式锁:如果热点key失效了,要控制好访问后端数据库的流量。只允许一个请求去访问数据库,取出罪行的key,存放到redis,其他请求必须等待。但分布式锁也要防止出现异常的情况。

集群

  • 主从复制集群
  • 哨兵集群
  • Cluster集群

切片

类型说明
客户端分片将分片工作放在业务程序端。不依赖于第三方分布式中间件,实现方法和代码可掌控,对开发人员要求高。
代理分片将分片工作交给专门的代理程序来做,运维方便。代表:Twemproy,Codis。
服务器端分片Redis Cluster将所有key映射到16384个Slot中,集群中每个Redis实例负责一部分,业务程序通过集成的Redis Cluster客户端进行操作。

http://www.ppmy.cn/news/1578179.html

相关文章

小程序 -- uni-app开发微信小程序环境搭建(HBuilder X+微信开发者工具)

目录 前言 一 软件部分 1. 微信开发者工具 2. HBuilder X 开发工具 二 配置部分 1. 关于 HBuilder X 配置 2. 关于 微信开发工具 配置 三 运行项目 1. 新建项目 2. 代码编写 3. 内置浏览器 编译 4. 配置小程序 AppID获取 注意 四 实现效果 前言 uni-app开发小程…

K8s 1.27.1 实战系列(六)Pod

一、Pod介绍 1、Pod 的定义与核心设计 Pod 是 Kubernetes 的最小调度单元,由一个或多个容器组成,这些容器共享网络、存储、进程命名空间等资源,形成紧密协作的应用单元。Pod 的设计灵感来源于“豌豆荚”模型,容器如同豆子,共享同一环境但保持隔离性。其核心设计目标包括…

【2025深夜随笔】简单认识一下Android Studio

【2025深夜随笔】Android Studio 全生命周期开发指南:从安装到项目实战简单解析 一、Android Studio 核心认知 1.1 官方定位与生态价值 Android Studio(简称AS)是谷歌官方推出的 安卓开发IDE(集成开发环境)&#xff…

计算机网络笔记(二)——1.2互联网概述

1.2.1网络的网络 起源于美国的互联网现已发展成为世界上最大的覆盖全球的计算机网络。 下面,我们先来看看关于网络、互连网、互联网(因特网)的一些基本概念。为了方便,后面我们所称呼的"网络"往往就是"计算机网络",而不是电信网或有…

【0基础学Python】基础语法Part1

第一个python程序 print(12-3) print(hello world!) print(12/3)熟悉 C / Java 的同学可能认为, 2 / 3 结果为 0 (小数部分被截断). 但是在 Python 中得到的结果则是 一个小数. 更符合日常使用的直觉。 变量和类型 python无需声明变量类型,会自动确定你所写的变量…

NO.25十六届蓝桥杯备战|字符数组|初始化|输入|输出|strlen|gets|fgets|strcpy|strcat(C++)

字符数组 字符数组介绍 数组的元素如果是字符类型,这种数组就是字符数组,字符数组可以是⼀维数组,可以是⼆维数组(多维数组)。 接下来主要讨论⼀维的字符数组。 char arr1[5]; //⼀维数组 char arr2[3][5];//⼆维…

游戏引擎学习第140天

回顾并为今天的内容做准备 目前代码的进展到了声音混音的部分。昨天我详细解释了声音的处理方式,声音在技术上是一个非常特别的存在,但在游戏中进行声音混音的需求其实相对简单明了,所以今天的任务应该不会太具挑战性。 今天我们会编写一个…

SDIO(Secure Digital Input Output)详解

1. SDIO的定义 SDIO(Secure Digital Input Output) 是基于 SD(Secure Digital)存储卡标准 扩展的 通用输入输出接口协议,允许设备通过SD卡槽连接多种外设(如Wi-Fi模块、GPS、摄像头等)。它不仅…