存储高性能的知识点总结
文章目录
学习笔记
第四章: 存储高性能
4.1 关系数据库Mysql
关系数据库由于其ACID的特性和功能强大的Sql 查询,目前还是各种业务的重要存储系统
高性能数据库 集群 :
- 第一种方式 : 读写分离,其本质是访问压力分散到集群中的多个节点,但是没有分散存储压力。
- 第二种方式 : 分库分表,既可以分散访问压力,又可以分散存储压力
4.1.1 读写分离
读写分离 的基本原理 : 就是将数据库读写操作分散到不同节点上
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HuCPk1uk-1582187341139)(img/image-20200220145209399.png)]
基本实现:
- 数据库服务器搭建主从集群,一主一从,一主多从都可以
- 数据库主机负责读写操作,从机只负责读操作
- 数据库主机通过复制将数据同步到主机,每台数据库服务器都存储了所有的业务数据
- 业务服务器将写操作发给数据库主机,将读操作发给数据库主机
主从集群与主备集群的区别
- 备机 : 被认为是仅仅备份功能,不提供访问功能。
- 从机 : 需要提供读数据的功能的
主从复制的缺点:
-
主从复制的延迟,有可能大量的数据的读写,可能造成复制延迟的复杂性
例如 : 用户刚新建完用户,登录显示,还没有注册
解决复制延迟的几种常见的方法:
- 写操作的读操作指定发给数据库主服务器
- 读从机失败后,读取主机
- 有可能出现的问题是 : 大量的二次读取,增加了主机的负担
- 这里需要甄别,数据是否是真实数据,而不是黑客造成的
分库分表
大量超过千万条的数据出现,导致数据存储压力。单台服务器并不能支持快速高效的读写
体现方面 :
- 即使使用索引,但是索引也会随着数据的增加而变大
- 数据一旦被损坏,难以快速修复
- 数据过大,备份和修复需要耗费大量时间
业务分库
例如 淘宝 服务器:
可以分为 : 购物车服务器,用户数据,订单数据,商品数据等
出现问题
- join问题
- 由于数据表存在不同的服务器,无法使用join来快速获取数据表中的数据
- 事务问题
- 事务无法统一,或者说难以统一化,若采用分布式事务,又会影响高速性能
- 成本问题
- 服务器数量增加,但是业务数据 并没与达到这样的要求
分表
分表的前提 是 : 数据达到几千万以上,(这个看情况,具体分析)
分表分为
垂直分表
从上而下切分,
表 切分成 : 表记录数相同但包含不同的列
水平分表
从左到右切分
表切分成 : 表的列相同但包含不同的行数据
垂直分表
适用于将表中某些不常用且占了大量空间的列拆分除去
但是 对于的表的操作,要变得复杂
水平分表
适用于表行数特别大的表,如果单表行数超过5000万就必须要进行分表
但是 如何区分数据行数,是一大问题:路由算法
- 范围路由
- 选取有序的数据列或者数据列组作为路由的条件,不同分段分散到不同的数据库表中。
- 优点就是 : 可以平滑的增加新表,而不用更改其他表的操作
- 缺点就是 : 有可能造成分布不均匀,1000 与10 在分别两个表中
- HAsh路由
- 选取某个列(或者某个列组合也行)的值进行hash运算,然后根据hash结果分散到不同的数据库表中。
- 复杂性 : 初始表的数量选取上,表数量太多维护比较麻烦,表数量太少又可能导致单表性能存在问题
- 缺点就是 ; 增加子表非常麻烦,数据要重新分布
- 优点就是 : 数据分布较平均,
- 配置路由
- 就是一张路由表,一张可以独立记录路由信息
- 缺点就是 : 查询多一次,会影响整体性能,路由表大小也会影响性能
- 路由表再分表,会陷入死循环
问题
- join问题
- 需要多个表进行合起来操作
- count()操作
- count()相加 : 性能相加
- 记录表数 : 新建一张新表,后台自动更新和同步数据到这张表中
- order by 操作
- 只能依靠中间件和业务代码来完成功能
实现方法
程序代码封装
抽象一个数据访问层实现读写分离、分库分表。
例如 TDDL,
中间件封装
中间件就是一个数据库服务器
中间件从 数据服务器和业务服务器中间调度
例如 Mysql-proxy ,router 360的Atlas(基于proxy实现)
4.2 非关系数据库NoSql
noSql 是mysql的一个补充,是在一定程度上牺牲部分ACID特定的数据库
常见方案:
- K-V 存储 :解决无法存储数据结构的问题 ——Redis
- 文档数据库 : 解决强schema约束问题——MongoDB
- 列式数据库: 解决大数据场景下I/O问题——Hbase
- 全文搜索引擎: 解决全文搜索性能问题——Elasticsearch
4.2.1 K-V存储
redis 提供 : string,hash ,list,set,sorted set ,bitmap ,hyperloglog 数据结构
缺点 :
- 不支持完整的ACID属性,事务功能无法与关系数据库相比
- redis 事务只能保证隔离性和一致性,无法保证AD,原子性和持久性
- redis 事务不支持回滚
- redis是单进程单线程的工作模式
- 持久性 RDB 和AOF 但是都不能保证事务的持久性
4.2.2 文档数据库
文档数据库最大的特点就是:no-schema 可以存储和读取任意数据,数据格式是json或Bson
优点:
- 增加字段简单
- 历史数据不会出错
- 可以很容易存储辅助数据,例如 一个用户的 所有信息 — 多个家庭住址,多个爱好
- 可以作为关系数据库的补充 : 例如商品的详细信息
缺点:
- 不支持事务
4.2.3 列式数据库
业务同时读取多个列时效率高
能够一次性完成一行中的多个列的写操作
4.2.4 全文搜索引擎
全文搜索引擎的技术原理为倒叙索引,原理 : 建立 单词到文档的索引。
正排索引 原理 是: 建立文档到单词的索引
举例子 :
正排索引 : 通过文档的名称寻找文档
倒排索引 : 通过关键词 来寻找文档
与数据库结合 :
转换方式 :将关系型数据按照对象的形式转换为json文档,然后json文档输入全文搜索引擎来索引
Elasticsearch
是分布式的文档存储方式,
每个字段的所有数据都是默认被索引的,即每个字段都有为了快速检索设置的专用倒排索引。
4.3 缓存
为了弥补存储系统在复杂快速的场景下的不足,
原理 : 是将可能重复使用的数据放到内存中,一次生成,多次使用,避免每次使用都去访问存储系统
4.3.1 缓存穿透
是指 缓存没有发挥作用,业务系统去查询数据,发现没有相对应的数据,只能去存储系统中查询数据
存储数据不存在
- 一般不可能出现 :
- 解决办法 : 直接设置一个默认的值,放到缓存中,等到缓存出现数据,而不会去查找存储系统
缓存数据生成耗费大量时间资源
- 例如商品分页里面的数据,并不知道用户去访问第几页的数据
- 解决办法 :只能从监控上面入手,尽可能阻止大量请求去访问存储系统
4.3.2 缓存雪崩
是指 多缓存失效后引起系统性能急剧下降的情况
解决办法
1. 更新锁机制
- 对缓存更新加锁保护,保证只有一个线程能够进行缓存更新,其他线程要么等待,要么返回特定值
- Zookeeper
2. 后台更新
- 后台线程来更新缓存,缓存本身有效期为永久
- 定时读取 : 还有频繁去读取缓存,去更新缓存
- 消息队列通知 : 业务流程发现缓存失效,通过消息队列发送一条消息通知后台更新缓存
后台更新适用于单机多线程,也适合分布式集群,比更新锁机制要简单一些
4.3.3 缓存热点
例如 微博 的热点,,
缓存复制多份的缓存,将请求分隔多个缓存服务器上,减轻缓存热点导致的单台缓存服务器器压力
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步