Skip to content

Latest commit

 

History

History
578 lines (538 loc) · 50.8 KB

大数据.md

File metadata and controls

578 lines (538 loc) · 50.8 KB

大数据

ELK 日志分析系统

  • 由 ElasticSearch、FileBeat、LogStash、Kibana 组成
  • ElasticSearch:用于存储日志
  • FileBeat:是一个轻量级的日志收集处理工具(Agent),Filebeat 占用资源少,适合于在各个服务器上搜集日志后传输给 Logstash,官方也推荐此工具
  • LogStash:主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般工作方式为 c/s 架构,client 端安装在需要收集日志的主机上,server 端负责将收到的各节点日志进行过滤、修改等操作再一并发往 elasticSearch 上去
  • Kibana:一个开源的数据可视化工具,可以帮助汇总、分析和搜索重要数据日志

MapReduce

  • MapReduce 最早是由 Google 公司研究提出的一种面向大规模数据处理的并行计算模型和方法。Google 公司设计 MapReduce 的初衷主要是为了解决其搜索引擎中大规模网页数据的并行化处理
  • MapReduce 是一种编程模型,用于大规模数据集(大于 1TB)的并行运算
  • 概念"Map(映射)"和"Reduce(归约)",是它们的主要思想

Hadoop

  • 简介
    • 2004 年,开源项目 Lucene(搜索索引程序库)和 Nutch(搜索引擎)的创始人 Doug Cutting 发现 MapReduce 正是其所需要的解决大规模 Web 数据处理的重要技术,因而模仿 Google MapReduce,基于 Java 设计开发了一个称为 Hadoop 的开源 MapReduce 并行计算框架和系统
    • Hadoop 实现了一个分布式文件系统(Hadoop Distributed File System),简称 HDFS
    • HDFS 有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序
    • HDFS 放宽了(relax)POSIX 的要求,可以以流的形式访问(streaming access)文件系统中的数据
    • Hadoop 的框架最核心的设计就是:HDFS 和 MapReduce
    • HDFS 为海量的数据提供了存储,而 MapReduce 则为海量的数据提供了计算
  • Hadoop 框架包括以下四个模块:
    • Hadoop Common:这些是其他 Hadoop 模块所需的 Java 库和实用程序。这些库提供文件系统和操作系统级抽象,并包含启动 Hadoop 所需的必要 Java 文件和脚本
    • Hadoop YARN:这是作业调度和集群资源管理的框架
    • Hadoop 分布式文件系统(HDFS)
      • 提供对应用程序数据的高吞吐量访问的分布式文件系统
      • 保存多个副本,且提供容错机制,副本丢失或宕机自动恢复。默认存 3 份。为防止某个主机失效读取不到该主机的块文件,它将同一个文件块副本分配到其他某几个主机上
      • HDFS 会将一个完整的大文件平均分块存储到不同计算机上,默认会将文件分割成 block,64M 为 1 个 block。然后将 block 按键值对存储在 HDFS 上,并将键值对的映射存到内存中。如果小文件太多,内存的负担会很重
        • Block:将文件分块,通常为 64M
      • 流式数据访问,一次写入多次读写,和传统文件不同,它不支持动态改变文件内容,而是要求让文件一次写入就不做变化,要变化只能在文件末尾添加
    • Hadoop MapReduce: 这是基于 YARN 的大型数据集并行处理系统
  • HDFS(Hadoop Distributed File System)分布式文件系统主要组成:
    • Client:
      • 切分文件
      • 与 NameNode 交互,获取文件位置信息
      • 与 DataNode 交互,读取和写入数据
    • NameNode
      • 作为 Master 服务,负责管理文件系统的命名空间和客户端对文件的访问
      • NameNode 会保存文件系统的具体信息,包括文件信息、文件被分割成具体 block 块的信息、以及每一个 block 块归属的 DataNode 的信息
      • 对于整个集群来说,HDFS 通过 NameNode 对用户提供了一个单一的命名空间
      • NameNode 内存中存储的了 fsimage(文件镜像)和 edits(操作日志)
        • fsimage:元数据镜像文件(文件系统的目录树)
        • edits:元数据的操作日志(针对文件系统做的修改操作记录)
    • DataNode
      • 作为 Slave 服务,在集群中可以存在多个。通常每一个 DataNode 都对应于一个物理节点
      • 负责存储实际的数据,它将存储划分为多个 block 块,管理 block 块信息,同时周期性的将其所有的 block 块信息发送给 NameNode
    • Secondary NameNode
      • 定期合并 NameNode 的 fsimage 和 edits,再推送给 NameNode,减少 NameNode 的工作量
      • 是 NameNode 的冷备份,可辅助恢复 NameNode
  • 文件写入流程
    • Client 将文件按 64M 分块。分成多个 block
    • Client 向 NameNode 发送写数据请求,获取文件位置信息
    • NameNode 节点,记录 block 信息。并返回可用的 DataNode 信息给 Client
    • Client 向 DataNode 发送 block,发送过程是以流式写入,每个 block 会拆分成多个 64k 的 package,写入到其中一个 DataNode 后,该 DataNode 会将 package 再同步写入到其他两个 DataNode(作为备份的副本),每个 Block 写入完之后,DataNode 会向 Client 发送消息
    • Client 收到 DataNode 写入完成的消息后,向 NameNode 发送消息,通知 NameNode 数据写入完毕
    • 当所有 Block 写入完毕后,文件写入完毕
  • 文件读取流程
    • Client 向 NameNode 发起文件读取的请求
    • NameNode 返回文件存储的 block 块信息、及其 block 块所在 DataNode 的信息
    • Client 读取文件信息
  • MapReduce 分布式计算框架
    • JobTracker:管理所有作业,将任务分解成一系列任务,并分派给 TaskTracker
    • TaskTracker:运行 Map Task 和 Reduce Task;并与 JobTracker 交互,汇报任务状态
    • Map Task:解析每条数据记录,传递给用户编写的 map(),将输出结果写入本地磁盘
    • Reducer Task:从 Map Task 的执行结果中,远程读取输入数据,对数据进行排序,将数据按照分组传递给用户编写的 reduce 函数执行
  • MapReduce 的缺陷
    • JobTracker 是 Map-reduce 的集中处理点,存在单点故障
    • JobTracker 需要完成的任务太多,既要维护 job 的状态又要维护 job 的 task 的状态,造成过多的资源消耗。业界普遍总结出老 Hadoop 的 Map-Reduce 只能支持 4000 节点主机的上限
    • 在 TaskTracker 端,以 map/reduce task 的数目作为资源的表示过于简单,没有考虑到 cpu/ 内存的占用情况,如果两个大内存消耗的 task 被调度到了一块,很容易出现 OOM
    • 在 TaskTracker 端,把资源强制划分为 map task slot 和 reduce task slot, 如果当系统中只有 map task 或者只有 reduce task 的时候,会造成资源的浪费,也就是前面提过的集群资源利用的问题
  • Yarn 运行原理
    • Yarn 是 Hadoop 集群的分布式资源管理系统。Hadoop2.0 对 MapReduce 框架做了彻底的设计重构,我们称 Hadoop2.0 中的 MapReduce 为 MRv2 或者 Yarn
    • Yarn 是为了提高分布式的集群环境下的资源利用率,这些资源包括内存、IO、网络、磁盘等。其产生的原因是为了解决原 MapReduce 框架的不足
    • 在 Yarn 中把 job 的概念换成了 application,因为在新的 Hadoop2.x 中,运行的应用不只是 MapReduce 了,还有可能是其它应用如一个 DAG
    • Yarn 的另一个目标就是拓展 Hadoop,使得它不仅仅可以支持 MapReduce 计算,还能很方便的管理诸如 Hive、Hbase、Pig、Spark/Shark 等应用。各种应用就可以互不干扰的运行在同一个 Hadoop 系统中,共享整个集群资源
  • YARN 组件与架构
    • ResourceManager:Global(全局)的进程
    • NodeManager:运行在每个节点上的进程
    • ApplicationMaster:Application-specific(应用级别)的进程。ApplicationMaster 是对运行在 Yarn 中某个应用的抽象,它其实就是某个类型应用的实例,ApplicationMaster 是应用级别的,它的主要功能就是向 ResourceManager(全局的)申请计算资源(Containers)并且和 NodeManager 交互来执行和监控具体的 task
    • Scheduler:是 ResourceManager 的一个组件。Scheduler 是 ResourceManager 专门进行资源管理的一个组件,负责分配 NodeManager 上的 Container 资源,NodeManager 也会不断发送自己 Container 使用情况给 ResourceManager
    • Container:节点上一组 CPU 和内存资源。Container 是 Yarn 对计算机计算资源的抽象,它其实就是一组 CPU 和内存资源,所有的应用都会运行在 Container 中
  • YARN 执行过程
    • 应用程序提交
    • 启动应用的 ApplicationMaster 实例
    • 执行 ApplicationMaster 实例管理应用程序

