存储高性能的知识点总结

学习笔记

第四章: 存储高性能

4.1 关系数据库Mysql

关系数据库由于其ACID的特性和功能强大的Sql 查询,目前还是各种业务的重要存储系统

高性能数据库 集群 :

  1. 第一种方式 : 读写分离,其本质是访问压力分散到集群中的多个节点,但是没有分散存储压力。
  2. 第二种方式 : 分库分表,既可以分散访问压力,又可以分散存储压力

4.1.1 读写分离

读写分离 的基本原理 : 就是将数据库读写操作分散到不同节点上

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HuCPk1uk-1582187341139)(img/image-20200220145209399.png)]

基本实现:
  1. 数据库服务器搭建主从集群,一主一从,一主多从都可以
  2. 数据库主机负责读写操作,从机只负责读操作
  3. 数据库主机通过复制将数据同步到主机,每台数据库服务器都存储了所有的业务数据
  4. 业务服务器将写操作发给数据库主机,将读操作发给数据库主机
主从集群与主备集群的区别
  1. 备机 : 被认为是仅仅备份功能,不提供访问功能。
  2. 从机 : 需要提供读数据的功能的
主从复制的缺点:
  1. 主从复制的延迟,有可能大量的数据的读写,可能造成复制延迟的复杂性

    例如 : 用户刚新建完用户,登录显示,还没有注册

解决复制延迟的几种常见的方法:
  1. 写操作的读操作指定发给数据库主服务器
  2. 读从机失败后,读取主机
    • 有可能出现的问题是 : 大量的二次读取,增加了主机的负担
    • 这里需要甄别,数据是否是真实数据,而不是黑客造成的

分库分表

大量超过千万条的数据出现,导致数据存储压力。单台服务器并不能支持快速高效的读写

体现方面 :

  1. 即使使用索引,但是索引也会随着数据的增加而变大
  2. 数据一旦被损坏,难以快速修复
  3. 数据过大,备份和修复需要耗费大量时间
业务分库

例如 淘宝 服务器:

可以分为 : 购物车服务器,用户数据,订单数据,商品数据等

出现问题
  1. join问题
    • 由于数据表存在不同的服务器,无法使用join来快速获取数据表中的数据
  2. 事务问题
    • 事务无法统一,或者说难以统一化,若采用分布式事务,又会影响高速性能
  3. 成本问题
    • 服务器数量增加,但是业务数据 并没与达到这样的要求
分表

分表的前提 是 : 数据达到几千万以上,(这个看情况,具体分析)

分表分为

垂直分表

从上而下切分,

表 切分成 : 表记录数相同但包含不同的列

水平分表

从左到右切分

表切分成 : 表的列相同但包含不同的行数据

垂直分表

适用于将表中某些不常用且占了大量空间的列拆分除去

但是 对于的表的操作,要变得复杂

水平分表

适用于表行数特别大的表,如果单表行数超过5000万就必须要进行分表

但是 如何区分数据行数,是一大问题:路由算法

  1. 范围路由
    • 选取有序的数据列或者数据列组作为路由的条件,不同分段分散到不同的数据库表中。
    • 优点就是 : 可以平滑的增加新表,而不用更改其他表的操作
    • 缺点就是 : 有可能造成分布不均匀,1000 与10 在分别两个表中
  2. HAsh路由
    • 选取某个列(或者某个列组合也行)的值进行hash运算,然后根据hash结果分散到不同的数据库表中。
    • 复杂性 : 初始表的数量选取上,表数量太多维护比较麻烦,表数量太少又可能导致单表性能存在问题
    • 缺点就是 ; 增加子表非常麻烦,数据要重新分布
    • 优点就是 : 数据分布较平均,
  3. 配置路由
    • 就是一张路由表,一张可以独立记录路由信息
    • 缺点就是 : 查询多一次,会影响整体性能,路由表大小也会影响性能
    • 路由表再分表,会陷入死循环
问题
  1. join问题
    • 需要多个表进行合起来操作
  2. count()操作
    • count()相加 : 性能相加
    • 记录表数 : 新建一张新表,后台自动更新和同步数据到这张表中
  3. order by 操作
    • 只能依靠中间件和业务代码来完成功能

