现代数据库及大数据管理—必备知识点总结

1. 现代数据管理概述

1.1. 现代数据管理的特征

数据的组织: 结构化、半结构化、非结构化
内容及其处理:文本、图像、音频、视频
存取:海量
使用:基于语义
运行环境及其管理:面向网络

1.2. 数据管理新技术VS数据库

  1. 数据形式:
    新技术:多结构、多模态、多种内容
    数据库:结构化为主、擅长处理文本 数字 日期等程序可直接识别和运算的符号数据
  2. 查询需求:
    新技术:文字匹配、基于语义、相似性匹配 排序、聚类 分类 去兀余
    数据库方式:基于关键字 值匹配、精确匹配 排序 近邻计算、存在性查询 等值查询 范围查询
  3. 应用和运行环境:
    新技术:和网络(尤其是语义网)结合更加密切、更加直接——web应用集成、爬虫、网络数据 知识
    数据库:信息规范,手工录入、批量导入
  4. 处理的业务需求
    新技术:面向海量数据(TB PB)、查询为主 更新为辅、数据一致性可弱化
    数据库:面向企业级数据库、CURD(create update read delete)、ACID(事务)特性受到保障
  5. 关键技术
    新技术: 海量数据的分布式存储、分布式并行处理
    相似性度量
    高维数据处理
    语义特征获取
    语义知识的组织与映射
    模型的提出与训练
    查询扩展与反馈
    可视化
    数据库:
    数据字典
    关系代数理论的实现技术
    索引技术
    多维数据查询
    面向关系代数和物理开销评估的查询优化
    系统保护(并发、恢复、完整性控制、安全性控制)
    6.系统开放性
    新技术:分布式、易扩充、低成本、新编程模型
    数据库:服务器模式、异构集成、中间件、服务器接口(ODBC、API)

1.3. 大数据的4V

  1. Volume: 数据体量巨大
  2. Variety:数据类型繁多
  3. Velocity:处理速度快
  4. Value:价值密度低

1.4. 知识库与传统搜索对比

  1. 结果的正确与全面:关键词的多重含义,展示给用户全面的信息
  2. 最好的总结:总结出相关的内容和主题
  3. 更深更广:给出完整知识体系

1.5. 大数据领域开源技术

  1. Hadoop:开源的分布式计算框架
  2. R Language:专门为数据统计和数据可视化设计的编程语言
  3. Cascading:针对Java开发的应用框架,以屏蔽MapReduce的复杂性,提供替代API
  4. Scribe:日志汇聚服务器软件
  5. Elasticsearch:开源的分布式搜索服务器
  6. Hbase:非关系型分布式数据库
  7. Cassandra:NoSQL数据库,已被HBase取代
  8. MongoDB:分布式文件存储数据库,JSON文档式NoSQL数据库
  9. CouchDB:JSON文档式NoSQL数据库,使用JavaScript作为查询语言,集成了MapReduce技术。
  10. Spark:分布式内存快速通用计算引擎
  11. Neo4j:NoSQL图数据库。

1.6. Neo4j存在的问题:

  1. 插入速度慢
  2. 超大节点:操作速度将明显下降
  3. 适合处理图中的关系:结点的属性没有明显优势
  4. 内存的优化机制

1.7. NoSQL与关系型数据库对比

  1. 存储形式:
    NoSQL:键值、文档、列存储、图数据库、XML数据库等
    关系型: 格式化(表)
  2. 新的应用需求:
    高性能——高并发读写
    海量存储——对海量数据的高效率存储和访问的需求
    低成本的高扩展性和高可用性
    简单访问任务
  3. SQL数据库的主要特性vs新需求:
    事务一致性:很多web系统并不要求,成为了高负载情景下一个沉重负担
    写实时性和读实时性:大部分不要求
    复杂的SQL查询(多表关联):主动避免
  4. NoSQL的优势:
    数据存储不需要固定的表结构
    通常也不执行连接操作
    系统可建立在PC集群之上