Pig

  • Pig 是一款数据装载、处理、存储的工具,是一种探索大规模数据集的脚本语言,底层基于 MapReduce 实现
  • 我们可以使用 pig 将数据装载到内存中成为一个关系,然后再通过 PigLatin 语言对数据进行操作,最后再将数据转换的结果存储到一个文件中,适合用于 ETL(Extract-Transform-Load)

Hive(数据仓库)

  • 简介
    • Hive 定义了一种类似 SQL 的查询语言(HQL),可以将 SQL 转化为 MapReduce 任务在 Hadoop 上执行
    • 实现了按字段多层 Partition(分区)的功能
    • 通常用于离线分析
    • Hive 本身提供了一系列对数据进行提取、转换、加载(ETL)的工具,可以存储、查询和分析存储在 Hadoop 中的大规模数据
    • 支持自定义 UDF 函数或者计算脚本
    • 支持 MapReduce,Tez,Spark 等多种计算引擎
    • 可以直接访问 HDFS 文件以及 HBase
    • 不支持列级别的数据添加、更新、删除操作
    • 可以创建托管表和外部表,外部表可以访问仓库目录以外的文件
    • 支持流量控制
  • Hive 分为三个角色:HiveServer、MetaStore、WebHcat
    • HiveServer:将用户提交的 HQL 语句进行编译,解析成对应的 Yarn 任务,Spark 任务或者 HDFS 操作,从而完成数据的提取,转换,分析
    • MetaStroe:提供元数据服务
    • WebHcat:对外提供基于 Htpps 协议的元数据访问、DDL 查询等服务

