导读:数据治理是一个很大的话题,本文将主要介绍存储服务相关工作,聚焦成本治理。文章主要分两大部分,四个小节:第一部分:主要讲述小米数据治理的演进过程,从高层视角来看小米的数据治理是如何开展的:1. 朴素数据治理;2. 用大数据治理大数据。第二部分:聚焦团队的工作,如成本优化等具体内容:1. HDFS 的治理实践;2. HBase 的治理实践。
01 朴素数据治理
数据治理的内涵是不断丰富的,把时间倒回到 2018 年,小米刚开始做数据治理的时候,当时对数据治理的认识是很朴素的,数据治理就等于成本治理。
公司随着业务发展、组织架构调整、交接不规范、商务谈判等等,都会造成资源上的浪费。起初不多,治理的价值不高,大家更多的精力还是放在满足业务需要上。到 2018 年这个时间点,治理已经可以有不错的收益了,值得投入一些人力去治理了。
具体如何去做成本治理呢?简单说就是“抓大放小”。先盘点哪些服务的成本最高,再找出哪些集群的成本是最高的,然后每个负责人就各自领自己的治理任务,推进成本优化。
这么做的好处在于:目标清晰、简单高效。一方面,积累到 2018 年已经有不少浪费了,抓大放小的治理有很好的效果。另一方面,当时的工作重点仍在满足业务需求上,不能让治理动作消耗太多人力,目标是:投入有限的人力和时间快速取得结果。
这样做也存在一些问题:
1. 不可观测
成本、资源利用率不可观测,看不到就不会有成本意识,没有及时反馈,就会容易松懈,最终演变为运动式治理,每年年初搞一次。
2. 各自算帐
各个服务负责人要自己去算账,算账的口径不统一,比如算节约了多少钱,有的用的是商务价格,有的用的是内部账单价格,有的用的是过保价格,有的算的是相比去年同期节约了多少钱,有的算的是相比未来年底增长节约了多少钱。
3. 分工不合理
存储平台作为底层平台,和业务中间还隔着好几层,但是我们背着治理的指标,就需要去找业务沟通,效率不是很高,成本优化技术研发工作也被 delay 了。
02 用大数据治理大数据
随着公司发展,大数据治理的内涵也在发生了变化,治理不再只是成本治理,同时相比运动式治理我们更需要长期生效的治理,于是治理发展到了新阶段,即用大数据治理大数据,做到数据资产化、可衡量。
新阶段的数据治理要解决哪些问题呢?第一个还是成本问题,第二个是数据质量差问题,比如某个团队产生的数据表,其他团队正好需要,但他们不敢用,因为他们不知道数据质量怎么样,对方是不是还在维护这张表,是不是能按时产出,即可能存在时效性的问题。业务方只能自己产出和维护一份同样的表,于是有引入了重复建设的问题。最后是安全隐私问题,平台侧的审查还不够完善。
针对以上问题,我们希望能够用一套通用的方法,把这些问题统一管控。
解决办法就是用大数据治理大数据,简单说就是三步走。
第一步,建元仓。
所有服务都要把自己的元数据接入到元仓中,可以看到 Yarn、Hive、HBase、主机和集群信息等等,都接入到元仓中。这一步做到了统一口径,服务节约多少钱都以元仓为准。另一点是有据可查,所有参与的人都能看到服务和集群的成本以及资源利用率。
第二步,定特征。
有了数据,就可以定特征。特征是一系列规则,用于筛选出不合理的使用,比如产出表未被读取、表存在相似数据、存储生命周期设置的不合理、表没有 owner 没有负责人等等。特征是服务方和业务方一起沟通后定下来的,每天会带着这些特征扫描元仓,把有问题的表找出来。
第三步,产品化。
知道了哪些表有问题,下一步就是如何去触达用户。这里我们设计了一个治理产品,把所有的数据都换算成健康分,然后通过一个网页让业务的负责人,包括他们的大老板,可以直接看到健康度怎么样。同时要给一些治理建议,比如开启自动冷备,治理完成后分数就涨上来了。
存储平台作为数据治理的一环,承接成本治理工作,对应到 3 步里是:元数据接入、提供特征、提供治理技术方案。
今年上半年我们用了 2 个多月的时间把这套方法落地了,主机数减少了23.8%,主机成本降低了 38.9%,主机成本降的比主机多是因为下的是比较贵的机器。
以上介绍了小米在数据治理方面的演进过程,接下来介绍存储平台在成本治理中具体做了哪些工作,我们做的成本治理的技术对应到前端优化都有哪些治理建议。
03 HDFS 的治理实践
首先介绍一下 HDFS 的治理实践。
HDFS 治理策略是冷热分层,低成本存储技术有很多,包括:高密度、Hadoop 3 EC、在高密度机器上做 EC 等等,选型时要结合小米自身业务特点。小米的特点是集群全球部署,海外都是直接部署在公有云上。公有云不提供高密度机器,公有云上最便宜的存储是对象存储,所以海外成本治理一定要围绕对象来做。又考虑到全球统一架构,集中开发人力,我们最终选择了 Tiering 方案,把冷数据保存到对象存储里,在国内和海外是同一套方案。
具体做法:
(1)Tiering 在 HDFS 中引入了对象文件,它没有块,只是记录了一系列对象 uri。
(2)所有文件在刚写入的时候都是基于块的文件,保存在 DN 上。
(3)治理服务会周期地扫描特征,发现要治理的文件后,发送给 NN,NN在 INode 上打一个标记。我们部署了一个服务定期解析 image,把这些文件找出来,转为对象文件。
(3)转对象的过程是通过 spark 任务完成的,它先把文件读出来拆成对象写入,并在文件写完后发送 RPC 给 NN。NN 会新建一个对象 INode 把原来的 INode 替换掉,原来的 INode 会在 safeBox 中保存一段时间。
下面是读的过程:
(1)左侧是正常用户读,先从 NN 获取地址,再去 DN 读数据。
(2)Tiering 的读流程是一样的,右侧小人也是先去 NN 拿地址,不过这次拿到的是一个假的块 id,和随机选择的 proxy dn 地址,之后 client 去 proxy dn 读数据。Proxy dn 是一组没有盘的 DN,只负责读 Tiering 文件。收到请求后,它会解析出 object uri,并去对象存储把内容读出来,返回给用户。Proxy DN 上要做带宽控制,一是限制单个 DN 的流量,二是限制专线流量。因为在国内我们的部署方式是物理机房+公有云,Client 和对象存储一个在 IDC 一个在公有云,通过专线相连,是要做限速的。海外没有这个问题,海外的 client 和对象存储在同一个 az。
(3)有一些特殊情况要处理,比如 transform 成功后,原文件要被删掉。如果有一些 client 缓存了地址或是正在读,就会失败。对于失败处理的逻辑要修改下,否则会报 blkId 不匹配。另一点是短路读,HDFS 短路读是通过 Domain Socket 在进程间传递fd,从而直接读块文件。但是 proxy dn 是没有 fd 的,和 client 在一起也不能短路读。最好是关掉,不关闭也没关系,短路读失败会自动重试,走网络读。
下面介绍 HDFS 的治理策略,如何自动化地做冷热分层。因为 HDFS 上大部分保存的是结构化的表,所以自动化治理完全是基于结构化数据。对于非结构化数据,我们先看其能否被当作一张表来治理,如果不能的话就先不治理了。
对于结构化的表要怎么治理呢?我们先判断表的创建时间,如果是 93 天以内创建的,那这个表还很新,先不治理它,给它打个 80 分。如果超过了 93 天,我们要治理它,先看看这张表有没有分区。如果没有分区,那就只能整表来看最近 93 天有没有访问,没有访问的话推给用户建议他治理。如果有分区,情况会好一些,我们逐个分区去看最近访问情况。这是我们要把表分为两类,一类是不可再生的表,比如原始日志,原始日志我们是可以从血缘关系里找出来的,或是计算起来极其麻烦资源耗费很大的表,这些表被列为不可再生表。除此之外都是可再生表,出了问题我们可以重新计算。我们要求用户必须给自己的表设置 ttv 和 ttl,ttv 就是建议访问周期,ttl是生命周期。对于不可再生表,如果超过 ttv 没超过 ttl,就是温数据,保存到对象里,如果超过 ttl 就直接删掉。对于可再生表,如果超过 ttv 没超过 2 倍 ttv 就是温数据,超过 2 倍 ttv 就是冷数据,都保存到对象里,区别是一旦数据转冷,就要用对象的归档类型,不支持直接访问,读之前需要先恢复。
04 HBase 的治理实践
接下来介绍 HBase 的治理。
HBase 在小米应用很广泛,主要是用在在线场景,作为在线的数据库,保存索引、IOT 指令、消息等等。在线场景对延迟有要求,所以我们大部分集群使用的都是 SSD。HBase 的治理思路也是冷热分离,比 SSD 便宜的存储方式包括:HDD、Tiering、HDFS EC、高密度机器。
不同存储方式要服务不同的场景,HBase 的场景比 HDFS 要复杂,下面介绍不同场景如何选择冷存储方案。
场景1:一致性要求高的备集群和离线集群
小米主备集群用 replication 同步,数据存在不一致。备集群分两种,一种是容灾用的,即一致性要求高的备集群。另一种是解决可用性问题的,即可用性要求高的备集群。
对一致性要求高的业务仅在主集群彻底无法访问时,比如机房网络全都断掉了,或是机房起火了,才会切换到备集群,切换后业务方允许大部分有一定恢复时间,因此我们可以用比较便宜的存储来保存备集群数据,只要能在一定时间恢复到 SSD 上就行。
离线集群指用来跑 Spark、Hive 作业的集群,都是离线作业性能要求不高。
针对这两种情况,我们都采用 Tiering 保存 HFile。WAL 仍使用三副本方式写入,不会因为写得慢阻塞同步。Tiering的性能在做全表 scan 时和 HDD 一致,Get 时比HDD 慢 22 倍,高延迟高吞吐,用在这里是合适的。
场景2:可用性要求高的备集群
对于可用性要求高的备集群,当主集群发生故障,用户需要马上切到备集群继续提供服务。这时用 Tiering 就不合适了,我们采用 EC 的方式,提供和主集群相近的性能,同时牺牲一些毛刺。
场景3:HBase 中的在线表
第三类场景是一些在线表保存了时序数据。我们可以通过时间戳对数据冷热进行划分,以 HFile 为粒度进行冷备。在国内我们采用 HDD 存储,海外采用 Tiering。
其实这里国内的选择不止 HDD,也可以选择 Tiering、EC+ 高密度等等。
场景4&5:迁移到离线,归档删除
还有两个小的场景,对于只写不读的在线表,我们会建议用户把表迁移到离线集群去,使用 Tiering 保存 HFile。对于 7 天无读无写的在线表,或是 1 年无读无写的离线表,我们建议用户直接把表删掉。因为我们面对的是在线业务,且没有血缘能统计出表是不是可再生,删除数据需要很谨慎,我们一般是先归档保存一份,再删除。
Hbase 的治理思路如上图所示。首先 HBase 这里我们没有统计血缘,没办法看出来表是不是可再生,首先我们判断表是不是无用表。长期无读无写的,建议归档后删掉。无读有写的在线表,建议保留但是迁移到离线集群。对于所有需要长期保存的表,如果是离线集群就全部 Tiering 转存到对象,如果是可用性要求高备集群就 EC,如果是一致性要求高备集群就 Tiering,如果是时序表就在表内做冷热分离。
HBase 的实例节约了 16.6% 的机器。