2. 第二章 多结构化数据管理

2.1. Memcached

memcached是一个高性能的分布式内存对象缓存系统,用于动态web应用以减轻数据库负载。

2.1.1. 基本特征

  1. 在内存中缓存数据和对象,为动态、数据库驱动网站提供更快的运行速度。减少读取数据库的次数,避免使用数据库应对高并发访问时磁盘开销和阻塞的发生。
  2. 使用LRU替换策略
  3. 分布式缓存,不同主机上的多个用户可同时访问, 解决了单机应用的局限。
  4. 使用自己的页块分配器
  5. 使用基于存储“键-值”对的hashmap哈希表
  6. 虚拟内存不会产生碎片,虚拟内存分配的时间复杂度可以保证为O(1)
  7. 通过在内存中维护一个统一的巨大的hash表,Memcached能过用来存储各种格式(图像、视频以及数据库检索结果)的数据
  8. 具有守护进程(daemon),采用C语言开发
  9. 客户端通过memcached协议与守护进程通信,可以用各种语言来编写
  10. 使用libevent(linux下用epoll)来均衡任何数量的打开链接
  11. 使用非阻塞的网络I/O,对内部对象使用引用计数
  12. 不提供兀余(如复制hashmap条目),当某个服务器S停止运行或崩溃,所用该服务器上的键值对都将丢失

2.1.2. 程序流程

  1. 搜索缓存中的键值对;
  2. 若键值对不在缓存中则执行SQL,并设置缓存对象

2.1.3. Memcached的分布式

尽管是“分布式”缓存服务器。但是服务器端没有分布式功能,各个memecached之间不会相互通信以共享信息,如何进行分布式?取决于客户端的实现。

2.1.4. 关于服务端的libevent

Mmcached采用的多线程模型:
主线程(main thread,单一)
工作线程(work thread,多个)

使用libevent作为底层的网络处理组件。

libevent:一个异步事件处理程序库,将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一接口。使用双向链表保存所有注册的I/O和Signal事件,采用min_heap来管理timeout事件。主循环函数不断检测注册事件,如果有事件发生,则将其放入就绪链表,并调用事件的回调函数,完成业务逻辑处理。

2.1.5. Memecached内存分配——Slab Allocator

早期的Memcached内存分配通过对所有记录进行malloc和free来进行。
(1)容易产生内存碎片;
(2)加重操作系统内存管理器的负担。
改进措施:默认采用Slab Allocator机制分配、管理内存。

Slab Allocator基本原理:

Chunk——按照预先规定的大小,将分配的内存分割成各种特定长度的块。
slab class——尺寸相同的块分成组(chunk的集合)。
分配到的内存不会释放,重复使用已分配的内存。只在get时查看记录的时间戳是否过期。

替换策略

(1)优先使用已超时的记录空间
(2)如果还存在追加记录时空间不足的情况,使用最近最少使用(LRU)机制替换已有缓存内容(引用计数非零则不替换)

2.2. DynamoDB

2.2.1. 设计理念

(1)高扩展性
(2)简单的key-value存储查询
(3)高可用,提供“always on”的服务
(4)服务器级别的协议保证

2.2.2. 设计思想

  1. 为了达到高可用,牺牲一致性;
  2. 在读数据的时候处理数据不一致的冲突;
  3. 根据应用层的不同需求,指定不同的NRW值,协调可用性和一致性;
  4. 去中心化的维护整个集群的成员及故障信息,采用Gossip同步。

2.2.3. 技术特征

  1. 一致性hash + 虚拟节点
  2. 支持数据的多副本写操作
  3. 节点成员关系和失效检测

2.2.4. 读写过程

