目录 php
大数据扫盲 1 html
0.2. 大数据处理技术架构 2 chrome
1. 数据分区与路由 2 数据库
1.1. 二级映射机制 3 json
1.1.2. 虚拟桶(virtual bucket) 3 缓存
1.1.3. 一致性哈希(consistent hashing) 4 安全
1.2. 一致性 4 服务器
大数据能够用4V来描述。
数据源,包括结构化数据、半结构化数据、非结构化数据。数据类型多样化。
结构化数据指的是数据描述和数据自己是分离的,存放在关系数据库中。
半结构化数据指的是数据的描述和数据自己掺杂在一块儿,好比邮件、xml文件、json格式、HTML页面。通常使用树、图结构存储。
非结构化数据指的是没有描述信息,好比音视频文件、图像等。没有固定的存储模型。
数据抽取与集成,指的是从原始的数据源中把数据提取出来,存放到必定的存储模型中,如HDFS、HBase、Redis等。
数据分析,指的是进行数据挖掘、机器学习、统计分析等,能够获取更加深层次的信息。
数据展现,指的是数据的显示,包括数据可视化、人机交互等。
传统的数据库中,数据量大了、运行速度慢了之后,能够经过提升单机的硬件水平来提升存储量或者查询速度,这叫作纵向扩展。缺点是成本高,收效愈来愈弱。
在大数据领域,通常是经过增长服务器来进行横向扩展。数据被分散存储在不少台服务器上,数据的查询经过对分散在不少台机器上面的数据查询进行汇总获得。
海量的数据按照什么规则分配到这么多服务器上?如何快速的查询位于某台服务器上的数据?当添加服务器或者下架服务器的时候,怎么办?
数据分配到服务器的方式称做数据分区。
快速查询位于服务器集群上的某条数据,称做数据路由。
当数据经过分区存储到集群后,会怎加数据访问失败的几率,这称做数据的可靠性。最简单的方式是使用副本机制。工业标准是副本数量为3。
副本机制,能够提升数据的安全性,能够经过并发读提升并发读取效率,能够经过查询最近位置提升单次读取效率。
副本机制,带来一个问题,就是写操做时,如何保持副本数据的一致性。
实现数据的分区与路由的方式,通常是二级映射机制。
其中,key是划分到哪些分区上的?有两种算法,一是哈希分区算法,一是范围分区算法。
哈希分区是把某个key根据哈希算法计算的结果,放到指定的分区中,适合"键查询"。
范围分区是把一段联系的key放到指定的分区中,适合"范围查询"。
假设有k机器,把全部的机器从0到k-1编号,使用哈希函数hash(key) mod K 就能够把全部数据存放到K台机器中。取得时候,也按照哈希函数取值便可。
优势是实现简单。缺点是缺少灵活性,好比增长或者减小机器时。
在key和机器之间,引入中间层,称做"虚拟桶",实现二级映射,就能够完美解决机器扩展性的问题。如数据库CouchBase。
哈希算法的致命缺陷是没有实现二级映射。
在分布式存储中,哈希算法在增删机器的场景下效率很是低,有解决方案吗?这就是一致性哈希算法。
Consistency强一致性、availability可用性、partition tolerance分区容错性,在一个大规模的分布式服务系统中不可能同时存在。
C指的是更新操做成功并返回客户端完成后,分布式的全部节点在同一时间的数据彻底一致
A指的是读和写操做都能成功
P指的是节点宕机不影响服务的运行。
1. 假设DB的更新操做是同时写北京和广州的DB都成功才返回成功
在没有出现网络故障的时候,知足CA原则,C 即个人任何一个写入,更新操做成功并返回客户端完成后,分布式的全部节点在同一时间的数据彻底一致, A 即个人读写操做都可以成功,可是当出现网络故障时,我不能同时保证CA,即P条件没法知足
2. 假设DB的更新操做是只写本地机房成功就返回,经过binlog/oplog回放方式同步至侧边机房
这种操做保证了在出现网络故障时,双边机房都是能够提供服务的,且读写操做都能成功,意味着他知足了AP ,可是它不知足C,由于更新操做返回成功后,双边机房的DB看到的数据会存在短暂不一致,且在网络故障时,不一致的时间差会很大(仅能保证最终一致性)
3. 假设DB的更新操做是同时写北京和广州的DB都成功才返回成功且网络故障时提供降级服务
降级服务,如中止写入,只提供读取功能,这样能保证数据是一致的,且网络故障时能提供服务,知足CP原则,可是他没法知足A可用性原则
选择权衡
经过上面的例子,咱们得知,咱们永远没法同时获得CAP这3个特性,那么咱们怎么来权衡选择呢?
选择的关键点取决于业务场景
对于大多数互联网应用来讲(如网易门户),由于机器数量庞大,部署节点分散,网络故障是常态,可用性是必须须要保证的,因此只有设置一致性来保证服务的AP,一般常见的高可用服务吹嘘5个9 6个9服务SLA稳定性就本都是放弃C选择AP
对于须要确保强一致性的场景,如银行,一般会权衡CA和CP模型,CA模型网络故障时彻底不可用,CP模型具有部分可用性,实际的选择须要经过业务场景来权衡(并非全部状况CP都好于CA,只能查看信息不能更新信息有时候从产品层面还不如直接拒绝服务)
Atomicity原子性、consistency一致性、isolation独立性、durability持久性
关系数据库采用这套模型,保证高可靠和强一致性。
Basically availible基本可用、soft state软状态、eventual consistency最终一致性
Base是经过牺牲一致性来得到高可用。目前的大部分NoSQL数据库都是base理论。
数学中的幂等指的是如max(x,y)=x、and操做等等。
分布式系统中的幂等性指的是不管多少次调用,结果都是相同的。
由于在分布式系统中,有可能网络中断,形成通信失败,幂等性很是重要。Zookeeper就是幂等性系统。
略
假设服务器A是一个反垃圾邮件服务器,A维护了一个可疑IP列表,列表中包含了大量的可疑的 IP地址。服务器B是另外一个反垃圾邮件服务器,B也维护了一个可疑IP列表,列表中包含了大量的可疑的IP地址。两台服务器只能经过互联网通讯。有一天, 服务器A须要确认本身的列表和服务器B的列表的类似度(即二者包含的相同的IP地址占全部IP地址的比例)。
首先,让咱们来看看什么是Bloom Filter吧。初始状态时,Bloom Filter是一个包含m位的位数组,每一位都置为0。
为了表达S={x1, x2,…,xn}这样一个n个元素的集合,Bloom Filter使用k个相互独立的哈希函数(Hash Function),它们分别将集合中的每一个元素映射到{1,…,m}的范围中。对任意一个元素x,第i个哈希函数映射的位置hi(x)就会被置为 1(1≤i≤k)。注意,若是一个位置屡次被置为1,那么只有第一次会起做用,后面几回将没有任何效果。以下图所示,咱们能够全部的元素xk映射到位数组 中。而m位的位数组就能够做为描述全部元素的简化版。
在判断y是否属于这个集合时,咱们对y应用k次哈希函数,若是全部hi(y)的位置都是1(1≤i≤k),那么咱们就认为y是集合中的元素,不然就认为y不是集合中的元素。下图中y1就不是集合中的元素。y2或者属于这个集合,或者恰好是一个false positive。
m的单位是bit,而n则是以元素个数为单位(准确的说是不一样元素的个数,能够是字符串或者复制对象)。因此使用bloom filter内存上一般都是节省的。
具备良好的时间和空间效率,尤为是空间效率极高。对于判断元素是否属于集合很是高效。好比google chrome使用它进行恶意url判断,网络爬虫使用它检查是否爬过特定的url,缓存数据等。如cassandra、hbase都采用了。
对一棵查找树(search tree)进行查询/新增/删除 等动做, 所花的时间与树的高度h 成比例, 并不与树的容量 n 成比例。若是可让树维持矮矮胖胖的好身材, 也就是让h维持在O(lg n)左右, 完成上述工做就很省时间。可以一直维持好身材, 不因新增删除而长歪的搜寻树, 叫作balanced search tree(平衡树)。
构造平衡树,很是复杂。可是构造跳表很是简单,并且功能相同、效率相近。
跳表是一种随机化的数据结构,目前开源软件 Redis 和 LevelDB 都有用到它,
它的效率和红黑树以及 AVL 树不相上下,但跳表的原理至关简单,只要你能熟练操做链表,
就能轻松实现一个 SkipList。
有序表的搜索
考虑一个有序表:
从该有序表中搜索元素 < 23, 43, 59 > ,须要比较的次数分别为 < 2, 4, 6 >,总共比较的次数
为 2 + 4 + 6 = 12 次。有没有优化的算法吗? 链表是有序的,但不能使用二分查找。相似二叉
搜索树,咱们把一些节点提取出来,做为索引。获得以下结构:
这里咱们把 < 14, 34, 50, 72 > 提取出来做为一级索引,这样搜索的时候就能够减小比较次数了。
咱们还能够再从一级索引提取一些元素出来,做为二级索引,变成以下结构:
这里元素很少,体现不出优点,若是元素足够多,这种索引结构就能体现出优点来了。
这基本上就是跳表的核心思想,其实也是一种经过"空间来换取时间"的一个算法,经过在每一个节点中增长了向前的指针,从而提高查找的效率。
跳表
下面的结构是就是跳表:
其中 -1 表示 INT_MIN, 链表的最小值,1 表示 INT_MAX,链表的最大值。
跳表具备以下性质:
(1) 由不少层结构组成
(2) 每一层都是一个有序的链表
(3) 最底层(Level 1)的链表包含全部元素
(4) 若是一个元素出如今 Level i 的链表中,则它在 Level i 之下的链表也都会出现。
(5) 每一个节点包含两个指针,一个指向同一链表中的下一个元素,一个指向下面一层的元素。
跳表的搜索
LSM树的本质是将大量的随机写操做转换成批量的序列写,这样能够极大的提高磁盘数据写入速度,因此LSM树很是适合对写操做效率有高要求的应用场景。可是读效率有些低,能够经过bloom filter或者缓存优化读性能。
LSM(Log Structured Merge Trees)数据组织方式被应用于多种数据库,如LevelDB、HBase、Cassandra等,下面咱们从为何使用LSM、LSM的实现思路两方面介绍这种存储组织结构,完成对LSM的初步了解。
存储背景回顾
LSM相较B+树或其余索引存储实现方式,提供了更好的写性能。究其缘由,咱们先回顾磁盘相关的一点背景知识。
顺序操做磁盘的性能,较随机读写磁盘的性能高不少,咱们实现数据库时,也是围绕磁盘的这点特性进行设计与优化。若是让写性能最优,最佳的实现方式就是日志型(Log/Journal)数据库,其以追加(Append)的方式写磁盘文件。
有得即有舍,万事万物存在权衡,带来最优写性能的同时,单纯的日志数据库读性能不好,为找到一条数据,不得不遍历数据记录,要实现范围查询(range)几乎不可能。为优化日志型数据库的读性能,实际应用中一般结合如下几种优化措施:
二分查找(Binary Search): 在一个数据文件中使用二分查找加速数据查找
哈希(Hash): 写入时经过哈希函数将数据放入不一样的桶中,读取时经过哈希索引直接读取
B+树: 使用B+树做为数据组织存储形式,保持数据稳定有序
外部索引文件: 除数据自己按日志形式存储外,另对其单独创建索引加速读取,如以前介绍的《一种Bitcask存储模型的实现》
以上措施都很大程度提高了读性能(如二分查找将时间复杂度提高至O(log(N))),但相应写性能也有折损,第一写数据时须要维护索引,这视索引 的实现方式,最差状况下可能涉及随机的IO操做;第二若是用B+树等结构组织数据,写入涉及两次IO操做,先要将数据读出来再写入。
LSM存储结构
LSM存储实现思路与以上四种措施不太相同,其将随机写转化为顺序写,尽可能保持日志型数据库的写性能优点,并提供相对较好的读性能。具体实现方式以下:
1. 当有写操做(或update操做)时,写入位于内存的buffer,内存中经过某种数据结构(如skiplist)保持key有序
2. 通常的实现也会将数据追加写到磁盘Log文件,以备必要时恢复
3. 内存中的数据定时或按固定大小地刷到磁盘,更新操做只不断地写到内存,并不更新磁盘上已有文件
4. 随着愈来愈多写操做,磁盘上积累的文件也愈来愈多,这些文件不可写且有序
5. 定时对文件进行合并操做(compaction),消除冗余数据,减小文件数量
以上过程用图表示以下:
LSM存储结构的写操做,只需更新内存,内存中的数据以块数据形式刷到磁盘,是顺序的IO操做,另外磁盘文件按期的合并操做,也将带来磁盘IO操做。
LSM存储结构的读操做,先从内存数据开始访问,若是在内存中访问不到,再顺序从一个个磁盘文件中查找,因为文件自己有序,而且按期的合并减小了磁盘文件个数,于是查找过程相对较快速。
合并操做是LSM实现中重要的一环,LevelDB、Cassandra中,使用基于层级的合并方式(Levelled compaction),生成第N层的时候,对N-1层的数据进行排序,使得每层内的数据文件之间都是有序的,但最高层除外,由于该层不断有数据文件产 生,于是只是数据文件内部按key有序。
除最高层外,其余层文件间数据有序,这也加速了读过程,由于一个key对应的value只存在一个文件中。假设总共有N层,每层最多K个数据文件,最差的状况下,读操做先遍历K个文件,再遍历每层,共须要K+(N-1)次读盘操做。
总结
LSM存储框架实现的思路较简单,其先在内存中保存数据,再定时刷到磁盘,实现顺序IO操做,经过按期合并文件减小数据冗余;文件有序,保证读取操做相对快速。
咱们须要结合实际的业务场景选择合适的存储实现,不存在万金油式的通用存储框架。LSM适用于写多、读相对少(或较多读取最新写入的数据,该部分数据存在内存中,不须要磁盘IO操做)的业务场景。
Merkle哈希树校验方式为咱们提供了一个很好的思路,它试图从校验信息获取及实际校验过程两个方面来改善上述问题。先说说什么是哈希树,以最简 单的二叉方式为例,以下图所示,设某文件共13个数据块,咱们能够将其padding到16(2的整数次方)个块(注意,padding的空白块仅用于辅 助校验,而无需看成数据进行实际传输),每一个块均对应一个SHA1校验值,而后再对它们进行反复的两两哈希,直到得出一个惟一的根哈希值为止(root hash, H0),这一计算过程便构成了一棵二元的Merkle哈希树,树中最底层的叶子节点(H15~H30)对应着数据块的实际哈希值,而那些内部节点 (H1~H14)咱们则能够将其称为"路径哈希值",它们构成了实际块哈希值与根哈希值H0之间的"校验路径",好比,数据块8所对应的实际哈希值为 H23,则有:SHA1(((SHA1(SHA1(H23,H24),H12),H6),H1)应该等于H0。固然,咱们也能够进一步采用n元哈希树来进 行上述校验过程,其过程是相似的。
采用Merkle哈希树校验方式可以极大地减少.torrent文件的尺寸,这是由于,一旦采用这种方式来校验数据块,那么便没有必要 在.torrent文件中保存全部数据块的校验值了,其中仅需保存一个20字节的SHA1哈希值便可,即整个下载文件的根哈希值H0。想象一下一个3、 4GB的文件,其对应.torrent文件却只有100-200字节的样子?
一般设计是在各个日志服务器安装代理,经过代理收集数据。
数据总线的做用是可以造成数据变化通知通道,当集中存储的数据源中的数据发生变化时,能尽快通知对数据变化敏感的相关应用或者系统构建,使得他们能尽快捕获这种数据变化。
近乎实时的数据扩散,如linkedIn的databus。
sqoop
在集群硬件上抽象出一个功能独立的集群资源管理系统。把全部资源当成一个总体,并对其余全部计算任务提供统一的资源管理与调度框架和接口。计算任务按需申请资源、释放资源。
好处:
集群总体资源利用率高;
可增长数据共享能力;
支持多类型计算框架和多版本计算模型。
核心包含三部分:资源组织模型、调度策略、任务组织模型。
设计中,一般有节点管理器,负责收集本节点的资源使用状况,汇报给资源收集器。并对分配给本节点的任务放入容器中执行。通用调度器包括资源收集器、资源池、任务池、调度策略。资源收集器负责接收各个节点管理器提交的各节点使用状况,并更新到资源池中。资源池维护者本集群最新的可用资源。任务池存放着待执行的各类任务。调度策略负责把任务取出分配可用的资源去执行任务。调度策略一般有FIFO、公平调度、能力调度等。
数据局部性,包括节点局部性优先、机架局部性优先、全局局部性优先。
抢占式调度、非抢占式调度,前者用于优先级调度,后者用于公平调度。
资源分配粒度,包括全分或不分式、增量知足式、资源储备式。资源分配可能出现任务饿死、死锁问题。
资源隔离方面一般采用容器技术,LXC是一种轻量级的内核虚拟化技术,LXC依赖于Linux内核的cgroups子系统。
典型的案例包括Mesos和Yarn。
序列化与RPC主要用于网络中不一样节点的进程直接的交互。
许多分布式系统都会在进程间进行信息交换。RPC就是这种技术。当A调用B进程时,A进程挂起,把参数传给B进程,B进程执行后把结果传给A进程。B进程结束,A进程继续执行。
数据序列化是为了保证高效的数据传输的,通常采用json或者xml格式,也有采用专门协议的。
常见的框架包括protocol buffer、thrift、avro。
消息队列主要用于大规模分布式系统中,用于解除相互之间的功能耦合,这样能够减轻各个子系统之间的依赖,使得各个子系统能够独立演进、维护或者重用。这里的消息指的是数据传输的基本单位,能够是简单的字符串,也能够是复杂的对象。
常见的框架有ActiveMQ、ZeroMQ、RabiitMQ、Kafka等。
Gossip协议。应用于cassandra、bittorrent、s3等。还能够用于维护贮备数据的最终一致性以及负载均衡等领域。