NoSQL 概述

2020-06-23 00:00:00 查询 数据 节点 结点 分片

NoSQL

含义

Not Only SQL

和 SQL 的区别

SQL

  • 适合存储结构化的数据
    • 数据需要做结构化查询,eg:join
    • 数据的规模,增长的速度通常是可以预期的
    • 需要保证数据的事务性,一致性要求


  • 缺点
    • 读写性能
    • 表结构更新:如果表里有较多数据时候,有比较大的结构变更会耗时较长
    • 高并发:每秒上万次读写请求,对于传统关系型数据库来说,硬盘IO是一个很大的瓶颈
    • 海量数据:对于关系型数据库来说,在一张包含海量数据的表中查询,效率是比较低的


NoSQL

  • 适合存储非结构化数据
    • 这些数据通常用于模糊处理,eg :全文搜索,机器学习
    • 数据是海量的,而且增长速度难以预期
    • 根据数据的特点,NoSQL 数据库通常具有无限(至少接近无限)的伸缩性
    • 按key获取数据的效率很高,但是对join或者其他结构化查询的支持就比较差


常见类型

键值类(key-value)

  • 产品:memcached,Redis
  • 应用场景:内容缓存,主要用于处理大数据的高访问负载
  • 优点:查找速度快
  • 缺点:数据无结构化,通常只被当做字符串或者二进制数据

列式数据

  • 按列存储数据
  • 大特点是方便存储结构化和半结构化数据,方便做数据压缩,针对某一列或者某几列查询有较大的IO优势
  • 产品:HBase,BigTable,Cassandra等
  • 优点
    • 查找速度快,可拓展性强,容易分布式拓展


  • 缺点
    • 功能相对局限


文档类

  • 将半结构化数据存储为文档,通常采用JSON或者XML 格式
  • 应用场景:存储类似JSON格式的内容,可以对某些字段建立索引功能,是想关系型的数据库
  • 产品:MongoDB,couchBase
  • 优点:数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构
  • 缺点:查询性能不太高

图形类

  • 可以存储顶点以及成为边缘的直接链路
  • 数据模型:图结构
  • 典型应用场景:社交网络,推荐系统等。专注于构建关系图谱,善于处理大量复杂,互连接,低结构化的数据,数据变化迅速,且查询频繁
  • 优点:利用图结构相关算法,比如短路径寻址,N度关系查找等
  • 缺点:很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案

数据分片

单节点

按id范围分片

  • 缺点:可能存在早的 都是冷数据,新的都是热数据

按hash取模分片

  • Node = Hash(Key) % 结点总个数
  • 缺点:不利于拓展,加入或者减少结点之后, 要全部重新分片

一致性Hash取模

  • 算法
    • 先构造一个长度为232的整数环(这个环被称为一致性Hash环),
    • 根据节点名称的Hash值(其分布为[0, 232-1])将服务器节点放置在这个Hash环上,
    • 然后根据数据的Key值计算得到其Hash值(其分布也为[0, 232-1]),接着在Hash环上顺时针查找距离这个Key值的Hash值近的服务器节点,完成Key到服务器的映射查找。


  • 优点
    • 如果增加或者减少结点,不必像hash取模那样 ,需要重新分片,只进行部分分片就可以。


  • 缺点:一个节点失效后,紧邻着的下一个节点压力会增大,会造成负载不均衡。如果下一个节点不能承受压力,会造成雪崩

基于虚拟节点的一致性Hash取模

  • 原理
    • 将一个物理节点拆分为多个虚拟节点,并且同一个物理节点的虚拟节点尽量均匀分布在Hash环上。


  • 优点
    • 一个真实结点不再固定在Hash换上的某个点,而是大量地分布在整个Hash环上,这样即使上线、下线服务器,也不会造成整体的负载不均衡。


Hash 槽

  • 其实哈希槽的本质和一致性哈希算法非常相似,
  • 不同点就是对于哈希空间的定义。
    • 一致性哈希的空间是一个圆环,节点分布是基于圆环的,无法很好的控制数据分布。
    • 而Redis Cluster的槽位空间是自定义分配的,类似于Windows盘分区的概念。这种分区是可以自定义大小,自定义位置的。


  • 每个Key通过计算后都会落在具体一个槽位上,而这个槽位是属于哪个存储节点的,则由用户自己定义分配。例如机器硬盘小的,可以分配少一点槽位,硬盘大的可以分配多一点。如果节点硬盘都差不多则可以平均分配。

数据分片的实现方式

  • 客户端分片(Client side partitioning)
    • 客户端直接选择正确的节点来写入和读取指定键


  • 代理协助分片(Proxy assisted partitioning)
    • 客户端发送请求到一个可以理解 服务端(eg:redis)协议的代理上,而不是直接发送请求到 服务端实例上。代理会根据配置好的分片模式,来保证转发我们的请求到正确的 服务端实例,并返回响应给客户端。


  • 查询路由(Query routing)
    • 你可以发送你的查询到一个随机实例,这个实例会保证转发你的查询到正确的节点。
    • 或者 直接返回给客户端要查询的正确的结点数据,客户端重新去正确的结点查询

相关文章