《NoSQL精粹》读书摘要

1、Why NoSQL?
  • 关注NoSQL的两个缘由
    • 应用程序的开发效率(NoSQL简化了数据交互)
    • 大规模的数据(NoSQL为集群环境而设计)
  • NoSQL不是独立存在的,之后也不会取代关系型数据库,之后数据库领域将步入混合持久化(Polyglot Persistence)时代。
  • 关系型数据库的优势:
    • 标准化的建模
    • 较为容易的处理关系
    • 经过事务来处理并发
    • 能够持久化
  • 关系型数据库的缺点:
    • 阻抗失谐:关系型数据库中的存储结构(模式、表、元组)与应用程序中的数据结构须要转换。ORM框架能够解决这个问题,可是会引发性能的降低。
    • 应用程序数据库(摘绿帽)与集成数据库(戴绿帽):SOA的兴起(内部数据库与外部通讯服务间的解耦)
    • 集群化问题:扩展性问题(纵向与横向)与许可费问题,大数据是一个巨大推进
  • NoSQL的定义:开源分布式的非关系型数据库
    • 开源
    • 分布式
    • 非关系型(无模式)
  • 使用NoSQL的主要缘由:(其余状况下,请依然使用关系型数据库)
    • 数据量大,访问效率要求高
    • 要解决“阻抗失谐”的问题
 
2、聚合数据模型
  • NoSQL的主要分类
    • 面向聚合(aggregate oriented):来自于DDD
      • 键值模型(key-value):聚合对数据库不透明,只能整个的读取
      • 文档模型(document):透明的聚合,能够看到数据结构,能够读取其部分(以结构的限制换取更好的访问性)
      • 列族模型(column family):“两级映射”——两级聚合结构。所以其既“面向行”也“面向列”
    • 非面相聚合:图数据库(graph)
  • 聚合的优势:
    • 在集群中,使用聚合操做数据比较简单
    • 聚合也方便应用程序操做数据结构(对程序员更为友好)
    • 以聚合为单位的原子操做
    • 下降了数据采集时的须要节点数
  • 聚合的缺点:
    • 多个聚合的操做原子性须要应用代码来维护,而这经常比较复杂
 
3、数据模型详解
  • 关系型:若是待处理的数据中存在大量关系,那么这就意味着须要选用关系型数据库(但其实图数据库在这方面更强)
  • 聚合型:操做单个聚合很方便,可是操做多个聚合时就很笨拙
  • 图数据库:
    • 以包含节点和边的图构成;
    • 节点简单,互连结构丰富
    • 图数据库中遍历关系很是迅速,可是关系型数据库较差
    • 一般运行在单一的服务器上
  • 无模式的数据库:
    • 其实总包含“隐含模式”
    • 本质上说,无模式数据库把模式交由访问其数据的应用程序代码来处理
    • 若是你发现存储的数据类型不统一,那么应优选无模式数据库
    • 无模式的灵活性仅限于聚合内部
    • 数据迁移对有无模式的数据库而言都是难点
  • 物化视图
    • 做用:使基本数据和派生数据对客户端透明
    • 计算生成物化视图比较复杂耗时
    • 方式:
      • 一旦有数据变化,当即更新
      • 按期经过批处理操做更新(通常经过Map-Reduce)
    • 能够将物化视图在聚合内使用,以便在原子操做内更新
 
4、分布式模型
  • 横向扩展易于纵向扩展
  • 数据分布:
    • 复制(replication)
      • 主从式(master-salve)
      • 对等式(peer-to-peer)
    • 分片(sharding)
    • 这两种方式正交,能够同时使用
  • 单一服务器
    • 单一服务器便可以SQL也能够NoSQL
    • 在不需分布数据时,应老是选择“单一服务器”方案
  • 分片
    • 将不一样的数据放在不一样的数据库服务器上
    • 读、写性能均可以提高
    • 会下降数据库的错误恢复能力(由于须要维护更多的数据库服务器了)
    • 优化方式:
      • 地理空间上应将数据库靠近访问者
      • 负载均衡
      • 自动分片技术(大部分NoSQL提供,其将应用代码与数据库分片功能解耦)
  • 主从复制
    • 能够将系统视为带有“即时备份”功能的“单服务器存储方案”
    • 优势:
      • 经过新增从节点能够方便的进行水平扩展,能够处理更多的读请求,并保证读请求都被引导至从节点
      • 能够加强读操做的故障恢复能力
        • 主节点出错了,从节点依然能够提供读服务
        • 拥有与主节点相同内容的从节点能够很快的被指派为新的主节点,代替故障的原主节点
      • 减小了写操做的冲突几率
    • 缺点:
      • 数据的不一致性
      • 主节点是性能瓶颈
  • 对等复制
    • 优势
      • 全部的节点均可以读写
      • 易于扩展
      • 不存在性能瓶颈节点
    • 缺点:
      • 数据一致性问题
  • 解决写入操做冲突的两种极端解决思路:
    • 老是去协调节点间的关系,确保不发生冲突,只需保证各大部分副本的一致性,
    • 容许节点间的冲突,但尝试合并这些冲突的写入操做
  • 分片+复制
    • 对等复制+分片
    • 将分片存放在必定数量(复制因子)的对等节点中
 
