大数据存储系统

18 阅读7分钟

分布式系统基本概念

分布式系统类型

  • Client / Server

    • 客户端发送请求,服务器完成操作,发回响应
  • P2P (Peer‐to‐peer)

    • 分布式系统中每个节点都执行相似的功能
    • 整个系统功能完全是分布式完成的
    • 没有中心控制节点
  • Master / workers

    • 有一个/一组节点为主,进行中心控制协调
    • 其它多个节点为workers,完成具体工作

故障类型

  • Fail stop

    • 当出现故障时,进程停止/崩溃
  • Fail slow

    • 当出现故障时,运行速度变得很慢
  • Byzantine failure

    • 包含恶意攻击

CAP

一致性、可用性、分区容错性三者不可兼容

分布式文件系统

  • 本地文件系统 (Local File System)

    • Linux ext4, Windows ntfs, Mac OS hfs
  • NFS:Sun’s Network File System,client/server架构

    • Stateless:server无状态,故障重启即可

    • Idempotent:操作幂等性,Client无响应,重试即可

    • Client cache:缓存读写的数据,避免远程操作

      • 一致性问题:写回,写操作关闭时,将写同步到server

      • 其他已缓存的怎么知道缓存是否过期?每次使用缓存,发送GETATTR请求,验证缓存是否过期

        • 但是效率很低
  • AFS (Andrew File System)

    • 解决cache过期问题:Client 获得一个文件时,在server上登记,当server发现文件修改时,向已登记的client发一个callback,Client收到callback删除缓存的文件

    • 其他区别:

      • AFS缓存整个文件,NFS数据页为单位
      • AFS缓存在本地硬盘中,NFS的缓存是在内存中的
      • AFS open: 将把整个文件从Server读到Client
      • 有统一的名字空间,而NFS可以mount到任何地方

Google File System和HDFS

  • GFS/HDFS:Google File System 、Hadoop Distributed File System

    • Client/server架构
    • 主要功能:大块数据顺序读写、并行追加
    • 不支持:修改文件

  • 文件切分成定长的数据块(默认为64MB大小的数据块)

  • 每个数据块独立地分布存储在Data Node上

  • 默认每个数据块存储3份,在3个不同的data node上

  • open:与Name Node通信一次

  • read:直接与Data Node通信,从多个副本中选择最佳的Data Node读取数据,支持多副本并行读取

  • write:3个副本:本机、本机柜、其它机柜

    • 数据发送到Datanode,形成pipeline传递副本数据
    • 不支持并发写
    • 支持并行的append

Key‐Value Store

  • Dynamo: 由Amazon公司研发

    • p2p架构:多个nodes互连形成环形分布式系统

    • token= hash(key),每个node设置存储的token区间,实现横向扩展

    • 故障迁移:类似一致性哈希,移交到下一个顺序的节点

    • 数据备份:顺位备份两个副本

    • 读写强一致性:Quorum (N, W, R)

      • 满足R+W>N,容错W-1
    • 不支持事务

  • Bigtable / HBase: Bigtable起源于Google公司, Hbase是开源实现

    • Master/server架构,底层使用HDFS存储ssTable

    • 表的组成:Row key、Column Family、Column Key

    • 存储:按row key顺序,列式存储

    • Hbase操作:

      • create 'mytable', 'mycf’
        put 'mytable', 'abc', 'mycf:a', '123'
        scan 'mytable'
        
    • 索引结构:LSM-Tree

      • 由多层组成,大小指数级增长

      • 每层都是一个有序索引,例如B+树

      • 都是对磁盘的顺序写,利用bloom filter 快速判断当前层有没有数据

  • Cassandra:由Facebook研发,后成为Apache开源项目

  • RocksDB: 由Facebook研发,是在Google LevelDB基础上形成的

Distributed Coordination: ZooKeeper

  • 分布式问题:选主、节点状态、一致性共识

  • ZooKeeper:维护一组共同的数据状态

    • 数据模型:Data Tree

      • Name: 一个Znode可以用一条从根开始的路径唯一确定,如/c/f
      • Data: 可以存储任意数据,但长度不超过1MB
      • Version:版本号
      • Regular/Ephemeral:正常的/临时的
    • API:

      • 创建Znode/删除Znode/判断Znode存在
      • 读Znode数据/修改Znode数据
      • 找孩子Znode
    • Watch机制

      • exists(path, watch),当Znode被删除/新建时,收到通知
    • Linearizable writes:写可串行化,因为Leader复制数据到Follower

    • FIFO client order,不同Client之间的读写顺序没有任何保证

  • ZAB

    • 两个主要工作模式

      • Broadcast: Leader向Follower广播新的写操作

        • 2PC:

          • Propose阶段:Leader把一个新的txn写入本地log, 广播Propose这个txn,每个Follower收到Propose后,写入本地log,向Leader发回Ack
          • Commit阶段: Leader收到 f个Ack后,写Commit到log, 广播Commit,然后修改自己的ZooKeeper树。 Follower收到Commit消息,写Commit到log,然后修改ZooKeeper树
      • Recovery:竞争新的Leader,新的Leader进行恢复

        • 每个节点选择Leader为看到max(TxnID)为最大的节点
  • 应用:

    • 配置信息

      • 把配置信息存储在一个确定路径的Znode中
      • 利用Watch机制获得配置信息的变化
    • 成员管理

      • 用一个Znode代表节点组,每个成员都在group下面创建一个ephemeral 的孩子
      • 当某个成员崩溃了,那么它对应的孩子就被删除
    • 分布式锁

      • 可以把lock对应为一个Znode
      • 加锁=创建Znode,解锁=删除Znode
      • 加锁不成功,可以用watch,当Znode被删除时,可以得到通知

