HDFS文件系统以及Hbase、Cassendra、TiDB比较

HDFS
HDFS设计目标
  • 存储非常大的文件:这里非常大指的是几百M、G、或者TB级别。实际应用中已有很多集群存储的数据达到PB级别。根据Hadoop官网,Yahoo!的Hadoop集群约有10万颗CPU,运行在4万个机器节点上。更多世界上的Hadoop集群使用情况,参考Hadoop官网.
  • 采用流式的数据访问方式: HDFS基于这样的一个假设:最有效的数据处理模式是一次写入、多次读取数据集经常从数据源生成或者拷贝一次,然后在其上做很多分析工作
    分析工作经常读取其中的大部分数据,即使不是全部。 因此读取整个数据集所需时间比读取第一条记录的延时更重要。
  • 运行于商业硬件上: Hadoop不需要特别贵的、reliable的机器,可运行于普通商用机器(可以从多家供应商采购) 商用机器不代表低端机器在集群中(尤其是大的集群),节点失败率是比较高的HDFS的目标是确保集群在节点失败的时候不会让用户感觉到明显的中断。

有些场景不适合使用HDFS来存储数据。下面列举几个:

  1. 低延时的数据访问
    对延时要求在毫秒级别的应用,不适合采用HDFS。HDFS是为高吞吐数据传输设计的,因此可能牺牲延时HBase更适合低延时的数据访问。
  2. 大量小文件
    文件的元数据(如目录结构,文件block的节点列表,block-node mapping)保存在NameNode的内存中, 整个文件系统的文件数量会受限于NameNode的内存大小。
    经验而言,一个文件/目录/文件块一般占有150字节的元数据内存空间。如果有100万个文件,每个文件占用1个文件块,则需要大约300M的内存。因此十亿级别的文件数量在现有商用机器上难以支持。
  3. 多方读写,需要任意的文件修改
    HDFS采用追加(append-only)的方式写入数据。不支持文件任意offset的修改。不支持多个写入器(writer)。
    1. 小文件过多,会过多占用namenode的内存,并浪费block。
      1. 文件的元数据(包括文件被分成了哪些blocks,每个block存储在哪些服务器的哪个block块上),都是存储在namenode上的。
        HDFS的每个文件、目录、数据块占用150B,因此300M内存情况下,只能存储不超过300M/150=2M个文件/目录/数据块的元数据
      2. dataNode会向NameNode发送两种类型的报告:增量报告和全量报告。
        增量报告是当dataNode接收到block或者删除block时,会向nameNode报告。
        全量报告是周期性的,NN处理100万的block报告需要1s左右,这1s左右NN会被锁住,其它的请求会被阻塞。
    2. 文件过小,寻道时间大于数据读写时间,这不符合HDFS的设计:
      HDFS为了使数据的传输速度和硬盘的传输速度接近,则设计将寻道时间相对最小化,将block的大小设置的比较大,这样读写数据块的时间将远大于寻道时间,接近于硬盘的传输速度。
HDFS文件目录

在这里插入图片描述
HDFS文件目录主要由NameNode、SecondaryNameNode和DataNode组成
HDFS(Hadoop Distributed File System)默认的存储单位是128M的数据块

NameNode的文件结构如下

name
├── current
│ ├── edits_0000000000000000001-0000000000000000002
│ ├── edits_0000000000000000003-0000000000000000003
│ ├── edits_0000000000000000004-0000000000000000005
│ ├── edits_0000000000000000006-0000000000000000006
│ ├── edits_0000000000000000007-0000000000000000008
│ ├── edits_0000000000000000009-0000000000000000010
│ ├── edits_0000000000000000011-0000000000000000012
│ ├── edits_0000000000000000013-0000000000000000014
│ ├── edits_0000000000000000015-0000000000000000016
│ ├── edits_0000000000000000017-0000000000000000018
│ ├── edits_0000000000000000019-0000000000000000020
│ ├── edits_inprogress_0000000000000000021
│ ├── fsimage_0000000000000000000
│ ├── fsimage_0000000000000000000.md5
│ ├── fsimage_0000000000000000020
│ ├── fsimage_0000000000000000020.md5
│ ├── seen_txid
│ └── VERSION
└── in_use.lock

NameNode文件结构包括edits、fsimage、seen_txid、VERSION

  • 编辑日志(edit log):当客户端执行写操作时,首先NameNode会在编辑日志中写下记录,并在内存中保存一个文件系统元数据,这个描述符会在编辑日志改动之后更新。
  • edits_start transaction ID-end transaction IDfinalized edit log segments,在HA(高可用)环境中,Standby Namenode只能读取finalized log segments
  • edits_inprogress__start transaction ID
    当前正在被追加的edit log,HDFS默认会为该文件提前申请1MB空间以提升性能
  • fsimage是文件系统元数据的持久检查点.
  • Seen_txid存放transactionId

DataNode的文件结构主要由blk_前缀文件、BP-random integer-NameNode-IP Addr-creation time和VERSION组成

  • BP-random integer-NameNode-IP Addr-creation time:
    BP代表BlockPool,即唯一的blockpoolID
  • Finalized/rbm
    这两个目录都用用于实际存储HDFS BLOCK的数据,里面包含许多的block_xx文件以及相应的元数据文件,rbm用于存储用户当前正在写入的数据
  • blk_前缀文件
    存储原始文件内容