客户端请求最终交给preference list中的一个节点处理,该节点称为coodinator 。Dynamo采用类似Quarum的方式保证数据正确,即W+R>N。
Put流程:
(1)coodinator生成新的数据版本,及vector clock分量 ;
(2)本地保存新数据 ;
(3)向preference list中的所有节点发送写入请求 ;
(4)收到W-1个确认后向用户返回成功 。
Get流程 :
(1)coodinator向preference list中所有节点请求数据版本 ;
(2)等到R-1个答复
(3)coodinator通过vector clock处理有因果关系的数据版本 ;
(4)将不相容的所有数据版本返回用户。

2.2.5. 节点临时失效处理

Hinted Handoff(暗示接力)技术:

  1. 为了保证每次都能写到W个副本,读到R个副本,每次读和写都是发送给N个节点。如果这N个节点有节点失效,则往后继续找一个不同的节点,暂时代替失效的节点。
  2. 该后续节点定期监测故障节点的恢复,
  3. 发现故障节点恢复时,将暂时代为保管的数据写回复活节点。

例:N=3,某数据的preference list是节点A、B、C。若A节点失效,则对该数据的写请求将发送到节点B、C、D上。
D暂时取代A的角色,原本应该写到A上的数据存放到D的一个特定的文件夹(意味着这些数据不是D本该拥有的,而是其它节点的)。
D上会启动一个线程定期检查A的状态,当发现A恢复后,就将D上存放的这些A的数据写回到A。
该策略保证了节点失效时系统的高可用和数据持久性。

2.2.6. 成员信息及故障检测

默认观点:节点失败无法恢复的情况并不常见,加入或离开集群都需要手动通过命令完成。

Dynamo集群中的每个节点都会维护当前集群的成员及节点不可达等信息,这些信息通过Gossip协议传播到整个集群;客户端可以通过任意一个节点获得并维护这些成员信息,从而找到自己要访问的数据。

Dynamo使用一个基于Gossip的协议传播成员变动,并维持成员的最终一致性:每个节点每隔一秒随机选择另一个节点,两个节点协调他们保存的成员变动历史。
新节点加入时选择自己负责的虚拟节点,并将其虚拟节点表保存到磁盘,之后与其他的节点通过Gossip协议交换协调他们的虚拟节点表。

每个节点都知道全局的虚拟节点表。

**逻辑分裂错误:**如果A节点和B节点同时加入到集群,根据上述基于Gossip协议的加入机制,A和B会互相不知道对方的存在,这种错误称为逻辑分裂。

外部发现(种子节点避免逻辑分裂):
Dynamo中有一些种子节点,每个节点都知道种子节点,每个节点都与种子节点进行虚拟节点表的协调,从而避免了逻辑分裂错误。
种子的发现(discovered)是通过外部机制来实现的

2.3. Redis

Redis是一个开源的key-value存储系统,将大部分数据存储在内存中,使用C语言开发。

2.3.1. 数据类型

Redis内部使用一个redisObject对象来表示所有的key和value,与Memcached仅支持简单的key-value结构的数据记录不同,value支持五种数据类型及其相关操作:
字符串——String
哈希表——Hash(实现:数据较少时使用zipmap 一种一维数组,增大时转换为ht 真正的HashMap)
链表——List(实现:双向链表)
集合——Set(可以自动去重 ,实现:value永远为null的HashMap,通过计算hash来排重、判断存在)
有序集合——Sorted Set(实现:采用HashMap和跳跃表 SkipList来保证数据的存储和有序,HashMap记录成员到score的映射,跳跃表实现排序,HashMap里存的score作为排序依据。)

2.3.2. Skip List(跳跃列表)

Skip List:一种随机化的数据结构,基于并联的链表,其效率相当于二叉查找树(对于大多数操作需要O(log n)平均时间)。

Skip List基本思想:有序的链表加上附加的前进链接。

一个跳表的结构特征:
(1)一个跳表由多个层(level)组成;
(2)每一层都是一个有序的链表;
(3)第1层包含所有的元素;
(4)如果元素x出现在第i层,则所有比i小的层都包含x;
(5)第i层的元素通过一个down指针指向下一层拥有相同值的元素;
(6)在每一层中都包含-1和1两个元素,分别表示INT_MIN和INT_MAX;
(7)Top指针指向最高层的第一个元素。

