菜单
菜单
文章目录
  1. CAP理论
  2. 数据一致性
    1. 1.场景
    2. 2.强一致性
    3. 3.弱一致性
    4. 4.最终一致性
    5. 5.其他一致性
    6. 6.实现技术
  3. 几种数据库比较
    1. HBase
      1. 1.列存储
      2. 2.简介
      3. 3.场景
      4. 4.区别
      5. 5.数据模型
      6. 6.视图
      7. 7.系统结构
      8. 8.存储格式
    2. Redis
      1. 1.简介
      2. 2.数据模型
      3. 3.数据类型
      4. 4.其他管理命令
      5. 5.Redis事务
      6. 6.Redis分区
    3. MongoDB
      1. 1.简介
      2. 2.主要特点
      3. 3.适用场景
      4. 4.Mongodb术语
      5. 5.Mongodb操作
      6. 6.复制与备份
      7. 7.分片
      8. 8.案例
    4. Neo4j
      1. 1.简介
      2. 2.概念
      3. 3.特点
      4. 4.例子
    5. 总结比较结果

Nosql复习

CAP理论

  • CAP理论:一个分布式系统不可能满足一致性可用性和分区容错性这三需求,最多只能同时满足

  • 强一致性(Consistency):系统在执行过某项操作后仍然处于一致的状态。在分布式系统中,更新操作执行成功后所有的用户都应该读取到最新的值,这样的系统被认为具有强一致性。

  • 可用性(Availability):每一个操作总是能够在一定的时间内返回结果

    • 一定时间内”是指,系统的结果必须在给定时间内返回,如果超时则被认为不可用。这是至关重要的。比如通过网上银行的网络支付功能购买物品。当等待了很长时间,如15分钟,系统还是没有返回任务操作结果,购买者一直处于等待状态,那么购买者就不知道现在是否支付成功,还是需要进行其他操作。这样当下次购买者再次使用网络支付功能时必将心有余悸。
    • 返回结果”同样非常重要。还是拿这个例子来说,假如购买者点击支付之后很快出现了结果,但是结果却是“Java.lang.error……”之类的错误信息。这对于普通购买者来说相当于没有返回任何结果。因为他仍旧不知道系统处于什么状态,是支付成功还是失败,或者需要重新操作。
  • **分区容错性(Partition Tolerance):**分区容错性可以理解为系统在存在网络分区的情况下仍然可以接受请求(满足一致性和可用性)。这里网络分区是指由于某种原因网络被分成若干个孤立的区域,而区域之间互不相通。还有一些人将分区容错性理解为系统对节点动态加入和离开的处理能力,因为节点的加入和离开可以认为是集群内部的网络分区。

  • 图解CAP

    • 如下图所示,在网络中有两个节点分别为G1和G2,这两个节点上存储着同一数据的不同副本,现在数据是一致的,两个副本的值都为V0,A、B分别是运行在G1、G2上与数据交互的应用程序。

    • 在正常情况下,操作过程如下(如下图所示):

      (1)A将V0更新,数据值为V1;

      (2)G1发送消息m给G2,数据V0更新为V1;

      (3)B读取到G2中的数据V1。

    • 如果发生网络分区故障,那么在操作的步骤(2)将发生错误:G1发送的消息不能传送到G2上。这样数据就处于不一致的状态,B读取到的就不是最新的数据,如图所示。如果我们采用一些技术如阻塞、加锁、集中控制等来保证数据的一致,那么必然会影响到系统的可用性和分区容错性。

    • CAP理论告诉我们如果系统具有较高的可用性和较小延迟,那么节点必须能够容忍网络分区,但这时候应用程序可能会得到不同的数据(B读取到的值为V1)。
    • 有人可能会想,如果我们对步骤(2)的操作加一个同步消息,问题会不会解决呢(同时满足CAP理论三个特性)?答案是否定的。不加同步的情况下,G1到G2的更新是不可知的,也就是说,B读取到得数据可能是V1也可能是V2,但是服务是可用的。即同时满足了“A”和“P”,但是不保证“C”一定满足。加了同步消息之后,将能够保证B读取到数据V1。但是这个同步操作必定要消耗一定的时间,尤其是在网络规模较大的情况下,当节点规模成百上千的时候,不一定能保证此时的服务是可用的。这种情况下只能满足“C”和“P”,而不能保证“A”一定满足。