HBase

  • 简介
    • HBase(Hadoop Database)是建立在 Hadoop 文件系统之上的分布式面向列的数据库,支持横向扩展,基于 JAVA 语言实现
    • 该技术来源于 Fay Chang 所撰写的 Google 论文“Bigtable:一个结构化数据的分布式存储系统”
    • HBase 在列上实现了 BigTable 论文提到的压缩算法、内存操作和布隆过滤器。HBase 的表能够作为 MapReduce 任务的输入和输出,可以通过 Java API 来访问数据,也可以通过 REST、Avro 或者 Thrift 的 API 来访问
  • 逻辑存储模型
    • namespace:命名空间,一般就是逻辑上用于表的区分,类似数据库中的 database。在最终物理文件存储的时候,会根据 namespace 切分目录
    • table:表,类似于数据库中的 table
    • column family:列族,相同列族的列会存放在一起
    • row:由基于字符串的 rowkey 唯一指定,rowkey 全局不能重复,按照字典序顺序存储,rowkey 的设计对最终的查询起到关键性作用
    • column:列,用于存放字段的数据内容
    • Cell
      • HBase 中通过 rowkey 和 columns 确定的为一个存储单元称为 cell
      • 每个 cell 都保存着同一份 数据的多个版本。版本通过时间戳来索引
    • Timestamp:时间戳一般写在 value 的旁边,代表某个值的版本号,默认的时间戳是你写入数据的那一刻,但是你也可以在写入数据的时候指定不同的时间戳
    • RowKey:Hbase 使用 Rowkey 来唯一的区分某一行的数据
  • HBase 是三维有序存储的,通过 rowkey(行键),column key(column family 和 qualifier)和 TimeStamp(时间戳)这个三个维度可以对 HBase 中的数据进行快速定位
  • HBase 架构
    • HBase 中的组件包括 Client、Zookeeper、HMaster、HRegionServer、HRegion、Store、MemStore、StoreFile、HFile、HLog 等
      • HBase 有两张特殊表:
        • .META.:记录了用户所有表拆分出来的的 Region 映射信息,.META.表可以有多个 Regoin,.META.表存储了每张表每个 Region 的起始 RowKey
        • -ROOT-:记录了.META.表的 Region 信息,-ROOT-只有一个 Region,无论如何不会分裂
      • Client
        • Client 访问用户数据前需要首先访问 ZooKeeper,找到-ROOT-表的 Region 所在的位置,然 后访问-ROOT-表,接着访问.META.表,最后才能找到用户数据的位置去访问,中间需要多次 网络操作,不过 client 端会做 cache 缓存
      • ZooKeeper
        • ZooKeeper 为 HBase 提供 Failover 机制,选举 Master,避免单点 Master 单点故障问题
        • 存储所有 Region 的寻址入口:-ROOT-表在哪台服务器上。-ROOT-这张表的位置信息
        • 实时监控 RegionServer 的状态,将 RegionServer 的上线和下线信息实时通知给 Master
        • 存储 HBase 的 Schema,包括有哪些 Table,每个 Table 有哪些 Column Family
      • HMaster
        • 把 HRegion 分配到某一个 RegionServer
        • 对 HRegionServer 进行负载均衡
        • 如果有 RegionServer 宕机,HMaster 可以把这台机器上的 Region 迁移到 active 的 RegionServer 上
        • 过 HDFS 的 dfs client 接口回收垃圾文件(无效日志等)
        • 处理 Schema 更新请求(表的创建,删除,修改,列簇的增加等等)
        • HMaster 没有单点问题,HBase 中可以启动多个 HMaster,通过 Zookeeper 的 Master Election 机制保证总有一个 Master 运行
      • RegionServer
        • RegionServer 维护 Master 分配给它的 Region,处理对这些 Region 的 IO 请求
        • RegionServer 负责 Split 在运行过程中变得过大的 Region,负责 Compact 操作
      • HRegion
        • table 在行的方向上分隔为多个 HRegion,Region 是 HBase 中分布式存储和负载均衡的最小单元
        • 同的 region 可以分别在不同的 Region Server 上,但同一个 Region 是不会拆分到多个 server 上
        • Region 按大小分隔,随着 Region 增大,当 region 的某个列族达到一个阈值时就会分裂成两个新的 region
      • Store
        • 每个 HRegion 由多个 Store 构成,每个 Store 保存一个列族(Columns Family)
        • table 有几个列族,则有几个 Store
        • 每个 Store 由一个 MemStore 和多个 StoreFile 组成
          • MemStore:MemStore 是放在内存里的。保存修改的数据即 keyValues。当 MemStore 的大小达到一个阀值(默认 128MB)时,MemStore 会被 flush 到文 件,即生成一个快照。目前 HBase 会有一个线程来负责 memStore 的 flush 操作
          • MemStore 内存中的数据写到文件后就是 StoreFile,StoreFile 底层是以 HFile 的格式保存
          • StoreFile 是只读的,一旦创建后就不可以再修改。因此 HBase 的更新/修改其实是不断追加 的操作
          • 当一个 Store 中的 StoreFile 达到一定的阈值后,就会进行一次合并(minor_compact, major_compact),将对同一个 key 的修改合并到一起,形成一个大的 StoreFile
          • 当 StoreFile 的大小达到一定阈值后,又会对 StoreFile 进行 split,等分为两个 StoreFile
        • HBase 以 store 的大小来判断是否需要切分 region
      • HFile
        • HBase 中 KeyValue 数据的存储格式,HFile 是 Hadoop 的 二进制格式文件,实际上 StoreFile 就是对 Hfile 做了轻量级包装,即 StoreFile 底层就是 HFile
        • HFile 分为六个部分:
          • Data Block:保存表中的数据,这部分可以被压缩(Gzip、LZO)
          • Meta Block:可选的,保存用户自定义的 kv 对,可以被压缩(Gzip、LZO)
          • File Info:Hfile 的元信息,不被压缩,用户也可以在这一部分添加自己的元信息
          • Data Block Index:Data Block 的索引。每条索引的 key 是被索引的 block 的第一条记录的 key
          • Meta Block Index:可选的,Meta Block 的索引
          • Trailer:这一部分是定长的。保存了每一段的偏移量,读取一个 HFile 时,会首先读取 Trailer, Trailer 保存了每个段的起始位置(段的 Magic Number 用来做安全 check),然后,DataBlock Index 会被读取到内存中,这样,当检索某个 key 时,不需要扫描整个 HFile,而只需从内存中找 到 key 所在的 block,通过一次磁盘 io 将整个 block 读取到内存中,再找到需要的 key。DataBlock Index 采用 LRU 机制淘汰
      • HLog
        • HLog(HBase write ahead log),用来做灾难恢复使用,HLog 记录数据的所有变更,一旦 region server 宕机,就可以从 log 中进行恢复
        • HLog 文件就是一个普通的 Hadoop Sequence File, Sequence File 的 value 是 key 时 HLogKey 对象,其中记录了写入数据的归属信息,除了 table 和 region 名字外,还同时包括 sequence number 和 timestamp,timestamp 是写入时间,sequence number 的起始值为 0,或者是最近一次存入文件系统中的 sequence number。 Sequence File 的 value 是 HBase 的 KeyValue 对象,即对应 HFile 中的 KeyValue
  • 数据读取流程
    • Client 请求 ZooKeeper 获取.META.所在的 RegionServer 的地址
    • Client 请求.META.所在的 RegionServer 获取访问数据所在的 RegionServer 地址,Client 会将.META.的相关信息 cache 下来,以便下一次快速访问
    • Client 请求数据所在的 RegionServer,获取所需要的数据
      • RegionServer 定位到目标数据所在的 Region,发出查询请求
      • Region 先在 Memstore 中查找,命中则返回
      • 如果在 Memstore 中找不到,则在 Storefile 中扫描 为了能快速的判断要查询的数据在不在这个 StoreFile 中,应用了 BloomFilter
    • Client 会将 RegionServer 与 Region 的映射关系缓存到本地,只有在发生读取错误的情况下才会重新走一遍前面的查询流程
  • 数据写入流程
    • Client 先根据 RowKey 找到对应的 Region 所在的 RegionServer
    • Client 向 RegionServer 提交写请求
    • RegionServer 找到目标 Region
    • Region 检查数据是否与 Schema 一致
    • 如果客户端没有指定版本,则获取当前系统时间戳作为数据版本
    • 将数据写入 HLog(HBase write ahead log)
    • 将数据写入 MemStore
    • 判断 MemStore 的是否需要 flush 为 StoreFile 文件
  • Region 分裂(split)机制
    • 当 MemStore 的数据超过阈值时,将数据写入磁盘,生成一个 StoreFile 文件。当 Region 中最大 Store 的大小超过阈值时,Region 分裂,等分成两个 Region,实现数据访问的负载均衡。新的 Region 的位置由 HMaster 来确定在哪个 RegionServer 中
    • 整个分裂的流程如下:
      • Region 所在 RegionServer 创建 splits 目录
      • 关闭要分裂的 Region 的读写请求
      • 在 splits 目录中创建所需要的文件结构
      • 移动两个新 Region 文件目录到目录表中,并更新.META 表
      • 异步复制父 Region 中的数据到两个子 Region 中(最主要的消耗时间)
      • 复制完成后、打开两个新产生的 Region,并上线,可以接收新的读写请求
      • 异步任务把定时把原来被分裂的 Region 从.META 表中清除掉,并从文件系统中删除该 Region 所占用的空间
  • HFile 合并(Compact)机制
    • HBase 是一种 LSM-Tree(Log-Structured Merge Tree)存储模式,用户数据写入先写 HLog,再写 MemStore,满足一定条件后缓存数据会执行 flush 操作真正落盘到 StoreFile 中,形成一个数据文件 HFile
    • 随着数据写入不断增多,flush 次数也会不断增多,进而 HFile 数据文件就会越来越多
    • 然而,太多数据文件会导致数据查询 IO 次数增多,因此 HBase 尝试着不断对这些文件进行合并,这个合并过程称为 Compaction
    • HFile 合并分为两种,Minor Compact 和 Major Compact
      • Minor Compact:按照策略,将一部分文件合并为一个 HFile
      • Major Compact:把一个 Store 中的所有 HFile 文件合并为一个 HFile 文件
    • Minor Compact 策略:
      • RatioBasedCompactionPolicy(0.94 版本的默认策略)
        • 对同一个 Store 的文件,从旧到新逐一扫描所有候选文件,满足以下条件之一便停止扫描:
          • 当前文件大小 < 比它更新的所有文件大小总和 * ratio,其中 ratio 是一个可变的比例,在高峰期时 ratio 为 1.2,非高峰期为 5,也就是非高峰期允许 compact 更大的文件
          • 当前所剩候选文件数 >= hbase.store.compaction.min(默认为 3)
          • 当前所剩候选文件数 <= hbase.store.compaction.max(默认为 5)
        • 停止扫描后,待合并文件就选择出来了,即为当前扫描文件+比它新的所有文件进行合并
        • 缺点:经常引起大面积的合并,因为 3 太小了,经常因为满足当前文件大小 < 比它更新的所有文件大小总和 * ratio,发生大面积合并。注意合并的时候就不能写入数据,经常合并就会引起 IO,所以 HBase 在 0.96 版本之后就修改了合并算法
      • ExploringCompaction(0.96 版本后的默认策略)
        • 根据【该文件<(所有文件大小-该文件大小)*比例因子】公式,比例因子默认为 1.2,该公式不再强调顺序性,而是把所有的文件都遍历一遍,若满足公式就把该文件放进待合并队列组合中
        • 根据 hbase.store.compaction.min 和 hbase.store.compaction.max 两个参数选挑选出多个文件组合
        • 在得到多个组合后,组合里面选择文件数最多的组合进行合并,文件数一样多时进一步选择文件总 size 最小的组合(尽可能多地合并文件并尽量降低 Compact 带来的 IO 压力)
        • Exploring 策略比 Ratio 策略在 IO 方面会有 10%左右的提升
      • FIFOCompationPolicy(删除策略)
        • 因为 MemStore 在 LSM 整理时,对于 TTL 过期只要不写入 HFile 文件就算是删除了
        • 所以 FIFOCompationPolicy 策略在合并时直接删除所有单元格都过期的块(不落盘而已),可以看到过期的块被整个删除掉了,没有过期的块完全没有操作。整体上只有删除没有复制和移动,优点就是对 CPU/IO 几乎没有压力
        • 适合 TTL 特别短,容易出现整个块的每一个单元格都过期的场景
        • 不适用场景:
          • 表没有设置 TTL,或者 TTL=FOREVER
          • 表设置了 MIN_VERSIONs,并且 MIN_VERSIONs>0
      • DateTieredCompactionPolicy
        • 1.3 版本 HBase 增加了基于时间戳的分层 compact 策略,该方法借鉴自 Cassandra
        • 基本思想就是将数据按时间戳分区,使得新老数据在不同的分区,定时(默认 6 小时)执行 Compact 操作,使得 Compact 行为在不同的分区内发生,这样相当于把 Compact 也按时间戳进行了拆分
        • 同一个时间窗口里的文件,如果达到最小合并数,文件就会合并,合并策略使用的 ExploringCompaction 策略
        • 当文件太老了,老到超过所定义的时间范围(以天为单位)就直接不合并了,但是也会存在问题:在这个最老的 HFile 文件没有 TTL 过期,当用户手动删除该文件时,因为不会发生 Major Compaction,所以这个数据根本就不会真正的删除,而是一直占着磁盘空间
        • 优点:
          • 提高了按时间读取数据时候的效率,因为从指定的时间分区就可以获取数据,而不再需要遍历所有的文件进行查找
          • 防止旧文件和新文件合并在一起,因为新文件往往是热点数据
        • 适用场景:
          • 根据时间排序存储,且专注于读写最新的数据的场景
          • 手动删除可能会失效,所以更适用于那些基本不删除数据的场景
        • 不适合数据频繁改动的场景
      • StripeCompactionPolicy(文件分层合并,综合性能最好)
        • 分层 Compact 是将所有的文件分成多个层(实际只有 2 层),最顶层的叫 L0,其下分别是 L1、L2 依此类推,同一层内各个数据文件覆盖的 rowkey 区间不会重叠,相邻层之间的数据文件可以进行 Compaction
        • 由于区间不重叠每个 key 处于哪个数据文件是确定的,因此 compact 过程中,只需部分文件参与即可,而不需要所有文件参与,有助于提高 compaction 执行效率
        • 新写入的数据会首先落到 L0 层,从 L0 层向下依次执行合并
        • 随着数据的写入,MemStore flush 形成的 hfile 会首先落到 level 0 层,一旦 level 0 层的文件数量超过了用户的设置值,则将这些文件写入到 level 1 层
        • Level 1 层的数据按照 rowkey 覆盖的范围划分成多个互不重叠的区间,每个区间称为 stripe
        • 优点:
          • 由于 level 的存在,get 数据时会从依据 block cache、MemStore、level 0 和 level 1 下 HFile 文件的顺序依次寻找,而 Compact 会细化为 level 0 中的数据上升到 level 1 的过程以及 level 1 层内部数据文件的合并,具体的 Compact 策略复用了前面的 Exploring 策略
          • 每一个 stripe 相当于划分出的 subregion,这样的设计使得 compact 的粒度变细(从 region 细化到 sub-region 级别),冷热数据的 compact 相隔离,避免了 Compact 时一次扫描整个 Region 下所有的 HFile 文件进行合并,提高了执行合并的效率,同时减少因 Compact 带来的阻塞时间
          • 读取链路变长,性能会有损耗,但是提高了查询速度的稳定性
          • 本来要牵涉全部 HFile 才能执行 Major Compaction,现在可以分 Strip 执行了,一次 Major Comapction 只会牵涉一个 Strip 中的所有文件,所以克服了 IO 不稳定的缺点
        • 适合场景:
          • Region 较大。小 region 没有必要切分为 stripes,一旦切分,反而会带来额外的管理开销。一般默认如果 region 大小小于 2G,就不适合使用 stripe compaction
          • RowKey 具有统一格式,stripe compaction 要求所有数据按照 Key 进行切分,切分为多个 stripe。如果 rowkey 不具有统一格式的话,因为数据不均匀分布会导致无法进行切分
  • RowKey 设计原则
    • 唯一性原则:RowKey 必须能够唯一的识别一行数据
    • 长度原则:rowkey 是一个二进制码流,可以是任意字符串,最大长度 64kb ,实际应用中一般为 10-100bytes,以 byte[] 形式保存,一般设计成定长,越短越好,可以降低磁盘占用率,提高 MemStore 的内存利用率,最好符合操作系统位数特性,4/8 的整数倍
    • 散列原则:确保数据均衡分布在各个 RegionServer,避免数据倾斜,影响查询效率
  • 合理的 Region 数量与大小
    • Region 数量
      • 通常较少的 region 数量可使群集运行的更加平稳
      • Region 太多,会降低查询效率,提高 MemStore 往 StoreFile 进行 flush 的频率,提高了 HFile 的 Compact 频率
      • 官方推荐单个 RegionServer 的 Region 数量控制在 20-300 之间
    • Region 大小
      • 如果设置太小,容易出现自动分裂(split),影响集群性能
      • 如果设置太大,自动合并(Compact)的几率会增大,影响集群性能
      • 官方推荐单个 Region 大小控制在 10~30G 之间