跳跃列表的增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表(因此得名)。

跳表的插入需要三个步骤:
(1)查找到在每层待插入位置;
(2)随机产生一个层数;
(3)从高层至下插入,插入时算法和普通链表的插入完全相同。

删除节点操作和插入类似,找到每层需要删除的位置,之后删除操作和普通链表一样。
注:如果该节点的level是最大的,则需更新跳表的level。

跳表的优点就是查找比普通链表快。

Skip List所有操作都以对数随机化的时间进行,较好的解决了有序链表查找特定值的困难。

2.3.3. Redis内存管理

Redis通过定义一个数组zmalloc_allocations[]来记录所有的内存分配情况。
这个数组的长度为ZMALLOC_MAX_ALLOC_STAT。
数组的每一个元素代表相应大小内存块被分配的个数(内存块的大小为该元素的下标),例如:zmalloc_allocations[16]代表已经分配的长度为16bytes的内存块的个数。

有一个静态变量 used_memory记录当前分配内存的总和。

2.3.4. 持久化

Redis虽然是基于内存的存储系统,同时也提供内存数据持久化的机制,有两种持久化策略:

1)RDB快照:将当前数据的快照存成一个数据文件,从而持久化。
RDB的实现借助了fork命令的copy on write机制。在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有的数据,将数据写成为RDB文件。

可靠性:当生成一个新的RDB文件时,Redis生成的子进程先将数据写到一个临时文件中,然后通过原子性系统调用rename将临时文件重命名为RDB文件,这样在任何时候出现故障,RDB快照文件总是可用的。
生成时机:可以通过save指令配置RDB快照生成的时机(例如当10分钟以内有100次写入就生成快照,或者1小时内有1000次写入就生成快照,或者多个规则一起实施)。
可用性:开启RDB的代价不高,但是RDB文件中的数据并不是全新的,从上次RDB文件生成到Redis停机这段时间的数据将丢失。

2)AOF日志(Append Only File):一个追加写入的日志文件,与一般数据库的bin log不同,AOF文件是可识别的纯文本,内容是一个个导致数据变化的Redis标准命令。生成过程类似于RDB。

优化策略:AOF文件会越来越大,所以Redis提供了AOF rewrite功能,就是重新生成一份AOF文件,文件中一条记录的操作只会有一次,去掉之前叠加的操作。

2.3.5. 分布式存储

  1. Redis Cluster采用了P2P机制,没有Proxy层,客户端将key的请求转发给合适的nodes。
  2. Client保存集群中nodes与keys的映射关系(slots),并保持此数据的更新,所以通常Client能将请求直接发送给正确的nodes。
  3. Clients与每个nodes保持链接,所以请求延迟等同于单个节点,不会因为Cluster的规模增大而受到影响。
  4. 由于没有Proxy层,Client请求的数据无法在nodes间merge。
  5. Redis核心面向K-V数据存储,没有scan类型(sort,limit,group by)的操作。

Redis槽(slot):集群将key分成16384个slots(hash 槽),slot作为数据映射的单位。
Keys到slot的映射:
HASH_SLOT = CRC16(key) mod 16384。其中CRC16是一种冗余码校验和,将字符串转换成16位的数字。

每个节点持有16384个slots中的一部分。

Redis Cluster最多支持16384个nodes(每个nodes持有一个slot)。

Redis集群中的各个节点通过Gossip协议来交换各自关于不同节点的状态信息,协议由三种消息实现:
MEET(握手)、
PING、
PONG(Ping的回应)。

每次发送MEET、PING、PONG消息时,发送者都从自己的已知节点列表中随机选出两个节点的信息(可以是主节点或者从节点) 保存到两个clusterMsgDataGossip结构中。