选择 放弃 特点 例子
CA P 两阶段提交、缓存验证协议 传统数据库、集群数据库、LDAP、GFS文件系统
CP A 悲观加锁 分布式数据库、分布式加锁
AP C 冲突处理、乐观 分布式数据库、分布式加锁: BASE

数据一致性

1.场景

    • 存储系统

      • 存储系统可以理解为一个黑盒子,它为我们提供了可用性和持久性的保证
    • Process A

      • ProcessA主要实现从存储系统write和read操作
    • Process B 和ProcessC

      • B和C独立于A,B和C也相互独立的
      • B和C也实现对存储系统的write和read操作

2.强一致性

    • 也叫即时一致性
    • 假如A先写入了一个值到存储系统,存储系统保证后续A,B,C的读取操作都将返回最新值
    • 单副本数据容易保证强一致性
    • 多副本数据需要使用分布式事务协议

3.弱一致性

    • 假如A先写入了一个值到存储系统,存储系统不能保证后续A,B,C的读取操作能读取到最新值

    • 不一致性窗口

      • 从A写入到后续操作A,B,C读取到最新值这一段时间

4.最终一致性

    • 最终一致性是弱一致性的一种特例
    • 假如A首先write了一个值到存储系统,存储系统保证如果在A,B,C后续读取之前没有其它写操作更新同样的值的话,最终所有的读取操作都会读取到A写入的最新值
    • 此种情况下,如果没有失败发生的话,“不一致性窗口”的大小依赖于以下的几个因素:交互延迟,系统的负载,以及复制技术中replica的个数(这个可以理解为master/salve模式中,salve的个数)
    • 最终一致性方面最出名的系统可以说是DNS系统,当更新一个域名的IP以后,根据配置策略以及缓存控制策略的不同,最终所有的客户都会看到最新的值
  • 注: BASE模型(Basically Availble Soft-state Eventual-Consistency)

    • BASE模型完全不同于ACID模型,牺牲高一致性,获得可用性或可靠性
    • ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

5.其他一致性

  • Causal consistency(因果一致性)

    • 如果Process A通知Process B它已经更新了数据,那么Process B的后续读取操作则读取A写入的最新值,而与A没有因果关系的C则可以最终一致性
  • Read-your-writes consistency(读自写一致性)

    • 如果Process A写入了最新的值,那么Process A的后续操作都会读取到最新值。但是其它用户可能要过一会才可以看到
  • Session consistency(会话一致性)

    • 此种一致性要求客户端和存储系统交互的整个会话阶段保证Read-your-writes consistency,Hibernate的session提供的一致性保证就属于此种一致性4
  • Monotonic read consistency(单调读一致性)

    • 此种一致性要求如果Process A已经读取了对象的某个值,那么后续操作将不会读取到更早的值
  • Monotonic write consistency(单调写一致性)

    • 此种一致性保证系统会序列化执行一个Process中的所有写操作