实现方法

程序代码封装

抽象一个数据访问层实现读写分离、分库分表。

例如 TDDL,

中间件封装

中间件就是一个数据库服务器

中间件从 数据服务器和业务服务器中间调度

例如 Mysql-proxy ,router 360的Atlas(基于proxy实现)

4.2 非关系数据库NoSql

noSql 是mysql的一个补充,是在一定程度上牺牲部分ACID特定的数据库

常见方案:

  1. K-V 存储 :解决无法存储数据结构的问题 ——Redis
  2. 文档数据库 : 解决强schema约束问题——MongoDB
  3. 列式数据库: 解决大数据场景下I/O问题——Hbase
  4. 全文搜索引擎: 解决全文搜索性能问题——Elasticsearch

4.2.1 K-V存储

redis 提供 : string,hash ,list,set,sorted set ,bitmap ,hyperloglog 数据结构

缺点 :
  1. 不支持完整的ACID属性,事务功能无法与关系数据库相比
  2. redis 事务只能保证隔离性和一致性,无法保证AD,原子性和持久性
    • redis 事务不支持回滚
    • redis是单进程单线程的工作模式
    • 持久性 RDB 和AOF 但是都不能保证事务的持久性

4.2.2 文档数据库

文档数据库最大的特点就是:no-schema 可以存储和读取任意数据,数据格式是json或Bson

优点:
  1. 增加字段简单
  2. 历史数据不会出错
  3. 可以很容易存储辅助数据,例如 一个用户的 所有信息 — 多个家庭住址,多个爱好
  4. 可以作为关系数据库的补充 : 例如商品的详细信息
缺点:
  1. 不支持事务

4.2.3 列式数据库

业务同时读取多个列时效率高

能够一次性完成一行中的多个列的写操作

具体看博客

4.2.4 全文搜索引擎

全文搜索引擎的技术原理为倒叙索引,原理 : 建立 单词到文档的索引。

正排索引 原理 是: 建立文档到单词的索引

举例子 :

正排索引 : 通过文档的名称寻找文档

倒排索引 : 通过关键词 来寻找文档

与数据库结合 :

转换方式 :将关系型数据按照对象的形式转换为json文档,然后json文档输入全文搜索引擎来索引

Elasticsearch

是分布式的文档存储方式,

每个字段的所有数据都是默认被索引的,即每个字段都有为了快速检索设置的专用倒排索引。

4.3 缓存

为了弥补存储系统在复杂快速的场景下的不足,

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

4.3.1 缓存穿透

是指 缓存没有发挥作用,业务系统去查询数据,发现没有相对应的数据,只能去存储系统中查询数据

存储数据不存在
  • 一般不可能出现 :
  • 解决办法 : 直接设置一个默认的值,放到缓存中,等到缓存出现数据,而不会去查找存储系统
缓存数据生成耗费大量时间资源
  • 例如商品分页里面的数据,并不知道用户去访问第几页的数据
  • 解决办法 :只能从监控上面入手,尽可能阻止大量请求去访问存储系统

4.3.2 缓存雪崩

是指 多缓存失效后引起系统性能急剧下降的情况

解决办法

1. 更新锁机制
  1. 对缓存更新加锁保护,保证只有一个线程能够进行缓存更新,其他线程要么等待,要么返回特定值
  2. Zookeeper
2. 后台更新
  1. 后台线程来更新缓存,缓存本身有效期为永久
  2. 定时读取 : 还有频繁去读取缓存,去更新缓存
  3. 消息队列通知 : 业务流程发现缓存失效,通过消息队列发送一条消息通知后台更新缓存

后台更新适用于单机多线程,也适合分布式集群,比更新锁机制要简单一些

4.3.3 缓存热点

例如 微博 的热点,,

缓存复制多份的缓存,将请求分隔多个缓存服务器上,减轻缓存热点导致的单台缓存服务器器压力

原文地址:https://www.cnblogs.com/YJBlog/p/12337094.html