Presto

  • Presto 是由 Facebook 开发的开源大数据分布式高性能 SQL 查询引擎,专门为交互式查询所设计,提供分钟级乃至亚秒级低延时的查询性能
  • 结构
    • Client(客户端):提交数据操作的窗口
    • Discovery Server(服务发现者):存储可用的 Server 列表
    • Coordinator(协调者): 接收数据操作,解析 SQL 语句,生成查询计划,分发任务至 Worker 机
    • Connector Plugin(连接插件):连接 Storagr,提供元数据,支持 Hive、Kafka、MySQL、MonogoDB、Redis、JMX 等数据源,可自定义
    • Worker(执行者):执行查询计划
  • 查询流程:
    1. Client 发送请求给 Coordinator
    2. SQL 通过 ANTLR 进行解析生成 AST
    3. AST 通过元数据进行语义解析
    4. 语义解析后的数据生成逻辑执行计划,并且通过规则进行优化
    5. 切分逻辑执行计划为不同 Stage,并调度 Worker 节点去生成 Task
    6. Task 生成相应物理执行计划
    7. 调度完后根据调度结果 Coordinator 将 Stage 串联起来
    8. Worker 执行相应的物理执行计划
    9. Client 不断地向 Coordinator 拉取查询结果,Coordinator 从最终汇聚输出的 Worker 节点拉取查询结果
  • Presto 为何高性能
    • ipeline, 全内存计算
    • SQL 查询计划规则优化
    • 动态代码生成技术
    • 数据调度本地化,注重内存开销效率,优化数据结构,Cache,非精确查询等其它技术
  • 优点:
    • 支持多数据源,如 Hive、Kafka、MySQL、MonogoDB、Redis、JMX 等,也可自己实现 Connector,支持的数据规模大
    • 易用性强,灵活性高,能随意查询数据,高度支持 ANSI SQL,支持 JDBC/ODBC 连接,支持窗口函数,join,聚合,复杂查询等,分析能力极强
    • 处理方式简单,无需预处理,全部后处理,没有冗余数据
  • 缺点:
    • 没有容错能力,当一个 query 分发到多个 Worker 去执行时,当有一个 Worker 因为各种原因查询失败,Master 感知到之后,整个 query 也会失败
    • 内存限制,由于 Presto 是纯内存计算,所以当内存不够时,Presto 并不会将结果 dump 到磁盘上,所以查询也就失败了(新版本的 Presto 已经支持写盘操作)
    • 并行查询,因为所有的 task 都是并行执行,如果其中一台 Worker 因为各种原因查询很慢,那么整个 query 就会变得很慢
    • 并发能力弱,因为全内存操作+内存限制,能同时处理的数据量有限,因而导致并发能力不足
    • 实时性较差,不支持数据的实时导入,偏离线处理