6.实现技术

  • NWR模型

    • N: 复制的节点数量
    • R: 成功读操作的最小节点数
    • W: 成功写操作的最小节点数
    • 只需W + R > N,就可以保证强一致性,因为读取数据的节点和被同步写入的节点是有重叠的

    • 在分布式系统中,一般都要有容错性,因此N大于3

    • 根据CAP理论,一致性、可用性和分区容错 性最多只能满足两个,因此需要在一致性和可用性之间做一平衡

      • 如果要高的一致性,那么就配置N=W,R=1,这个时候可用性特别是写操作的性能就会大大降低
      • 如果想要高的可用性,那么此时就需要放松一致性的要求,此时可以配置W=1,这样使得写操作延迟最低,同时通过异步的机制更新剩余的N-W个节点

    几种特殊情况

      • W = 1, R = N,对写操作要求高性能高可用
      • R = 1, W = N , 对读操作要求高性能高可用,比如类似cache之类业务
      • W = Q, R = Q where Q = N / 2 + 1 一般应用适用,读写性能之间取得平衡,如N=3,W=2,R=2
  • 两阶段式提交

    • 两阶段提交协议是很常见的解决分布式事务的方式,可以保证分布式事务中,要么所有参与的进程都提交事务成功,要么都取消事务,这样做可以在分布式环境中保持ACID中A(原子性)

    • 在两阶段提交协议中,包含了两种角色

      • 参与者就是实际处理事务的机器
      • 协调者就是其中一台单独的处理分布式事务的机器
    • 该算法分为两个阶段

      • 投票阶段

        • 在请求阶段,协调者将通知事务参与者准备提交或取消事务,然后进入表决过程
        • 在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)
      • 提交阶段

        • 协调者将基于第一个阶段的投票结果进行决策:提交或取消。当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务
    • 优点

      • 实现简单
    • 缺点

      • 同步阻塞问题
      • 执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。
      • 单点故障

        由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)

      • 数据不一致

        在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象

      • 二阶段无法解决的问题

        协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交

几种数据库比较

列存储 文档存储 KV存储 图存储
HBase MongoDB Redis Neo4j
数据压缩,对一个或多个字段查询 保证海量数据存储,同时查询良好。类json 极高的并发读取写性能,用key查value,但只能用key 图形关系的最佳存储

HBase

1.列存储

  • 对于任何记录,索引都可以快速地获取列上的数据
  • Map-reduce的实现Hadoop的流数据处理效率非常高,列式存储的优点体现的淋漓极致
  • 关系类型的列标对数据分析效果不好,因此,用户经常将更复杂的数据存储在列式数据库中。这直接体现在Cassandra中,它引入的“column family”可以被认为是一个“super-column”
  • 列式存储支持行检索,但这需要从每个列获取匹配的列值,并重新组成行

2.简介

  • HBase(Hadoop Database)是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群
  • HBase可以直接使用本地文件系统或者Hadoop作为数据存储方式,不过为了提高数据可靠性和系统的健壮性,发挥HBase处理大数据量等功能,需要使用Hadoop作为文件系统

3.场景

在这个领域,HBase有3种主要使用场景(但不限于这3 种)

1.抓取增量数据

使用HBase 作为数据存储,抓取来自各种数据源的增量数据,如抓取用户交互数据,以备之后进行分析、处理

2.内容服务

传统数据库最主要的使用场合之一是为用户提供内容服务,如URL短链接服务,可以HBase为基础,存储大量的短链接以及和原始长链接的映射关系

3.信息交换

Facebook的短信平台每天交换数十亿条短信,HBase可以很好的满足该平台的需求:高的写吞吐量,极大的表,数据中心的强一致性

4.区别

  • 数据类型(传统数据库)
    • HBase只有简单的字符串类型,所有类型都由用户自己处理,它只保存字符串
    • 关系数据库有丰富的类型选择和存储方式
  • 数据操作
    • HBase操作只有很简单的插入、查询、删除、清空等,表和表之间是分离的,没有复杂的表和表之间的关系,所以也不能也没有必要实现表和表之间的关联等操作
    • 传统的关系数据通常有各种各样的函数、连接操作
  • 存储模式
    • HBase是基于列存储的,每个列族都有几个文件保存,不同列族的文件是分离的
    • 传统的关系数据库是基于表格结构和行模式保存的
  • 数据维护
    • HBase的更新正确来说应该不叫更新,而且一个主键或者列对应的新的版本,而它旧有的版本仍然会保留,所以它实际上是插入了新的数据
    • 传统关系数据库里面是替换修改
  • 可伸缩性
    • HBase和BigTable这类分布式数据库就是直接为了这个目的开发出来的,能够轻易的增加或者减少(在硬件错误的时候)硬件数量,而且对错误的兼容性比较高
    • 传统的关系数据库通常需要增加中间层才能实现类似的功能