接收者收到消息时会访问消息正文中的两个结构,并根据自己是否认识结构中记录的被选中节点进行操作:
1)若发来的节点不在接收者的已知节点列表 → 接收者第一次接触到该节点,接收者将根据结构中记录的IP地址和端口号等信息与该节点进行握手(MEET)。
2)若发来的节点已经存在于接收者的已知节点列表 → 接收者之前已经与该节点接触过,接收者将根据结构记录的信息对该节点对应的clusterNode结构进行更新。

2.3.6. 复制机制

为了保证单点故障下的数据可用性,Redis Cluster引入了Master节点和Slave节点:每个Master节点有两个用于冗余的Slave节点。 → 集群中任意两个节点宕机都不会导致数据不可用。若Master节点退出,集群会自动选择一个Slave节点成为新的Master节点。

2.3.7. NWR理论

NWR理论(WernerVogels在讲“EventuallyConsistent”时提出)。设一个存储系统有如下属性:
N=每个数据的副本数
W=每次写操作时,必须同步确认写成功的副本数
R=每次读操作时,需要读取的副本数
则当W+R>N时,该存储系统可以提供强一致性。
强一致性等价于R中至少包含一个最新的副本,即(R-(N-W))>0,即W+R>N。

2.4. 基于分布式缓存的图处理系统:Trinity

微软的图处理引擎,基于分布式内存的云系统,能够有效支持针对web规模图数据的在线和离线处理任务。

在分布式缓存的基础上实现了对图数据的全局寻址,可有效支持随机存取。

默认前提条件:内存成本足够低、网络速度足够高。

2.4.1. 构成

Slave节点:存储一部分图数据,执行图计算任务。图计算任务包括向其他各类节点收发消息。
Proxy节点:系统中的可选节点,不包含数据,只处理消息。作为client和slave节点的中间层,也用作消息聚集节点,可汇总来自多个slave的消息。
Client节点:用户接口层,通过API和slave以及proxy节点通讯。

2.4.2. 分布式缓存

数据空间的划分:分为2^p个内存块(trunk),分布于m个节点上( 2^p >m),通常一个节点容纳多个trunk。

分解成多个trunk的原因:
1)多个trunk有利于并发;
2)维持一个大型的哈希表将导致哈希冲突的概率增加。

底层存储:为保证容错一致性,这些trunk底层上采用TFS(Trinity File System)分布式文件系统存储,类似HDFS

2.5. 分布式全网存储和检索——kad

Kademlia(简称Kad),一种典型的结构化P2P覆盖网络(应用层网络)。
信息的存储:以哈希表条目形式分散存储在各节点上。

全网构成一张巨大的分布式哈希表

检索:通过Kademlia协议查询key值对应的value(不必关心value所在节点位置)。
应用:eMule、BitTorrent等P2P文件交换系统的检索协议。

2.5.1. Kad存储

网络集群存储、维护两张分布式哈希表:关键词字典、文件索引字典。

关键词字典:关键词→其所对应的文件名称及相关信息,key=关键词字符串的160比特SHA1散列,value为一个三元组列表 (文件名,文件长度,文件的SHA1校验值) 。
文件索引字典:文件信息→文件的拥有者(下载服务提供者),key=文件的SHA1校验值,value也是一个三元组列表 (拥有者IP,下载侦听端口,拥有者节点ID)。

存储和交换无需集中索引服务器参与优势:

1)提高了查询效率
2)提高了文件交换系统的可靠性。

2.5.2. Kad网络节点ID和距离

每一个节点有一个专属ID(一个160bit的整数),由节点自己随机生成(可以认为ID具有唯一性)。

距离为两个ID的二进制异或值。
两个节点的ID分别为a与b,则有:
distance=a XOR b。

Kad网络规定:条目依据其key值被复制到目标节点ID距离最近的k个节点中。
k取值准则——任意选择至少k(典型取值20)个节点,它们在任意时刻同时不在线的几率几乎为0。

为了实现较短的查询响应延迟,在条目查询的过程中,任一条目可被cache到任意节点之上。