Apache Druid

  • 文档地址
  • 简介
    • Apache Druid 是一个分布式的、支持实时多维 OLAP 分析的数据处理系统
    • 支持高速的数据实时摄入处理
    • 支持实时且灵活的多维数据分析查询
    • 支持根据时间戳对数据进行预聚合摄入和聚合分析
    • 亚秒响应的交互式查询,支持较高并发
  • 结构
    • Master
      • Coordinator:负责集群 Segment 的管理和发布,并确保 Segment 在 Historical 集群中的负载均衡
      • Overlord:负责接受任务、协调任务的分配、创建任务锁以及收集、返回任务运行状态给客户端;在 Coordinator 节点配置 asOverlord,让 Coordinator 具备 Overlord 功能,这样可以减少一个组件的部署和运维
    • Query
      • Router 节点:可选节点,在 Broker 集群之上的 API 网关,有了 Router 节点 Broker 不再是单点服务了,提高了并发查询的能力
      • Broker:负责从客户端接收查询请求,并将查询请求转发给 Historical 节点和 MiddleManager 节点。Broker 节点需要感知 Segment 信息在集群上的分布
    • Data
      • Middle Manager:主要是负责数据索引,生成索引文件,并把索引文件先发布到一个共享的存储系统里
      • Historical:主要负责加载索引文件,同时提供历史数据的查询服务
    • Metastore Storage:用于存储 Druid 的各种元数据信息,属于 Druid 的外部依赖组件,生产环境中可用 MySQL
    • Zookeeper:分布式协调服务,用于节点管理和事件监控
    • Deep Storage:用于存储 Segment 文件供 Historical 节点下载。Deep Storage 不属于 Druid 内部组件,用户可根据系统规模来自定义配置。单节点可用本地磁盘,分布式可用 HDFS
  • 数据结构
    • DataSource:DataSource 是一个逻辑概念,表示 Druid 的基本数据结构,可以理解为关系型数据库中的表。它包含时间、维度和指标三列
      • 时间(TimeStamp):表明每行数据的时间值,默认使用 UTC 时间格式且精确到毫秒级别。这个列是数据聚合与范围查询的重要维度
      • 维度(Dimension):标识数据行的各个类别信息
      • 指标(Metric):用于聚合计算的列,这些指标列通常是一些数字,主要操作包括 Count、Sum 和 Mean 等
    • Segment:Segment 是 Druid 中数据的实际物理存储格式,Druid 正是通过 Segment 实现了对数据的横纵向切割(Slice and Dice)操作
      • 横向:通过参数 segmentGranularity 的设置,将不同时间范围内的数据存储在不同的 Segment 数据块中。这样在指定时间范围内查询时,可以不用扫全表
      • 纵向:即列式存储,对每个列进行切分并压缩,且利用 Bitmap 构建索引从而优化数据访问
  • Druid 为何高性能
    • 数据预聚合
      • Druid 可以按照给定的时间粒度和所有维度列,进行最细粒度的指标聚合运算,并加以保存为原始数据
    • 列式存储
      • 对部分列进行查询时可以显著提高效率
    • Bitmap 索引
      • 利用位图对所有维度列构建索引,可以快速定位数据行
    • mmap
      • 通过内存映射文件的方式加快对于 Segment 的访问
    • 查询结果的中间缓存
      • 支持对于查询级别和 segment 级别的缓存
  • 适合场景
    • 网络流量分析、监控系统、APM
    • 数据运营和营销
    • BI 分析/OLAP
  • 优点:
    • 性能高,列存压缩,预聚合加上倒排索引以及位图索引,亚秒级查询速度,并发能力强
    • 易用性强,支持 JSON 查询,支持 ANSI-SQL,支持 HDFS 离线数据导入,支持 Kafka 实时数据导入,有强大的管理后台工具
    • 支持的数据规模大,扩展性强,占用硬件空间小
    • 支持根据时间戳对数据进行预聚合摄入和聚合分析
    • 并发能力强
  • 缺点:
    • 不支持大表 join
    • 不支持更新