5.数据模型

  • HBase的索引是行关键字、列关键字和时间戳

  • 每个值是一个不解释的字符数组,数据都是字符串,没有类型

  • 用户在表格中存储数据,每一行都有一个可排序的主键和任意多的列

  • 由于是稀疏存储的,同一张表里面的每一行数据都可以有截然不同的列

  • 列名字的格式是“<family>:<label>”,都是由字符串组成,每一张表有一个family集合,这个集合是固定不变的,相当于表的结构,只能通过改变表结构来改变,但是label值相对于每一行来说都是可以改变的

  • HBase把同一个family里面的数据存储在同一个目录底下,而HBase的写操作是锁行的,每一行都是一个原子元素,都可以加锁

  • 所有数据库的更新都有一个时间戳标记,每个更新都是一个新的版本,而HBase会保留一定数量的版本,这个值是可以设定的

  • 客户端可以选择获取距离某个时间最近的版本,或者一次获取所有版本

  • HBase数据模型中三个重要概念

    • 行键(Row Key):HBase表的主键,表中的记录按照行键排序。行键用来检索记录的主键
    • 时间戳(Timestamp):每次数据操作对应的时间戳,可看作是数据的版本号,不同版本通过时间戳来进行索引
    • 列族(Column Family):表在水平方向有一个或者多个列族组成,一个列族中可以由任意多个列组成,即列族支持动态扩展,无需预先定义列的数量以及类型,所有列均以二进制格式存储,用户需要自行进行类型转换

6.视图

  • 概念视图

    稀疏的

  • 物理视图

7.系统结构

  • client

    • Client访问用户数据之前需要首先访问Zookeeper,然后访问-ROOT-表,接着访问.META.表,最后才能找到用户数据的位置去访问,中间需要多次网络操作,不过Client端会做cache缓存
    • Client包含访问HBase的接口,Client维护着一些缓存来加快对HBase的访问,比如HRegion的位置信息
    • HBase Client使用HBase的RPC机制与HMaster和HRegionServer进行通信,对于管理类操作,Client与HMaster进行RPC;对于数据读写类操作,Client与HRegionServer进行RPC
  • Zookeeper

    • Zookeeper中除了存储-ROOT-表的地址和HMaster的地址,HRegionServer也会把自己以“Ephemeral”方式注册到Zookeeper中,使得HMaster可以随时感知到各个HRegionServer的健康状态

    • Zookeeper也避免了HMaster的单点问题

    • Zookeeper的作用

      • 保证任何时候,集群中只有一个HMaster
      • 存储所有HRegion的寻址入口
      • 实时监控HRegionServer的状态,将HRegionServer的上线和下线信息实时通知给HMaster
      • 存储HBase的schema,包括有哪些表,每个表有哪些列族
  • HMaster

    • HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个HMaster运行

    • HMaster在功能上主要负责表和HRegion的管理工作

      • 管理用户对表的增、删、改、查操作
      • 管理HRegionServer的负载均衡,调整HRegion分布
      • 在HRegion分裂后,负责新HRegion的分配
      • 在HRegionServer停机后,负责失效HRegionServer上的HRegion的迁移
  • HRegionServer:主要负责响应用户I/O请求,向HDFS文件系统中读写数据,是HBase中最核心的模块

  • HStore:HStore存储是HBase存储的核心了,由两部分组成,一部分是HMemStore,一部分是HStoreFile

    • 用户写入的数据首先会放入HMemStore,当HMemStore满了以后会Flush成一个HStoreFile。当HStoreFile文件数量增长到一定阈值,会触发合并操作,将多个HStoreFile合并成一个HStoreFile
    • 合并会形成越来越大的HStoreFile,当单个HStoreFile大小超过一定阈值后,会触发分裂操作,同时把当前HRegion 分裂成2个Hregion
    • 在分布式系统环境中,无法避免系统出错或者宕机,因此一旦HRegionServer意外退出,HMemStore中的内存数据将会丢失。这就需要引入HLog,当HRegionServer重启后进行数据恢复
  • HRegion

    • 任何时刻,一个HRegion只能分配给一个HRegionServer
    • HMaster记录了当前有哪些可用的HRegionServer,以及当前哪些HRegion分配给了哪些HRegionServer,哪些HRegion还没有分配
    • 当存在未分配的HRegion时,并且有一个HRegionServer上有可用空间时,HMaster就给这个HRegionServer发送一个装载请求,把HRegion分配给这个HRegionServer
    • HRegionServer得到请求后,就开始对此HRegion提供服务
  • HRegionServer上线

    • Master使用Zookeeper来跟踪HRegionServer的状态
    • 当某个HRegionServer启动时,会首先在Zookeeper上的server目录下建立代表自己的文件,并获得该文件的独占锁
    • 由于HMaster订阅了server目录上的变更消息,当server目录下的文件出现新增或删除操作时,HMaster可以得到来自Zookeeper的实时通知
    • 因此,一旦HRegionServer上线,HMaster能马上得到消息
  • HMaster下线

    • 由于HMaster只维护表和HRegion的元数据,而不参与表数据IO的过程,HMaster下线,仅导致所有元数据的修改被冻结(无法创建删除表,无法修改表的schema,无法进行HRegion的负载均衡,无法处理HRegion上下线,无法进行HRegion的合并,唯一例外的是HRegion的分裂可以正常进行,因为只有HRegionServer参与),表的数据读写还可以正常进行
    • 因此,HMaster下线短时间内对整个HBase集群没有影响
    • 从上线过程可以看到,HMaster保存的信息全是可以冗余信息(都可以从系统其它地方收集到或者计算出来),因此,一般HBase集群中总是有一个HMaster在提供服务,还有一个以上的HMaster在等待时机抢占它的位置