5、一致性
  • 须要理解并权衡
    • 强一致性(strong consistency):时时一致
    • 最终一致性(eventual consistency):有不一致的时间窗,但最后一致
  • 更新一致性
    • 问题:写冲突(write-write conflict)
    • 经常使用解决方式:
      • 先决条件:处理更新操做的顺序必须一致
        • 顺序一致性(sequential consistency)
      • 悲观方式:避免发生冲突
        • 写入锁
        • 会大幅下降系统的响应能力
        • 容易产生死锁
      • 乐观方式:发生冲突,再解决冲突
        • 条件更新
        • 保存全部的更新,标注出冲突,并合并冲突
  • 读取一致性
    • 问题:读写冲突(read-write conflict)/读取不一致(logical consistency)
    • NoSQL对事物的支持:
      • 面向聚合:支持“原子更新”,但不支持多个聚合构成的事物
      • 图数据库:支持
    • 不一致窗口:数据逻辑不一致的时间长度
    • 复制一致性:不一样副本中数据的一致性
    • 一般能够指定单个请求所需的一致性级别,合理地下降部分请求的一致性级别能够提升性能
    • 照原样读出所写内容的一致性(read-your-writes consistency)
      • 会话一致性
        • 黏性会话
          • 将读写绑定至某一个节点
          • 会下降负载均衡器的效能
        • 版本戳
  • 放宽“一致性”约束
    • 制定合理的隔离级别,合理地放宽一致性要求
    • CAP理论
      • 一致性(Consistency)
      • 可用性(Availability)
      • 分区耐受性(Partition tolerance)
      • 常见错误理解:
        • 咱们只能同时知足其中两个方面
        • 实际上:当系统可能会遇到“分区”情况时,咱们须要在“一致性”和“可用性”之间进行权衡;这并非一个二选一问题。
    • 有时能够适当放宽一致性,容许冲突的发生,并经过领域知识指导下的应用程序代码来解决冲突,以换取更好的并发能力。
    • NoSQL倡导的BASE理论:
      • 基本可用(Basically Available)
      • 柔性状态(Soft State)
      • 最终一致性(Eventual consistency)
      • 本质上大可能是一致性与时延的取舍
  • 放宽“持久性”约束
    • 非持久性写入操做
      • 例如,Redis先写入内存,而后再按期的写入硬盘
    • 复制持久性
      • 在复制过程当中,写节点失效,就会形成数据的丢失
      • 须要权衡对复制质量的保证仍是数据库的响应速度
  • 仲裁(避免冲突的方式)
    • 写入仲裁
      • 在对等式分布模型下:
        • W>N/2
        • W:写节点数
        • N:复制因子
      • 在主从式分布模型下:
        • 从主节点
    • 读取仲裁
      • 在对等式分布模型下:
        • R+W>N
        • R:读节点数
      • 在主从式分布模型下:
        • 从主节点
    • 仍是须要根据实际状况来肯定具体的仲裁方式
 
6、版本戳
  • 商业事务vs系统事务
    • 商业事务:针对用户而言从,整个交互流程
    • 系统事务:用户提交后,对系统而言的事务
    • 问题:商业事务和系统事务之间,存在较大的时间窗
    • 解决方式:离线并发技术
      • 乐观离线锁(条件更新的一种):compare-and-set(CAS操做)
      • 经过比较商业事务开始执行时的版本戳与系统事务开始执行时的版本戳,来检验信息是否发生了变化,以肯定是否须要进行更新操做
  • 常见的版本戳类型:
    • 计数器
      • 易于比较
      • 可是须要一个主服务器用来生成并保证不一样版本的计数器值不会重复
    • GUID(Globally Unique Identifier),全局惟一标识符:
      • 任何人均可以生成
      • 可是数值较大,并且难以直接比较
    • 根据资源内容生成Hash码
      • 足够大时,能够惟一标识
      • 任何人均可以生成
      • Hash值是肯定的
      • 可是冗长且没法直接比较
    • 上一次更新的时间戳
      • 短小,易于生成
      • 能够直接比较
      • 可是不一样服务器之间的时钟必须同步,不然很容易形成数据损毁
      • 且时间戳的精度很难肯定:太低,没法区分;太高,须要频繁的更新
    • 复合版本戳(composite stamp)
      • 运用多种手法
  • 在多节点环境中生成版本戳
    • 单服务器或主从式复制模型:
      • 基本的版本戳方案就足够了:计数器
      • 时间戳也能够,但不如计数器好
    • 多个主节点时:
      • 每一个节点维护一份版本戳记录(version stamp history)
      • 经过判断“祖先”记录来肯定新旧关系;如互不为祖先,则检测为冲突
    • 对等式复制模型
      • 数组式版本戳(vector stamp)
      • 维护一个数组记录全部节点的版本,例如[server01:1, server02:4, server03:5]
      • 如缺失某些值,则视为0,例如视server04:0
      • 这样便于新增节点
  • 版本戳仅能检测冲突,而不能解决冲突,冲突的解决依赖于领域知识
 
7、Map-Reduce
  • 分散-汇集(Scatter-Gather)模式的一种形式
  • 将部分计算逻辑放于数据库服务器上
  • 输入值是某个集合,输出值是键值对的集合
  • 主要包括如下函数
    • Mapper
    • Combiner
    • Reducer
  • 一般会要求Mapper Combinable,既Mapper同时做为Combiner使用
  • 一般会使用管道及过滤器(Pipes-and-filters)来组合处理
  • 增量式Map-Reduce: 一般须要保存部分中间结果,以备下次使用
  • 经典实现:Hadoop
    • Pig:专用语言
    • Hive:类SQL语言
 
8、常见NoSQL实现
  • 键值
    • Memcached
    • Redis
    • Riak
  • 文档
    • CouchDB
    • MongoDB
  • 列族
    • HBase
    • Cassandra
    • Amazon SimpleDB
    • Neo4J
    • HyperGraphDB
相关文章
相关标签/搜索