ClickHouse

  • 简介
    • 2016 年 6 月,俄罗斯的搜索引擎 Yandex 公司开源的一款高性能的分布式数据库,C++实现
    • 采用列式存储、多核并行化处理和向量化
    • 支持实时数据写入,能够支持万亿级别的数据量
    • 它在大数据领域没有走 Hadoop 生态,而是采用 Local attached storage 作为存储
  • 优点:
    • 易用性强,支持 ANSI-SQL,支持 MySQL、HDFS 等数据源离线数据导入,支持 Kafka 实时数据导入
    • 并发能力强,查询速度极快(尤其是单表查询),支持索引
    • 关系型数据库,支持批量删除或修改数据
  • 缺点:
    • 不支持二级索引
    • SQL 支持有限

Apache Doris(Palo)

  • 简介
    • 2017 年 8 月,百度公司终于开源的分布式数据分析数据库,在 2018 年贡献给 Apache 社区,并将名字改为 Apache Doris(incubating)进行正式孵化
    • 于列式存储、向量化执行、MVCC 的实现,结合了谷歌 mesa 以及 Impala 的优势
  • 结构
    • Doris 由 frontend(FE)和 backend(BE)组成
      • FE 提供横向扩展和高可用:
        • FE 节点分为 follower 和 observer 两类。各个 FE 之间,通过 bdbje(BerkeleyDB Java Edition)进行 leader 选举,数据同步等工作
        • follower 节点通过选举,其中一个 follower 成为 leader 节点,负责元数据的写入操作。当 leader 节点宕机后,其他 follower 节点会重新选举出一个 leader,保证服务的高可用
        • observer 节点仅从 leader 节点进行元数据同步,不参与选举。可以横向扩展以提供元数据的读服务的扩展性
      • BE 负责数据存储与管理
  • 优点:
    • 易用性强,高度支持 ANSI-SQL
    • 支持数据列式存储,对数据列的动态增减方便
    • BE、FE 的扩容简单
    • 支持离线数据导入(hadoop 和文件)和近实时数据导入(kafka)
  • 缺点:
    • Doris 数据格式支持较简单

Apache Kylin

  • 简介
    • Apache Kylin 是一个开源的分布式分析引擎
    • 提供 Hadoop/Spark 之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据
    • 最初由 eBay Inc 开发并贡献至开源社区
    • 它能在亚秒内查询巨大的 Hive 表
    • Kylin 的核心思想是预计算,将数据按照指定的维度和指标,预先计算出所有可能的查询结果,利用空间换时间来加速查询模式固定的 OLAP 查询
  • 基本原理
    • 利用 MapReduce/Spark 将原始数据进行聚合计算,转成了 OLAP Cube 并加载到 HBase 中,以 Key-Value 的形式存储
    • Cube 按照时间范围划分为多个 segment,每个 segment 是一张 HBase 表,每张表会根据数据大小切分成多个 region
  • 优点:
    • 易用性强,支持 ANSI-SQL,可通过 ODBC,JDBC 以及 RESTful API 进行访问,提供了管理后台
    • 支持百亿、千亿甚至万亿级别交互式分析
    • 查询速度快,Kylin 的 Cube 预处理会大幅减小在线数据规模,对于超大规模数据更有优势
  • 缺点:
    • 多维索引要对多维度的各种组合作预计算,离线建索引需要较大计算量和时间,最终索引也会占用较多磁盘空间