8.存储格式

  • HBase中的所有数据文件都存储在Hadoop分布式文件系统HDFS上

  • 两种文件类型

    • HFile:HBase中KeyValue数据的存储格式,HFile是Hadoop的二进制格式文件,实际上HStoreFile就是对HFile做了轻量级包装,即HStoreFile底层就是HFile

          HFile分为六部分
      
      • Data Block:保存表中的数据,这部分可以被压缩
      • Meta Block(可选的):保存用户自定义的key/value对,可被压缩。
      • File Info:HFile的元信息,不被压缩,用户可在这部分添加自己的元信息
      • Data Block Index:Data Block的索引
      • Meta Block Index(可选的):Meta Block的索引
      • Trailer:读取HFile时会首先读取Trailer,Trailer保存了每个段的起始位置(Magic Number用来做安全check),然后,DataBlockIndex会被读取到内存中,这样当检索某个key时,不需要扫描整个HFile,只需从内存中找到key所在的block,通过一次磁盘io将整个block读取到内存中,再找到需要的key
  • HLogFile:HBase中WAL(Write Ahead Log)的存储格式,物理上是Hadoop的顺序文件

    • HLog又称WAL。WAL意为Write Ahead Log,类似Mysql中的binlog,用来做灾难恢复,HLog记录数据的所有变更,一旦数据修改,就可以从HLog中进行恢复
    • 每个HRegionServer维护一个HLog,而不是每个HRegion一个,这样不同HRegion(来自不同表)的日志会混在一起,这样做的目的是,不断追加单个文件相对于同时写多个文件而言,可以减少磁盘寻址次数,因此,可以提高对表的写性能。带来的麻烦是,如果一台HRegionServer下线,为了恢复其上的HRegion,需要将HRegionServer上的HLog进行拆分,然后分发到其它HRegionServer上进行恢复

Redis

1.简介

  • Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API

  • 支持的数据类型包括string、list、set、zset(有序集合)和hash

  • 支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且操作都是原子性的,支持各种不同方式的排序

  • 速度非常快,每秒可以执行大约110000设置操作,81000个/每秒的读取操作

  • Redis支持主从同步

    • 数据可以从主服务器向任意数量的从服务器上同步
    • 从服务器可以是关联其他从服务器的主服务器,这使得Redis可执行单层树复制
    • 由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录
    • 同步对读取操作的可扩展性和数据冗余很有帮助