Document Store

树状结构数据模型

  • JSON

    • 数据类型:string, number, true/false, null、Object{k:v}、Array[]
  • Google Protocol Buffers: Google推出,最初用于实现网络协议

    • 数据格式要提前声明,树形的

MongoDB

JSON是基本数据类型,存储为BSON二进制表示

组成:

  • Database:关系型中的数据库概念
  • Collection:关系型中的table概念
  • Document:关系型中的记录概念

API and Query Model

-- 创建表 和 插入数据
db.student.insert({ 
    student_id : 131234,  
    name : “张飞”,  
    major : “计算机”,  
    year: 2013 
})
-- 查询数据
db.student.find( 
    { major : “计算机” }, 
    {name : 1, year:1, _id:0} 
)
-- where + group by
db.student.aggregate( [ 
    {$match : { major : “计算机” }}, 
    {$group : { _id:{year: “$year”}, 
    cnt: {$sum: 1}}  
])

架构:

  • 单机

  • Sharding 垂直分片

  • Write Concern:什么时候认为写完成

    • Unacknowledged: 写请求发送了,就认为完成
    • Acknowledged:MongoDB应答了收到写请求,就认为完成
    • Journaled:MongoDB把写请求记录在硬盘上的日志中,认为完成

图存储系统(Graph Database)

图数据模型

  • G=(V, E)

    • V:顶点(Vertex)的集合
    • E:边(Edge)的集合
  • 图数据存储系统:存储图顶点和边,提供顶点和边的查询,类似OLTP

  • 图运算系统:以图为基础运行大规模算法,类似OLAP

Neo4j

  • 文件存储:

    • 顶点、边、属性:分别存储所有node, relationship, property的文件,unique id标识
    • Relationship:同一个node的relationship形成一个双向链表
    • Property:同一个node/relationship的property形成一个单向链表
  • Node/Rel cache:对node, relationship, property缓冲

  • Traversal:遍历操作

  • Cypher:图数据库查询语言

-- node
(nodename:type, {property_key:value, key:value})
(张飞) 
(张飞:Student) 
(张飞:Student,{name:“张飞”,major : “计算机”, year: 2013}) 
(体系结构:Course,{name:“体系结构”})

-- Relationship
‐ [name:type, {property_key:value, key:value}] ‐ >
‐[:Takecourse]‐ > 
‐[:Takecourse,{year:2014, grade:85}]‐ >

-- Create
CREATE (张飞:Student,{name:“张飞”, major : “计算机”, year: 2013})
CREATE (体系结构:Course,{name:“体系结构”})
CREATE (张飞) ‐[:Takecourse,{year:2014, grade:85}]‐>(体系结构)

-- Match
-- 找具有name:”张飞”属性的顶点
MATCH (x {name:”张飞”}) RETURN x
-- 找到所有选修体系结构课程的学生顶点
MATCH (x:Student)‐[:Takecourse]‐>(:Course {name:”体系结构”}) RETURN x 
-- 找到既选修体系结构又选修数据库的顶点
MATCH ({name:”数据库”})<‐[:Takecourse]‐(x)‐[:Takecourse]‐>({name:”体系结构”}) RETURN x 
-- 找到所有选修体系结构课程的学生顶点,要求学生是2013年入学的 
MATCH (x:Student)‐[:Takecourse]‐>(:Course {name:”体系结构”}) 
WHERE x.year=2013 
RETURN x 
-- 找到所有选修体系结构课程的学生顶点, 要求学生没有选修过操作系统
MATCH (x:Student)‐[:Takecourse]‐>(:Course {name:”体系结构”}) 
WHERE NOT (x)‐[:Takecourse]‐>(:Course {name:”操作系统”}) 
RETURN x 
-- 有路径从ab
(a)‐[*]‐>(b)
-- 有路径从ab,路径最短3步,最长5 步
(a)‐[*3..5]‐>(b)
  • HA: 多副本机制

    • 主副本把transaction log发送到从副本
    • 从副本replay log从而执行同样的操作

JanusGraph:一个分布式图数据库

  • Gremlin查询语言

RDF和Sparql

  • RDF(Resource Description Framework)

    • 每个RDF记录是三元组(subject 主, predicate 谓, object 宾)
  • SPARQL(读作sparkle):RDF的查询语言

多模数据库系统(Multi‐Model DB)