Pinot

  • Pinot 是一个类 druid 的分布式分析引擎。由 LinkedIn 开发和维护
  • 支持离线数据导入(hadoop 和文件)和近实时数据导入(kafka)
  • 结构
    • Pinot Controller
      • 管理集群中的节点
      • 处理 Table 和 Segment 的上的所有创建,更新,删除操作
      • 计算表及其段到 Pinot 服务器的分配
    • PinotServer
      • 保存一个或者多个物理的 Segment
      • 当被分配一个预先创建的 segment,下载并且装载这个 Segment
      • 当被分配一个 Kafka Topic,从 kafka 的 partion 的一个子集中消费数据 执行查询请求并将结果返回给 PinotBroker
    • Pinot Broker
      • 接收客户端的查询请求,并且将他们路由到多个服务上(根据路由策略), 合并接收的查询结果并返回给客户端
  • 优点:
    • 性能高,提供多种压缩模式,如运行长度、固定比特长度
    • 可插入式的索引技术,包括可排序索引、Bitmap 索引和反向索引
    • 数据聚合查询能力和数据写入能力极强,实时性好,近乎实时的从 Kafka 获取数据,以及批量从 Hadoop 获取数据,扩展性强
    • 易用性强,支持 JDBC,有完整的管理工具
  • 缺点:
    • 不支持 join

Apache Impala

  • Impala 是 Cloudera 由 C++编写的基于 MPP(massively parallel processing)理念的查询引擎
  • 由运行在 Apache Hadoop 集群上的不同的守护进程组成,它跟 Hive 的 metastore 集成,共用 database 和 tables 等信息
  • 实时性能一般,只能用于 HDFS 的离线计算

Apache Spark

  • 简介
    • Spark 是一种快速、通用、可扩展的大数据分析引擎,2009 年诞生于加州大学伯克利分校 AMPLab,2010 年开源,2013 年 6 月成为 Apache 孵化项目,2014 年 2 月成为 Apache 顶级项目。项目是用 Scala 进行编写
    • Spark 是基于内存计算的大数据并行计算框架
    • 目前,Spark 生态系统已经发展成为一个包含多个子项目的集合,其中包含 SparkSQL、Spark Streaming、GraphX、MLib、SparkR 等子项目
  • 核心组件
    • Spark Core
      • 实现了 Spark 的基本功能,包含任务调度、内存管理、错误恢复、与存储系统 交互等模块
      • Spark Core 中还包含了对弹性分布式数据集(resilient distributed dataset,简称 RDD)的 API 定义
    • Spark SQL
      • 是 Spark 用来操作结构化数据的程序包。通过 Spark SQL,我们可以使用 SQL 或者 Apache Hive 版本的 SQL 方言(HQL)来查询数据
      • Spark SQL 支持多种数据源,比 如 Hive 表、Parquet 以及 JSON 等
    • Spark Streaming
      • 是 Spark 提供的对实时数据进行流式计算的组件。提供了用来操作数据流的 API,并且与 Spark Core 中的 RDD API 高度对应
    • Spark MLlib
      • 提供常见的机器学习(ML)功能的程序库。包括分类、回归、聚类、协同过滤等,还提供了模型评估、数据 导入等额外的支持功能
    • Cluster Manager
      • Spark 设计为可以高效地在一个计算节点到数千个计算节点之间伸缩计 算。为了实现这样的要求,同时获得最大灵活性,Spark 支持在各种集群管理器(cluster manager)上运行,包括 Hadoop YARN、Apache Mesos,以及 Spark 自带的一个简易调度 器,叫作独立调度器
  • Spark 运行模式
    • Local:多用于本地测试
    • Standalone:即独立模式,自带完整的服务,可单独部署到一个集群中,无需依赖任何其他资源管理系统。它是 Spark 实现的资源调度框架,其主要的节点有 Client 节点、Master 节点和 Worker 节点
    • Spark On Yarn:yarn 是统一的资源管理机制,在上面可以运行多套计算框架,如 map reduce、storm 等根据 driver 在集群中的位置不同,分为 yarn client 和 yarn cluster。生产环境上一般使用 yarn cluster 模式
    • Spark On Mesos:mesos 是一个更强大的分布式资源管理框架,它允许多种不同的框架部署在其上,包括 yarn
  • 结构
    • Client:客户端进程,负责提交作业到 Master
    • Master:Standalone 模式中主控节点,负责接收 Client 提交的作业,管理 Worker,并命令 Worker 启动 Driver 和 Executor,控制整个集群,监控 worker
    • Worker:负责管理本节点的资源,定期向 Master 汇报心跳,接收 Master 的命令,启动 Driver。Executor,即真正执行作业的地方,一个 Executor 可以执行一到多个 Task
    • Driver: 一个 Spark 作业运行时包括一个 Driver 进程,也是作业的主进程,负责作业的解析、生成 Stage 并调度 Task 到 Executor 上。包括 DAGScheduler,TaskScheduler
    • Executor:即真正执行作业的地方,一个集群一般包含多个 Executor,每个 Executor 接收 Driver 的命令 Launch Task,一个 Executor 可以执行一到多个 Task
  • 优点:
    • 速度快
      • 与 Hadoop 的 MapReduce 相比,Spark 基于内存的运算要快 100 倍以上,基于硬盘的运算也要快 10 倍以上。Spark 实现了高效的 DAG 执行引擎,可以通过基于内存来高效处理数据流
    • 易用性强
      • Spark 支持 Java、Python 和 Scala 的 API,还支持超过 80 种高级算法,使用户可以快速构建不同的应用。而且 Spark 支持交互式的 Python 和 Scala 的 shell,可以非常方便地在这些 shell 中使用 Spark 集群来验证解决问题的方法
      • Spark 提供了统一的解决方案。Spark 可以用于批处理、交互式查询(Spark SQL)、实时流处理(Spark Streaming)、机器学习(Spark MLlib)和图计算(GraphX)。这些不同类型的处理都可以在同一个应用中无缝使用
      • Spark 可以非常方便地与其他的开源产品进行融合。比如,Spark 可以使用 Hadoop 的 YARN 和 Apache Mesos 作为它的资源管理和调度器,器,并且可以处理所有 Hadoop 支持的数据,包括 HDFS、HBase 和 Cassandra 等
      • Spark 也可以不依赖于第三方的资源管理和调度器,它实现了 Standalone 作为其内置的资源管理和调度框架,这样进一步降低了 Spark 的使用门槛,使得所有人都可以非常容易地部署和使用 Spark
      • Spark 还提供了在 EC2 上部署 Standalone 的 Spark 集群的工具
  • 缺点:
    • 占用内存过大,不能处理过大的数据