2.数据模型

  • Redis的key为字符串类型
  • Redis支持丰富的value类型:string, list, hash, set, zset
  • 只能通过key对value进行操作

3.数据类型

类型 存储的值 读写能力
STRING 可以是字符串、整数或者浮点数 对整个字符串或者字符串的其中一部分执行操作;对整数和浮点数执行自增(increment)或者自减(decrement)操作
LIST 一个链表,链表上的每个节点都包含了一个字符串 从链表的两端推入或者弹出元素;根据偏移量对链表进行修剪(trim);读取单个或者多个元素;根据值查找或者移除元素
SET 包含字符串的无序收集器(unordered collection),并且被包含的每个字符串都是独一无二、各不相同的 添加、获取、移除单个元素;检查一个元素是否存在于集合中;计算交集、并集、差集;从集合里面随机获取元素
HASH 包含键值对的无序散列表 添加、获取、移除单个键值对;获取所有键值对
ZSET 字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定 添加、获取、删除单个元素;根据分值范围(range)或者成员来获取元素
  • String
    • get
    • set
    • del
  • list
    • rpush
    • lrange
    • lindex
    • lpop
  • set
    • SADD
    • SMEMBERS
    • SISMEMBERS
    • SREM
    • 比如SINTER、SUNION、SDIFF这3个命令就可以分别执行常见的交集计算、并集计算和差集计算
  • Hash
    • HSET
    • HGET
    • HGETALL
    • HDELL
  • ZSET
    • ZADD
    • ZRANGE
    • ZRANGESCORE
    • ZREM

4.其他管理命令

  • 基数统计:Redis HyperLogLog 是用来做基数统计的

5.Redis事务

  • Redis事务允许一组命令在单一步骤中执行

  • 事务有两个属性

    • 在一个事务中的所有命令作为单个独立的操作顺序执行,在Redis事务中的执行过程中而另一客户机发出的请求,这是不可以的
    • Redis事务是原子的,原子意味着要么所有的命令都执行,要么都不执行

6.Redis分区

  • 分区是将数据分割成多个 Redis 实例,使每个实例将只包含键子集的过程

  • 分区的好处

    • 它允许更大的数据库,使用多台计算机的内存总和。如果不分区,只是一台计算机有限的内存可以支持的数据存储
    • 它允许按比例在多内核和多个计算机计算,以及网络带宽向多台计算机和网络适配器
  • 分区的劣势

    • 涉及多个键的操作通常不支持。例如,如果它们被存储在被映射到不同的 Redis 实例键,则不能在两个集合之间执行交集
    • 涉及多个键时,Redis事务无法使用
    • 分区粒度是一个键,所以它不可能使用一个键和一个非常大的有序集合分享一个数据集
    • 当使用分区,数据处理比较复杂,比如要处理多个RDB/AOF文件,使数据备份需要从多个实例和主机聚集持久性文件
    • 添加和删除的容量可能会很复杂。例如Redis的Cluster支持数据在运行时添加和删除节点是透明平衡的,但其他系统,如客户端的分区和代理服务器不支持此功能

MongoDB

1.简介

  • MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统
  • 在高负载的情况下,添加更多的节点,可以保证服务器性能
  • MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案
  • MongoDB 将数据存储为一个文档,数据结构由键值(key value)对组成
  • MongoDB 文档类似于 JSON 对象(bson)
  • 字段值可以包含其他文档,数组及文档数组

2.主要特点

  • 面向集合存储,易存储对象类型的数据
  • 模式自由
  • 支持动态查询
  • 支持完全索引,包含内部对象
  • 支持查询
  • 支持复制和故障恢复
  • 使用高效的二进制数据存储,包括大型对象(如视频)
  • 自动处理碎片,以支持云计算层次的扩展性
  • 支持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言
  • 文件存储格式为BSON(一种JSON的扩展)
  • 可通过网络访问

