底层存储:hadoop(hdfs+mapreduce)
Hadoop已经有十几年的历史,它是大数据领域的存储基石,HDFS目前仍然没有成熟替代品;MapR 文件系统在业内已经具有一定知名度了,不仅 MapR 宣布它自己的文件系统比 HDFS 快2-5倍(实际上有 20 倍),它还具有镜像、快照、高性能这些企业用户喜欢的特点。
Hadoop中的计算模型MapReduce已经退出历史舞台,被Spark接管(Hadoop的核心技术在Google那里已经过时,因为Hadoop并不擅长处理“快数据”)
hdfs角色管理
【NameNode】存储文件的元数据,如文件名,文件目录结构,文件属性(生成时间、副本数、文件权限),以及每个文件的块列表和块所在的DataNode
【DataNode】在本地文件系统存储文件块数据,以及块数据的校验和。基本单位是块(block),默认128M。
【SecondaryNameNode】用来监控HDFS状态的辅助后台程序,每隔一段时间获取HDFS元数据的快照
客户端利用利用MapReduce描述数据计算和处理的任务细节,交给hadoop的Yarn;Yarn则调度多台物理机的CPU完成计算,然后存储的hdfs中,常见操作有Map(映射)、Reduce(归约)
hdfs存在瓶颈
当hadoop集群较大时,文件量级达到数亿以上时,namenode 性能会成为一个潜在的瓶颈点。文件数达到4亿/10亿左右时NameNode基本达到瓶颈。随着元数据规模的上涨,其QPS存在下降的趋势
HDFS往往采用3副本的方式创建,存储空间利用率低。使用自建Haddop集群,严重依赖硬件资源,很难做到资源的弹性伸缩,成本和效益上捉襟见肘,比如规模超过数百台,
80%左右的数据为温冷数据,HDFS集群缺少自动化的冷热分层机制
容灾备份困难,一但集群挂掉意味着数据全部丢失。如果构建数据容灾集群,需要在另一个机房搭建同样的一套hadoop集群。
Hadoop架构迭代难,兼容性很差,业务低谷时计算资源利用率低,缺少弹性,需要进行存算分离改造
不适合低延迟数据访问、无法高效存储大量小文件、不支持多用户写入及任意修改文件
OSS对象存储
OSS对象存储作为大数据存算分离方案的核心存储方案,在元数据操作管理能力上深度优化,为大数据场景提供海量数据的存储管理能力、超高的吞吐带宽性能,解决用户自建HDFS存储的扩展性瓶颈和管理难题。
OSS存储支持海量的数据存储,高达Tbps级别的吞吐能力,可以避免HDFS的Namenode性能瓶颈问题
esProc SP
【需求背景】
同一个库中管理太多历史数据时也容易造成混乱
而分拆到多个库的运维成本又会上升,还难以混合计算
有些场景因为安全原因也不方便把数据上搬到公有云上,而在企业内部建设一套存算分离的云数据库就会太沉重了
【存算分离】
我们知道,文件是最便宜最方便的存储方案。历史数据通常不再变化,数据之间不再有约束性和一致性的耦合性问题,存成文件后很方便分目录管理,可以随意根据情况搬动位置。比如存储到网络文件系统或 HDFS 或是云存储中获得共享能力以及超强的可靠性。
esProc SPL 可以将把历史数据转储成文件,并提供文件上的计算能力
应用中的计算能力目前主要由数据库提供,要计算数据就需要依赖于数据库;
数据库通常是个存算不分离的封闭体系,不能仅仅使用其计算能力随意计算指定的数据。
esProc SPL 是个更好的轻量级解决方法,它同时能满足上述两个方面,即不依赖于数据库的计算能力以及天然的存算分离机制。
esProc SPL 本身就是个计算引擎,天然支持存算分离。基于这些成熟的第三方存储方案,可以充分利用这些技术带来的可靠性和安全性以及便利的可共享能力
数据通道:flume+kafka+sqoop
sqoop:
sqoop是和Hive一起使用的。Sqoop(发音:skup)是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysql、postgresql…)间进行数据的传递,可以将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS中,也可以将HDFS的数据导进到关系型数据库中
关系框架:hbase+hive
全量表:如前面ODS讲到的,如果我们是全量把数据导入到ODS的,我们会根据业务需要,如果是缓慢变化的,或者确认这种变化后对我们的业务作用基本可以忽略不计的,我们通常就采取全量的方式存储,这样的存储方式其实是和ODS里面一样的。
现状表:即数据的当前、最新状态的表;基本上可以认为是目前的数据不变;
历史表:即保存数据的历史变更记录,通过这个记录可以还原出数据的所有变更情况;
快照表:有无变化,都要报 ;数据量大的时候,其实每个分区都存储了许多重复的数据,非常的浪费存储空间,快照表就是以时间为粒度(比如天),生成每个时间的全量数据快照;流水表则是记录数据的每一条具体的改变。
流水表:是每天的交易形成的历史; 流水表用于统计业务相关情况,拉链表用于统计账户及客户的情况
增量表:就是把新增的数据存储下来,或者说变化的数据存储下来,一般来说,这是当前一种主要的存储形态
hbase可以自定义函数做统计的maprecude嘛
拉链表:拉链表对快照表进行了优化,根据拉链粒度(一般为时间)的不同,去除了在粒度范围内不变的数据。存储的时候,有一些不变的数据不进行存储;
1、拉链表可以维护两个时间(start_time, end_time),来标识当前记录是否还有效,以及更好的定位历史数据
2、拉链表本质上适合与缓慢变化的大量数据集
3、拉链表当然也会遇到查询性能的问题,比如说我们存放了5年的拉链数据,那么这张表势必会比较大,当查询的时候性能就比较低了,个人认为两个思路来解决:
其文件系统中的文件是不能做改变的,也就是说Hive的表只能进行删除和添加操作,而不能进行update
在一些查询引擎中,我们对start_date和end_date做索引,这样能提高不少性能。
保留部分历史数据,比如说我们一张表里面存放全量的拉链表数据,然后再对外暴露一张只提供近3个月数据的拉链表。
hive与mysql
数据库是用于处理实时数据的系统,而数据仓库则是用于存储历史数据并支持分析功能的系统。
数据仓库中的数据通常是批处理和预处理的,这意味着数据会按照特定的时间间隔进行更新,例如每天或每周
Hive在处理大规模数据时表现更加优异。Hive是为处理大数据而设计的,可以处理数千万甚至数十亿的数据。而MySQL则更适用于小规模数据的处理,处理大规模数据时性能会有所下降
Hive当涉及到多表连接查询时,Hive的性能会更好,MySQL在单表查询时的速度比Hive更快但是;因为Hive可以在Hadoop集群上分布式地处理数据,使用数据分区来提高查询速度。可以将数据分成多个分区,每个分区可以在不同的节点上处理,从而提高查询效率,而MySQL则需要在单个服务器上处理数据。查询的时候MapReduce,将sql拆分成多个语句最后分别计算或计算再合并计算或不计算
Hive是基于Hadoop分布式文件系统的,它的数据存储在Hadoop分布式文件系统中。Hive本身是没有专门的数据存储格式,也没有为数据建立索引,只需要在创建表的时候告诉Hive数据中的列分隔符和行分隔符,Hive就可以解析数据。所以往Hive表里面导入数据只是简单的将数据移动到表所在的目录中!
hive与hbase
将全量数据存储在Hbase中,现状数据另存一份到Hive中。
查询历史数据有两种方案,一种是 Hbase 表通过外表的方式映射成对应的Hive表,应用层通过类sql的方式查询对应的Hbase库
另一种搭建 Phoenix 环境,应用层通过类sql方式访问Phoenix 关联的Hbase数据库
hbase格式
habse储的数据是以列族为单位进行存储的,是完全将行数据按列族的方式进行分列。
比如:row_key作为时间维度,存储了几个不同维度的字段;hbase的存在很适合维度表的完成!
1 、 row :一行数据包含一个唯一标识 Row-Key 、多个 column 以及对应的值。在 HBase 中,一张表中所有 row 都按照 Row-Key 的字典序(二进制位移计算)由小到大排序。
2 、 column :与关系型数据库中的列不同, HBase 中的 column 由 column family (列簇)以及 qualifier (列名)两部分组成。column family 在表创建的时候需要指定,用户不能随意增减。column family 下可以设置任意多个 qualifier ,因此可以理解为 HBase 中的列可以动态增加。
3 、 cell :单元格,由五元组( row , column , timestamp , type , value )组成的结构,其中 type 表示 Put/Delete 这样的操作类型, timestamp 代表这个 cell 的版本。这个结构在数据库中实际是以 KV 结构存储的,其中( row , column , timestamp , type )是 K , value 字段对应 KV 结构的 V 。
4 、 timestamp :每个 cell 在写入 HBase 的时候都会默认分配一个时间戳作为该 cell 的版本, HBase 支持多版本特性,即同一 Row-Key 、 column 下可以有多个 value 存在,这些 value 使用 timestamp 作为版本号。
【表 1 逻辑存储视图】
【表 2 物理存储视图】
5、底层存储
HBase 的逻辑存储视图由行键、时间戳、列族组成一个类似二维表一样的结构,但是在实际存储的时候,数据库存,如图 Table1 、 Table2 中均有多个 Region ,这些 Region 分布在不同的 RegionServer 中。
Region 虽然是分布式分布式存储的最小单元,但并不是存储的最小单元
Store 是存储的最小单元。Region 由一个或者多个 Store 组成,每个 Store 会保存一个 Column Family 每个 Store 又由一个 MemStore 或 0 至多个 Hfile 组成;MemStore 存储在内存中, HFile 存储在 HDFS 中。
我们知道 LSM-Tree 相比较 B+Tree 而言,最大的特点就是在于通过牺牲部分读性能,利用分层合并的思想,将小树合并为大树,将无序数据合并为有序数据,然后统一刷入磁盘,从而大大提高了写的性能
hbase场景
日志处理:HBase适用于存储和分析大量的日志数据,如网络日志、服务器日志等。HBase的快速读写能力和可扩展性,使其成为处理实时日志数据的理想选择。
实时分析:HBase可以用于存储和查询实时分析数据,例如网站用户活动数据、电子商务交易数据等。HBase的高性能和近实时的查询能力,使其成为处理实时分析的优秀工具。
时序数据存储:HBase适用于存储和查询大规模的时序数据,如传感器数据、监控数据等。HBase的列族和版本控制功能,使其能够高效地存储和查询时间序列数据。
社交网络数据存储:HBase可以用于存储和查询大规模的社交网络数据,如用户关系图、用户行为数据等。HBase的高扩展性和灵活的数据模型,使其能够存储和处理复杂的社交网络数据。
机器学习数据存储:HBase可以用于存储和查询大规模的机器学习数据,如训练数据、特征向量等。HBase的高性能和可扩展性,使其成为处理机器学习数据的理想选择。
hbase使用
put '表名','行键','列族:列限定符','单元格值',时间戳
delete '表名','行键','列族<:列限定符>',<时间戳>
get '表名','行键','列族:列限定符',时间戳
get 'student','001' get 'student','001',{COLUMN=>'Grades'}
scan '表名',{< '列族:列限定符',时间戳>}
扫描全表:scan '表名'
指定列族名称 :scan 'student', {COLUMN=>'stuinfo'}
指定列族和列的名称 :scan 'student', {COLUMN=>'stuInfo:Name'}
指定输出行数 : scan 'student', {LIMIT => 1}
指定输出行键范围 : scan 'student', {STARTROW =>'001',ENDROW => '003'}
指定组合条件查询 : scan 'student', {COLUMN=>'stuinfo',STARTROW =>'001',ENDROW => '002'}
hbase特点
HBase 中的行是按照 Row-Key 的字典顺序排序的,这种设计优化了扫描操作,可以将相关的行存放在临近位置,便于扫描。然而糟糕的 Row-Key 设计是热点的源头。一旦由于 Row-Key 设计与业务场景不相符,大量访问会使热点 region 所在的单个机器超出自身承受能力,引起性能下降甚至不可用,这也会影响同一个 RegionServer 上的其他 region 。
那么如何避免这样的问题发生呢?通常会有以下几种设计思想可供参考:
1 、反转:将 Row-Key 的字符串可变的部分提到前面,相对固定的部分提到后面。这样就会打乱 Row-Key 的有序性,在一定程度上降低了批量数据写的性能,但是读的时候就会减少热点查询,通过牺牲部分写的性能而提升读的性能。
2 、前缀:将每一个 Row-Key 加一个随机字符前缀,使得数据分散在多个不同的 Region ,达到 Region 负载均衡的目标。最终消除局部热点,解决热点读写的问题。
3 、散列:通过哈希散列的方式将 Row-Key 重新设计,使得数据分散在不同的 Region ,同时效果要比前缀的方式更好,因为在读的时候,它是可以通过哈希的计算减少读性能的损耗。既解决了热点问题,同时也不必消耗太多的读性能。
计算框架:
Storm流式计算框架(适用于实时高效的运算,通常配合kafka消息组件使用)
Impala计算引擎(此项是在hadoop的数据节点基础上构建的新一代高效查询引擎,根据查询数据情况的差异下,效率比mapreduce或hive快几倍到几十倍不等)
Spark内存计算框架(这个可以把数据加载到内存中,可以配合pandas之类的数据分析组件对数据进行处理)
Filnk流式计算框架
数据成品:es+mysql
数据分层规划:
【事实表】
基于一个实体所创建的表,比如系统日志、销售记录等。事实表的记录在不断地增长,比如电商的商品订单表,就是类似的情况,所以事实表的体积通常是远大于其他表。
【维度表】
基于某个属性抽取所就创建的表,比如日期,地点、非常适合列式存储=>>>日期表(存储与日期对应的周、月、季度等的属性)、地点表(包含国家、省/州、城市等属性)等。
多个事实表,可以按照共同属性拆成维度表
数据贴源层ODS
Operation Data Store 数据准备区,也称为贴源层。数据源中的数据,经过抽取、洗净、传输,也就是ETL过程之后进入本层。为了考虑后续可能需要追溯数据问题,因此对于这一层就不建议做过多的数据清洗工作,原封不动地接入原始数据即可
【数据来源】
业务库:sqoop定时抽取数据;实时方面考虑使用canal监听mysql的binlog日志,实时接入即可
埋点日志:日志一般是以文件的形式保存,可以选择使用flume来定时同步;可以使用spark streaming或者Flink、Kafka来实时接入
消息队列:来自ActiveMQ、Kafka的数据等
数据细节层DWD
该层是业务层和数据仓库的隔离层,保持和ODS层一样的数据颗粒度;主要是对ODS数据层做一些数据的清洗和规范化的操作,比如去除空数据、脏数据、离群值等。
为了提高数据明细层的易用性,该层通常会才采用一些维度退化方法,将维度退化至事实表中,减少事实表和维表的关联。
数据中间层DWM
该层是在DWD层的数据基础上,对数据做一些轻微的聚合操作(简单来说,对通用的核心维度进行聚合操作,算出相应的统计指标),生成一些列的中间结果表,提升公共指标的复用性,减少重复加工的工作。
数据服务层DWS(应用层)
该层是基于DWM上的基础数据,整合汇总成分析某一个主题域的数据服务层,一般是宽表,用于提供后续的业务查询,OLAP分析,数据分发等。
一般来说,该层的数据表会相对较少;一张表会涵盖比较多的业务内容,由于其字段较多,因此一般也会称该层的表为宽表。
数据应用层ADS(应用层)
该层主要是提供给数据产品和数据分析使用的数据,一般会存放在ES、Redis、PostgreSql等系统中供线上系统使用;也可能存放在hive或者Druid中,供数据分析和数据挖掘使用,比如常用的数据报表就是存在这里的。
最常见的三种数据仓库建模体系分别为:规范化数据仓库,维度建模数据仓库,独立数据集市
1、星形模式(属性拆出)
2、雪花模式(维度子表)
3、星座模式(事实共用维度)
数据集市
维度数据集市
非维度建模数据仓库(dimensionally modeled data warehouse)是一种使用交错维度进行建模的数据仓库,其总体架构如下图所示:
该建模体系首先设计一组常用的度集合(conformed dimension),然后创建一个大星座模型表示所有分析型数据。如果这种一致维度不满足某些数据分析要求,自然也可在数据仓库之上继续构建新的数据集市。
部门数据集市
规范化数据仓库(normalized data warehouse)顾名思义,其中是规范化设计的分析型数据库,然后基于这个数据库为统一ETL各部门建立数据集市。总体架构如下图所示:
该建模体系首先对ETL得到的数据进行ER建模,关系建模,得到一个规范化的数据库模式。然后用这个中心数据库为公司各部门建立基于维度建模的数据集市。各部门开发人员大都从这些数据集市提数,通常来说不允许直接访问中心数据库。
独立数据集市
独立数据集市的建模体系是让公司的各个组织自己创建并完成ETL,自己维护自己的数据集市
从技术上来讲这是一种很不值得推崇的方式,因为将使信息分散,影响了企业全局范围内数据分析的效率。此外,各组织之间的ETL架构相互独立无法复用,也浪费了企业的开发资源。然而出于某些公司制度及预算方面的考虑,有时也会使用到这种建模体系。