时效性:考虑条目在节点上存储的时效性,越接近目标结点保存的时间将越长
为什么?

节点之间的距离取异或值

对于同一个key值的所有查询都会逐步收敛到同一个路径上,而不管查询的起始节点位置如何。

沿着查询路径上的节点都缓存相应的对,可以有效减轻存放热门key值节点的压力,加快查询相应速度。

2.5.3. 节点维护

每一个节点均维护160个list,每个list称为一个k-桶(k-bucket) 。
第i个k-桶的内容:记录当前节点已知的与自身距离为2i~2(i+1)的其他节点的网络信息(NodeID,IP地址,UDP端口)。
一个k-桶最多存放k个对端节点信息,桶中节点信息按访问时间排序(最早访问的在头部)。

List(k-桶)的更新原则:
1)目标节点信息已经在list中,将其移至队尾;
2)list未满,且目标节点不在其中,其信息将直接添入list队尾;
3)list已满,先检查队首节点是否仍有响应,如果有,则队首节点被移至队尾,目标节点被抛弃;如果没有,则抛弃队首节点,将最新访问的节点信息插入队尾。

K桶的设计初衷:维护最近最新见到的节点信息更新,对于某个需要查找的特定ID节点N,可以从当前节点的k桶中迅速的查出距离N最近的若干已知节点。

2.5.4. 寻找节点

查找与目标节点网络距离最近的k个节点所对应的网络信息(NodeID,IP地址,UDP端口)。
1)发起者从自己的k-桶中选出若干距离目标ID最近的节点,并向它们同时发送异步查询请求;
2)被查询节点收到请求后,从自己的k-桶中找出自己所知的目标ID的若干近邻返回给发起者;
3)发起者收到返回信息后,再次从当前已知的近邻节点中选出若干未被请求的,并重复步骤1。
重复上述过程2)~3)直至无法获得k近邻的更新时停止。
在查询过程中没有及时响应的节点将立即被排除。

2.5.5. 条目搜索

搜索发起方以迭代方式不断查询距离key较近的节点

直至查询路径中的任一节点返回所需查找的value。

系统优化:
搜索成功后发起方可选择将条目作为cache存储到查询路径的多个节点中,条目cache的超时时间与节点的距离呈指数反比关系。

2.5.6. 新节点加入

1)获知一个已经加入Kad网络的节点信息(记为节点I),并将其加入自己的k-buckets;
2)向I节点发起一次针对自己ID的节点查询请求,从而通过节点I获取一系列与自己邻近的其他节点信息;
3)刷新所有的k-bucket,保证自己获得最新的节点信息。

3. 第三章 多结构化数据管理二

3.1. NAS vs. SAN

1)NAS是一台特殊的含有大硬盘空间的计算机,连接在以太网上,其它计算机通过网络映射硬盘使用该空间。
SAN是一种容易扩容的光纤通讯的磁盘阵列机,是多台服务器共享使用多台阵列机,可以安装各种软件,可跨平台。

2)SAN是光纤协议,NAS是TCP/IP协议。NAS是利用现有网络,SAN是在sever端再架设一个网络。

3)NAS以文件方式访问数据,而SAN以sectors方式访问数据。
SAN对于高容量块级数据传输有明显的优势,易扩展且管理高效,可运行关键应用(如数据库、备份等)。
NAS更加适合文件级别的数据处理。可作为日常办公中需要经常交换小文件的存储配置(如存储网页)。

4)SAN更多的是强调:范围+高效。
NAS主要强调:共享。
NAS使用的文件传输协议意味着:当把数据库建立在NAS上时,取得一条记录需要对整个数据文件进行传输(如果数据库不更改数据访问方式)。

3.2. NAS和SAN的结合

一些公司推出了融合NAS与SAN的存储解决方案,可分为两类:“NAS头”与“统一存储系统”。

1)NAS头——由专为提供文件服务而优化的部件(文件管理器,filer)构成,NAS头连接到后端上的SAN存储上,以类似于利用SAN存储提供存储容量的方式为NAS头提供存储容量。