3.适用场景

  • 网站数据

    • Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性
  • 缓存

    • 由于性能很高,Mongo 也适合作为信息基础设施的缓存层
    • 在系统重启之后,由Mongo 搭建的持久化缓存层可以避免下层的数据源过载
  • 大尺寸、低价值的数据

    • 使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储
  • 高伸缩性的场景

    • Mongo 非常适合由数十或数百台服务器组成的数据库,Mongo 的路线图中已经包含对MapReduce 引擎的内置支持
  • 用于对象及JSON 数据的存储

    • Mongo 的BSON 数据格式非常适合文档化格式的存储及查询
  • 高度事务性的系统

    • 如银行或会计系统
    • 传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序
  • 传统的商业智能应用

    • 针对特定问题的BI 数据库会产生高度优化的查询方式
    • 数据仓库可能是更合适的选择
  • 需要SQL 的问题

4.Mongodb术语

  • Mongodb中基本的概念是文档、集合、数据库
SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键
  • 下表列出了 RDBMS 与 MongoDB 对应的术语:

    RDBMS MongoDB
    数据库 数据库
    表格 集合
    文档
    字段
    表联合 嵌入文档
    主键 主键 (MongoDB 提供了 key 为 _id )
    数据库服务和客户端
    Mysqld/Oracle mongod
    mysql/sqlplus mongo

5.Mongodb操作

  • insert:单条和批量

  • Find:

    • gt"(greater than), "gte”, “lt","lt", "lte”, “$ne”, “没有特殊关键字”
    • “无关键字“, “or","or", "in”,”$nin" 同样我也是举几个例子
    • 在mongodb中还有一个特殊的匹配,那就是“正则表达式”,这玩意威力很强的。
    • 有时查询很复杂,很蛋疼,不过没关系,mongodb给我们祭出了大招,它就是where,为什么这么说,是因为where中的value
  • Update:

    • 整体更新
    • 局部更新:inc,inc,set
    • upsert
    • 批量更新
  • Remove

  • 聚合

    • count

    • distinct

    • group

      • key:  这个就是分组的key,我们这里是对年龄分组

      • initial: 每组都分享一个”初始化函数“,特别注意:是每一组,比如这个的age=20的value的list分享一个initial函数,age=22同样也分享一个initial函数。

      • $reduce: 这个函数的第一个参数是当前的文档对象,第二个参数是上一次function操作的累计对象,第一次

        为initial中的{”perosn“:[]}。有多少个文档, $reduce就会调用多少次。

      • condition:  这个就是过滤条件。

      • finalize:这是个函数,每一组文档执行完后,多会触发此方法,那么在每组集合里面加上count也就是它的活了。

    • ​ mapReduce

      这玩意算是聚合函数中最复杂的了,不过复杂也好,越复杂就越灵活。

      mapReduce其实是一种编程模型,用在分布式计算中,其中有一个“map”函数,一个”reduce“函数。

      ① map:

      这个称为映射函数,里面会调用emit(key,value),集合会按照你指定的key进行映射分组。

      ② reduce:

      这个称为简化函数,会对map分组后的数据进行分组简化,注意:在reduce(key,value)中的key就是

      emit中的key,vlaue为emit分组后的emit(value)的集合,这里也就是很多{“count”:1}的数组。

      ③ mapReduce:

6.复制与备份

7.分片

  • Shard

    • 用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个relica set承担,防止主机单点故障
  • Config Server

    • mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息
  • Query Routers

    • 前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用