当目录中存储的块数据量增加到一定规模时,DataNode会创建一个新的目录,用于保存新的块及元数据。当目录中的块数据量达到64(可由dfs.DataNode.numblocks属性确定)时,便会新建一个子目录,这样就会形成一个更宽的文件树结构,避免了由于存储大量数据块而导致目录很深,使检索性能免受影响。通过这样的措施,数据节点可以确保每个目录中的文件块都可控的,也避免了一个目录中存在过多文件。

HDFS文件导出
  • 关系型数据库使用sqoop
  • NoSQL特别是HBase自带Export类
  • 导入数据仓库Hive直接可以用SQL语句完成
暂时的结论
  1. Hadoop及HDFS,其设计的初衷是批处理,大量数据的Map-Reduce。而实时计算,并不擅长,要考虑Storm之类流式计算框架。
  2. HDFS适合存储大问题,ChunkSize通常64M,非常不适合小文件,比如我们几M大小的图片。
  3. HDFS生态链相对好
  4. HDFS要设置NameNode,通过master-slave的方式来备份容灾。
其它FS选型

TFS:腾讯淘宝文件系统,淘宝内部应用海量的图片小文件放到tfs上。比较符合当前的业务场景,但是社区不活跃,相关资料很少。实际用的时候如果遇到bug可能很棘手。

其它思路
  • 进行小文件的合并然后存在HDFS(麻烦,但是可以根据业务尝试,可以利用Hbase实现HDFS小文件的合并)
总结

从开发的便捷性和生态链考虑还是选择HDFS最好,但要手动进行小文件合并

Hbase、TiDB适用场景以及相关生态
Hbase
基本简介

HBase 是一个开源的 非关系型分布式数据库(NoSQL),它参考了 谷歌 的 BigTable 建模,实现的编程语言为 Java。它是 Apache 软件基金会的 Hadoop 项目的一部分,运行于 HDFS 文件系统之上,为 Hadoop 提供类似于 BigTable 规模的服务。因此,它可以 容错地 存储 海量稀疏 的数据。

特性
  • 大:一个表可以有数十亿行,上百万列;
  • 无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列;
  • 面向列:面向列(族)的存储和权限控制,列(族)独立检索;
  • 稀疏:空(null)列并不占用存储空间,表可以设计的非常稀疏;
  • 数据多版本:每个单元中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳;
  • 数据类型单一:Hbase中的数据都是字符串,没有类型。
优势
  • Hbase作为一个NoSQL,在性能上不如Memcached和Redis,但是强在持久化存储
  • Hbase是在Hadoop生态链中与HDFS、MR、Spark结合最好的
  • 数据强一致,数据零丢失
缺点
  • 太依赖Hadoop和HDFS
  • 高并发读写效率相对低
TiDB
基本简介
特性
  • 大数据量下MySQL复杂查询(兼容MySQL),大数据量下时延相对更小
  • 水平扩展,不用分库分表,业务侵入性较小
  • 高并发实时写入、实时查询、实时统计分析
  • 使用 TiSpark 兼容OLAP场景
  • 批量写入与读取效率高
  • 不适合存储超宽表(单行数据不超过64k),若列过多建议分表存储
  • 多线程GC
使用场景
  • MySQL分片分表
  • 直接替代MySQL
  • 数据仓库
  • OLTP + OLAP场景
  • TiKV可以单独作为一个 HBase 的 Replacement 来用
生态
  • TiDB
  • TiKV
  • TiSpark
  • TiDB-Ansible: 自动部署(支持裸机及云部署)
  • TiDB-docker-compose: docker部署方案
    • 安全地扩展TiDB集群
    • 滚动更新TiDB群集
    • 多租户支持: 用户可以轻松地在单个Kubernetes集群上部署和管理多个TiDB集群
    • 自动故障转移
  • TiDB-operator
  • Syncer: MySQL 到 TiDB 间的实时同步工具
  • Binlog: 收集TiDB二进制日志
    • 数据复制: 将数据从TiDB群集同步到异构数据库。
    • 实时备份(可增量备份)和恢复
    • 多种输出格式:支持MySQL,转储文件等
    • 历史重播
    • Lightning: 大量数据快速导入 TiDB 工具
    • TiDB Vision: 数据可视化
    • Prometheus: TiDB 后台监控
已存在HDFS中的解析成结果数据

在处理来自 Hadoop 的原始的、经过处理的数据时,需要获得 Hadoop 作业的文件输出。与导出时一样,应该确保您的 Hadoop 作业以您可以有效读回的格式输出信息。

导入到 SQL

使用 CSV 既简单又直观,但对于更复杂的结构,也可以考虑使用 JSON 格式,因为它使整个转换和翻译过程变得非常容易。
要获取该信息,需要使用 HDFS 工具将输出文件放回您可以执行加载的文件系统中 — 例如 $ hdfs dfs -copyToLocal processed_logs/*。拥有这些文件后,就可以使用适合来源信息和结构的方法来加载信息。

从 Sqoop 中导出

与导入过程一样,Sqoop 提供了一种将信息从 Hadoop 作业转换回 SQL 表的简化方法。

从 Sqoop 中输出结果信息时,对于最简单的导出,可以采用 CSV 格式。然后,要导入该信息,需要创建一个合适的表来接受经过处理的日志。例如,从我们的访问日志可以看出,Hadoop 输出已将该数据映射到操作次数摘要中,所以必须先创建一个合适的表:CREATE TABLE summary_logs (operation CHAR(80), count int)。然后,可以直接将信息从 Hadoop 导入到您的 SQL 表中

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值