2)“统一存储系统”(如NetApp的FAS统一网络存储系统)——原有的NAS基础上增加对FCP协议的支持。

通过不同的接口卡完成对SAN和NAS的同时支持,如通过以太网卡提供NAS的访问服务,同时又可通过HBA卡提供SAN的访问服务。
由于NAS具有自己的操作系统和文件系统,因此增加的FCP和原有的NFS、CIFS、HTTP一样,仅是一个协议的支持。
NAS和SAN可以共同有效使用所有虚拟化的空间。

3.3. OceanBase

虽然数据库系统数据量十分庞大(可能几十亿、几百亿条甚至更多),但一段时间(例如一天)的修改量并不大(通常不超过几千万条到几亿条)

增量数据(UpdateServer) + 基线数据(ChunkServer)

增量数据: OceanBase使用单台服务器(UpdateServer)记录一段时间的修改增量,其存储以内存表(memtable)为主,SSD(固态盘)为辅。
基线数据:在增量数据时间段内保持不变的数据称为基线数据,存储于多台服务器(ChunkServer),类似于分布式文件系统。

RootServer:主控机(类似于GFS的master),进行机器故障检测、负载平衡计算、负载迁移调度等。

查询:由MergerServer把基线数据(Chunk-Server)和增量数据( UpdateServer )融合后返回调用者,分散在多台服务器上。

写事务:集中在UpdateServer进行,避免了复杂的分布式写事务,可实现跨行跨表事务,又有较好的扩展性。

3.3.1. UpdateServer

UpdateServer开始总是以内存表(memtable)方式记录修改,当内存表达到一定阈值,就冻结当前内存表并将后续修改切换到新的内存表。
冻结内存表不再接受写入并被转换成一种紧凑格式保存到SSD盘,转换完成后,冻结内存表的内存即可回收。

3.3.2. ChunkServer

使用主键(row key,类似于关系数据库的聚簇索引)对表中数据进行排序和存储。主键可包含多列并具有唯一性。
基线数据按主键排序并划分成sstable(存储一个或几个表的一段按主键连续的数据),一个或者多个sstable组合成数据量大致相等的块(tablet,缺省大小是256MB,可配置)并存储在ChunkServer上。
为了避免ChunkServer故障导致数据丢失,tablet通常保存2~3个副本(可配置)。

3.3.3. 数据合并

每隔一段时间(例如一天)把当前增量合并到原有基线数据并生成新的基线数据(称为每日合并),然后清除过期的修改增量和过期的基线数据。(数据的迁移)

合并过程:
1)UpdateServer冻结当前内存表并开启新内存表,此后新的修改写入新内存表;
2)ChunkServer融合当前基线数据与冻结的内存表,生成新基线数据;
3)当所有tablet的新基线数据生成后,UpdateServer冻结的内存表即可释放,其所占内存也被回收。

合并的调度时机:为了降低对用户访问的影响,合并被设置成低优先级任务,当机器负载(如CPU负载和I/O等待)高于一定阈值时,合并速度会减慢甚至暂停。

实际应用中,数据库管理员(DBA)通常把每日合并设定在业务的低峰期(后半夜) 。

3.4. 分布式B+树实现难点

1) 状态数据的持久化和迁移。
更新操作首先以事务提交日志(MySQL称为binlog, NOSQL称为commit log)写入到磁盘,为了保证可靠性,commit log需要复制多份。
机器宕机时需要通过commit log记录的状态修改信息将服务迁移到集群中的其它节点。

2) 子表的分裂和合并。
B+树实现的难点在于树节点的分裂与合并。
在分布式系统中,数据被顺序划分为大小在几十到几百MB的数据区间(子表),相当于B+树的叶子节点。
每个子表在系统中存储多份,需要保证多个副本的分裂点一致。
子表分裂时也有更新操作,增加了多副本一致的难度。

你可能感兴趣的:(database,现代数据管理,数据库)