Apache Storm

  • 简介
    • Apache Storm 是一个开源的、实时的、分布式以及具备高容错的分布式实时计算系统
    • Storm 支持水平扩展,具有高容错性
    • 它与 Spark Streaming 的最大区别在于它是逐个处理流式数据事件,而 Spark Streaming 是微批次处理,因此,它比 Spark Streaming 更实时
  • 核心概念
    • Nimbus:即 Storm 的 Master,负责资源分配和任务调度。一个 Storm 集群只有一个 Nimbus
    • Supervisor:即 Storm 的 Slave,负责接收 Nimbus 分配的任务,管理所有 Worker,一个 Supervisor 节点中包含多个 Worker 进程
    • Worker:工作进程,每个工作进程中都有多个 Task
    • Task:任务,在 Storm 集群中每个 Spout 和 Bolt 都由若干个任务(tasks)来执行。每个任务都与一个执行线程相对应
    • Topology:计算拓扑,Storm 的拓扑是对实时计算应用逻辑的封装,它的作用与 MapReduce 的任务(Job)很相似,区别在于 MapReduce 的一个 Job 在得到结果之后总会结束,而拓扑会一直在集群中运行,直到你手动去终止它。拓扑还可以理解成由一系列通过数据流(Stream Grouping)相互关联的 Spout 和 Bolt 组成的的拓扑结构
    • Stream:数据流

Apache Flink

  • 简介
    • Apache Flink 是一款分布式的流式计算引擎,它同时支持了批处理和流处理
    • 支持 java 和 scala api
    • 支持 Kafka、RabbitMq 等多种数据源,也可以自定义扩展数据源,读取其他类型的数据库作为数据源
    • 兼容 Hadoop 的 MapReduce 和 Storm
    • 集成了 Yarn、HDFS、HBase 和其它 hadoop 生态系统的组件

Apache Flume

  • 简介
    • Apache Flume 是 Cloudera 公司开源出来的一个分布式、可靠性和高可用的流式日志采集工具
    • Flume 采用了三层架构,分别为 agent,collector 和 storage,每一层均可以水平扩展。其中,所有 agent 和 collector 由 master 统一管理,这使得系统容易监控和维护,且 master 允许有多个(使用 ZooKeeper 进行管理和负载均衡),避免了单点故障问题
    • FLume 提供对数据进行简单处理并且写到各种数据接收方(可定制)的能力
    • Flume 提供从本地文件(spooling directory source)、实时日志(taildir、exec)、REST 消息、Thift、Avro、Syslog、Kafka 等数据源上收集数据的能力
  • Flume Agent 架构
    • source
      • source 组件是专门用来收集数据的,可以处理各种类型、各种格式的日志数据,包括 avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、http、legacy、自定义数据等
    • channel
      • source 组件把数据收集以后,临时存放在 channel 中,即 channel 组件在 agent 中是专门用来存放临时数据的——对采集到的数据进行简单的缓存,可以存放在 memory、jdbc、file 等
      • Memory Channel:不会持久化。消息存放在内存中,提供高吞吐,但提供可靠性;可能丢失数据
      • File Channel:对数据持久化;基于 WAL(预写式日志 Write-Ahaad Log)实现。但是配置较为麻烦,需要配置数据目录和 checkpoint 目录;不同的 file channel 均需要配置一个 checkpoint 目录,且性能一般
      • JDBC Channel:基于嵌入式 Database 实现。内置 derby 数据库,对 event 进行了持久化,提供高可靠性;可以取代同样持久特性的 file channel
    • sink
      • sink 组件是用于把数据发送大目的地 的组件,目的地包括 hdfs、logger、avro、thrift、ipc、file、null、hbse、solr、自定义
  • 运行机制
    • source 接收到数据之后,将数据发送给 channel
    • channel 作为一个数据缓冲区会临时存放这些数据
    • 随后 sink 会将 channel 中的数据发送到指定的地方——例如 hdfs 等
    • 只有在 sink 将 channel 中的数据发送成功后,channel 才会将临时的数据进行删除,这种机制保证了数据传输的可靠性与安全性

彩虹表

  • 彩虹表是一个用于加密散列函数逆运算的预先计算好的表,常用于破解加密过的密码散列
  • 彩虹表常常用于破解长度固定且包含的字符范围固定的密码(如信用卡、数字等)。这是以空间换时间的典型实践,比暴力破解(Brute force)使用的时间更少,空间更多
  • 但与储存密码空间中的每一个密码及其对应的哈希值(Hash)实现的查找表相比,其花费的时间更多,空间更少
  • 使用加盐的密钥派生函数可以使这种攻击难以实现

IAAS、PAAS、SAAS

介绍地址

  • IaaS:基础设施服务,Infrastructure-as-a-service
    • IaaS 是云服务的最底层,主要提供一些基础资源。它与 PaaS 的区别是,用户需要自己控制底层,实现基础设施的使用逻辑
    • 案例:Amazon EC2、RackSpace Cloud 等
  • PaaS:平台服务,Platform-as-a-service
    • PaaS 提供软件部署平台(runtime),抽象掉了硬件和操作系统细节,可以无缝地扩展(scaling)。开发者只需要关注自己的业务逻辑,不需要关注底层
    • 案例:Google App Engine、OpenShift 等
  • SaaS:软件服务,Software-as-a-service
    • SaaS 是软件的开发、管理、部署都交给第三方,不需要关心技术问题,可以拿来即用
    • 案例:Google Apps、Facebook / Twitter / Instagram 等
  • SaaS 模式下用户没有任何自主权,只能使用给定的应用程序
  • PaaS 模式下可以自己安装应用程序,但是不能定制操作系统
  • IaaS 模式下则是云服务商提供(虚拟的)硬件,从操作系统开始都可以自己选择和定制