8.案例

  • 用电信息采集
    • 用电信息采集系统中采集终端上传用电信息至前置通信平台,前置通信平台负责将原始数据帧最终转换为存入应用系统生产数据库和分析数据库的业务数据
    • 启动
      • 当数据采集服务和数据处理单元启动时,从前置通信平台关系数据库加载档案数据,用于数据帧解析和原始数据转存
      • 每隔15分钟同步更新一次
    • 策略:
      • 数据采集服务首先对原始数据进行本地缓存,然后再将文件上传至MongoDB私有云,而没有把原始数据直接以键值对形式写入MongoDB私有云
      • 一方面可以有效的保证原始数据的安全性,在很大程度上避免因网络中断,机房断电等异常造成的数据丢失
      • 另一方面,缓存后的文件写入MongoDB,与键值对写入MongoDB相比,前者速度快的多,能更好适应高速采集数据流的大数据处理
      • 利用多台服务器以MongoDB为基础构建了原始采集数据的云存储架构
      • 通过复制集的应用,利用多台机器之间的异步复制达到故障转移和冗余。每三个Mongo服务构成一组复制集,彼此相互进行“心跳”检测,实现数据的高可用性
      • 海量数据的读写分离:通过云存储技术的使用,结合复制集技术的应用,复制的数据库能很好的适用于读扩展
      • 可以将查询路由到更多的副本上,这样查询就会发送到从节点上执行,从而实现将“读写请求”按实际负载情况进行均衡分布的效果、增大吞吐量
      • 海量数据的均衡分布: 众多服务器构建的私有云利用自动分片机制,各数据片段均衡写入到各工作节点的存储系统中
      • 对均衡策略进行了优化,通过路由mongos获取分片所在节点负载,在迁移源分片与目标分片选取等环节加入负载因素的考虑,从数据量和负载两方面实现均衡
    • 人社大数据平台

Neo4j

1.简介

  • Neo4j 是一个高性能的 NoSQL 图形数据库
  • Neo4j 使用图(graph)相关的概念来描述数据模型,把数据保存为图中的节点以及节点之间的关系
  • https://neo4j.com/

2.概念

  • Neo4j 中两个最基本的概念是节点和边

    • 节点表示实体,边则表示实体之间的关系
    • 节点和边都可以有自己的属性
    • 不同实体通过各种不同的关系关联起来,形成复杂的对象图
  • Neo4j 提供了在对象图上进行查找和遍历的功能

    • 深度搜索
    • 广度搜索

3.特点

  • 完整的ACID支持
  • 高可用性
  • 轻易扩展到上亿级别的节点和关系
  • 通过遍历工具高速检索数据

4.例子

  • 社交网络
  • 文件系统

总结比较结果

我在知乎上简答了一下传送门

  • HbaseMongoDBRedis都属于nosql型存储方案。在实际的项目实践上看,他们的系统存储及处理的数量由大到小。
  • HBase基于列存储,提供<key, family:qualifier, timestamp>三项坐标方式定位数据,由于其qualifier的动态可扩展型(无需schema设计,可存储任意多的qualifier),特别适合存储稀疏表结构的数据(比如互联网网页类)。HBase不支持二级索引,读取数据方面只支持通过key或者key范围读取,或者全表扫描。
  • MongoDb在类SQL语句操作方面目前比HBase具备更多一些优势,有二级索引,支持相比于HBase更复杂的集合查找等。BSON的数据结构使得处理文档型数据更为直接。MongoDb也支持mapreduce,但由于HBase跟Hadoop的结合更为紧密,Mongo在数据分片等mapreduce必须的属性上不如HBase这么直接,需要额外处理。
  • HBase与Mongodb的读写性能正好相反,HBase写优于随机读,MongoDB似乎写性能不如读性能。
  • Redis为内存型KV系统,处理的数据量要小于HBase与MongoDB
分类 Example 典型应用场景 数据模型 优点 缺点
键值(key-value) Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB 内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。 Key 指向 Value 的键值对,通常用hash table来实现 查找速度快 数据无结构化,通常只被当作字符串或者二进制数据
列存储数据库 Cassandra, HBase, Riak 分布式的文件系统 以列簇式存储,将同一列数据存在一起 查找速度快,可扩展性强,更容易进行分布式扩展 功能相对局限
文档型数据库 CouchDB, MongoDb Web应用(与Key-Value类似,Value是结构化的,不同的是数据库能够了解Value的内容) Key-Value对应的键值对,Value为结构化数据 数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构 查询性能不高,而且缺乏统一的查询语法
图形(Graph)数据库 Neo4J, InfoGrid, Infinite Graph 社交网络,推荐系统等,专注于构建关系图谱 图结构 利用图结构相关算法。比如最短路径寻址,N度关系查找等 很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案