gitbook/数据中台实战课/docs/229940.md
2022-09-03 22:05:03 +08:00

223 lines
22 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 11 | 怎么一劳永逸地解决数据安全问题?
你好,我是郭忆。
在前面的课程中,我们了解了数据中台在数据建设效率、质量和成本方面的内容。而除了快、准和省以外,数据中台还必须是安全的。因为如果不安全,你很可能出现和“微盟删库跑路”同样的事情。所以,为了让你能重视数据中台的数据安全,我简单说一下这件事儿的情况。
2020年2月23日19点国内最大的精准营销服务商微盟出现了大面积的系统故障旗下300万商户的线上业务全部停止商铺后台的所有数据被清零。始作俑者是一位运维人员他在生产环境数据库进行了删库操作而刚刚上市不久的微盟就因此遭受了巨大的损失从2月23日宕机以来市值已经蒸发了30亿港元。这件事儿堪称史上最贵的安全事件。
那么从微盟的教训中,我们能得到什么警醒呢?在数据中台中怎么防止出现类似的事件呢? 我想这或许是你需要认真思考的内容。安全问题可大可小,不出事情,你可能根本不会重视,但是一旦出现事故,就是灾难性的。在网易,我们对数据中台的安全管理是非常严格的。
在刚开始构建网易数据中台的时候,我们就重点考虑了数据中台的安全保障,我把它归结为五大法宝。
![](https://static001.geekbang.org/resource/image/b2/f3/b2fc3e4ff33a32feef34f224e0f434f3.jpg)
接下来,我就带你深入分析一下,希望学完这部分内容之后,你可以回答这样三个问题:
* 如何解决数据误删除问题;
* 如何解决敏感数据泄露问题;
* 如何解决开发和生产物理隔离问题。
它们是你在数据中台建设中一定会面临的,学完之后,你一定可以找到解决这些问题的方法。
**机制一:数据备份与恢复**
对于绝大多数的企业数据中台的数据都存储在HDFS中即使是实时的数据存储于Kafka也会归档一份到HDFS因为要保存历史数据进行回算或者补数据。**所以我们要解决的核心问题是HDFS 的数据备份。**
网易HDFS 数据的备份是基于HDFS 快照 + DistCp + EC实现的。
![](https://static001.geekbang.org/resource/image/5a/db/5ae3dde9024db601ce1cc872de35d0db.jpg "网易数据备份的架构图")
我们分为线上集群和冷备集群两个集群数据加工任务访问的是线上集群存储采用的是HDFS默认的3副本。而冷备集群主要考虑到存储成本的因素采用的是EC 存储。
![](https://static001.geekbang.org/resource/image/1f/88/1f210c06cd54528ad03d19799b69d088.jpg "EC 存储原理示意图")
**为了让你了解EC存储的基本原理我多说几句。**其实Hadoop 在3.x就正式引入了EC 存储,它是一种基于纠删码实现的数据容错机制,通过将数据进行分块,然后基于一定的算法计算一些冗余的校验块,当其中一部分数据块丢失的时候,可以通过这些冗余的校验块和剩余的数据块,恢复出丢失的数据块。
这么说可能不太形象我做个比喻。比如有三个数据块分别存储的是1、2和3。我们非常担心其中一个数据块坏了丢失内容。所以增加了一个块这个块存储的内容是前面三个数据块之和。那么如果其中任意一个数据块坏了我们可以根据现有的数据块计算出丢失的数据块内容。 比如1丢失了我们可以根据6-3-2计算出1当然这个只是最简单的EC 算法只能容忍一个数据块丢失实际的EC算法要再复杂一些 。
关于EC 具体的算法细节不是本节课的重点不过我在文末提供了一个链接你可以课下研究一下。在这里我只想告诉你的是EC 存储在不降低可靠性的前提下与HDFS 3副本可靠性相同通过牺牲了一定的计算性能因为计算校验块需要消耗额外的计算资源将数据存储成本降低了一半非常适合低频访问的冷数据的存储而备份数据就是这种类型的数据。
**那线上集群的数据又是如何同步到冷备集群的呢?**
在回答这个问题前,你有必要先了解一下快照的基本原理,因为这样你才能理解后续的数据同步流程。
Hadoop 在2.x版本就已经支持了对某个文件或者目录创建快照你可以在几秒内完成一个快照操作。在做快照前你首先要对某个目录或者文件启用快照此时对应目录下面会生成一个.snapshot的文件夹。
![](https://static001.geekbang.org/resource/image/93/58/936a5ab8ff49edefc8fff146b6cb9958.jpg)
在上图中, 我们对/helloword目录启用快照然后创建一个s1的备份。此时在.snapshot下存在s1文件。然后我们删除/helloword/animal/lion 文件时HDFS 会在animal 目录创建differ文件并把diifer文件关联到s1备份最后把lion文件移动到differ目录下。
通过这个案例我们不难发现HDFS 快照实际只记录了产生快照时刻之后的,所有的文件和目录的变化,非常适合每天只有少数文件被更新的数据中台,代价和成本也很低。
有了快照之后我们就需要把快照拷贝到冷备集群中这里选择的是Hadoop 自带的DistCp。为什么考虑DistCp 呢因为它支持增量数据的同步。它有一个differ参数可以对比两个快照仅拷贝增量的数据。同时DistCp是基于MapReduce 框架实现的数据同步工具可以充分利用Hadoop分布式计算的能力保证数据的拷贝性能。
我提供给你一张详细的图,透过这张图,你可以看到具体的数据从线上集群拷贝到冷备集群的流程。
![](https://static001.geekbang.org/resource/image/94/92/94dbe40ed0d79d205cb52fab5d2ece92.jpg)
首先对于第一次开始数据备份的文件我们会先创建一个快照然后利用DistCp 拷贝全量的备份数据到冷备集群。然后后续的每一天我们都会定时生成一个快照并和前一天的快照基于distcp --differ 参数进行对比,将有更新的部分再同步到冷备集群。同步完成以后,会删除前一天的快照,这样就完成了每日数据的增量同步。
这里需要特别注意的是拷贝数据会对线上I/O 产生比较大的压力所以尽量在任务运行的低峰期进行同步比如白天12点到晚上24点之间的时间同时DistCp的bandwidth参数可以限制同步的速率你可以根据I/O 负载和数据同步速率动态调整。比如说I/O 利用率100%应该限制数据拷贝带宽为10MB/s。
讲到这儿,你已经了解了数据中台中,文件目录的备份了,但是光这些还不够,我们还需要备份数据的产出任务,表相关的信息:
* 任务的备份,要保存任务代码、任务的依赖关系、任务的调度配置以及任务的告警、稽核监控等信息;
* 表的备份主要是备份表的创建语句。
在网易,我们提供了产品化的解决方案,数据开发可以在我们提供的数据管理平台上,选择一张表,创建备份,然后系统就会自动地完成任务、文件和表的备份。平台也提供了一键恢复的功能,系统会自动地帮数据开发创建任务和表,拷贝数据从冷备集群到线上集群。
那么你可能会有疑问:什么样的数据应该备份呢? **在我看来,数据的备份策略应该和数据资产等级打通,对于核心数据资产,数据中台应该强制进行备份。**
那假如说,数据没有备份,但我们误删除了,还有没有其他的补救方法呢? 你可以试一下接下来地的这个机制。
**机制二:垃圾回收箱设计**
HDFS 本身提供了垃圾回收站的功能对于意外删除的文件可以在指定时间内进行恢复通过在Core-site.xml中添加如下配置就可以开启了默认是关闭状态。
```
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
```
当HDFS 一旦开启垃圾回收功能后用户通过命令行执行rm 文件操作的时候HDFS 会将文件移到/user/\[用户名\]/.trash/current/ 目录下。这个目录下的文件会在fs.trash.interval 配置的时间过期后被系统自动删除。当你需要恢复文件的时候,只需要把/user/\[用户名\]/.trash/current/被删除文件移到要恢复的目录即可。
**听到这儿你是不是感觉问题已经解决了呢但是我想强调的是HDFS垃圾回收机制在实际应用过程中存在重大的缺陷。**因为它只能支持通过命令行执行rm操作对于在代码中通过HDFS API调用Delete接口时会直接删除文件垃圾回收机制并不生效。尤其是我们在Hive中执行drop table删除一个Hive内表此时删除的数据文件并不会进入trash目录会存在巨大的安全隐患。
![](https://static001.geekbang.org/resource/image/d9/fe/d91b36b36c8b150a28a5080cc5c318fe.jpg "改造后 HDFS 回收站原理示意图")
那你要怎么解决呢我建议你可以对HDFS的Client 进行修改对Delete API通过配置项控制改成跟rm相同的语义。也就是说把文件移到trash目录。对于Hive 上的HDFS Client 进行了替换这样可以确保用户通过drop table 删除表和数据时数据文件能够正常进入HDFS trash目录。
**通过这种方式,你可以解决数据误删除的问题。**但HDFS 回收站不宜保留时间过长因为回收站中的数据还是三副本配置会占用过多的存储空间。所以我给出的一个配合解决方案是回收站保留24小时内的数据。这样解决的是数据还没来得及被同步到冷备集群误删除的情况。对于一天以上的数据恢复建议采取基于冷备集群的数据备份来恢复。
好了,讲完如何解决数据的误删除之后,接下来我们来解决第二个问题,就是如何避免敏感数据的泄露,而这离不开精细化的权限管理。
**机制三:精细化的权限管理**
数据权限是数据中台实现数据复用的前提和必要条件。如果刚开始系统没有开启权限,后期接入权限,任务的改造成本会非常高的,几乎涉及到所有的任务。**所以权限这个问题,在数据中台构建之初,必须提前规划好。**
网易数据中台支撑技术体系是基于OpenLDAP + Kerberos + Ranger 实现的一体化用户、认证、权限管理体系。
![](https://static001.geekbang.org/resource/image/b2/55/b206938aec70551a9d2784c453aae755.jpg "网易数据中台用户、认证、权限系统架构
")
试想一下如果有几千台机器却没有一个统一的用户管理服务当我们想添加一个用户时需要到几千台服务器上去创建初始化用户这个管理和运维的效率有多低。而OpenLDAP就帮我们解决了这个问题。
OpenLDAP是一个轻量化的目录服务数据以树型结构进行存储能够提供高性能的查询服务非常适合用户管理的场景。
![](https://static001.geekbang.org/resource/image/23/2d/23cd128afadafa2e31f8249ad3f93c2d.jpg "OpenLDAP 树型目录架构示意图
")
在OpenLDAP中我们可以创建用户User和组(Group)对于每个用户会有唯一的uid对于每个组通过Memberuid我们可以添加一个用户到一个组中。
在网易大数据平台上注册一个用户平台会自动生成一个OpenLDAP的用户当该用户加入某个项目时会将该项目对应的Group下增加一个Memberuid。假设在上图中甄漂亮加入了da\_music项目那么在da\_music 的Group下会增加Memberuid:1002。同理当甄美丽加入某个角色时在对应角色的Group下也会有甄美丽对应的Memberuid。
那Hadoop 又是怎么跟OpenLDAP集成的呢
Hadoop 可以使用LdapGroupsMappings 同步LDAP创建的用户和用户组这样当我们在LDAP中添加用户和组时会自动同步到Hadoop集群内的所有机器上。
**通过这个方式,你就可以解决用户管理的问题了,而接下来要解决的就是认证的问题。**在非安全网络中除了客户端要证明自己是谁对于服务端而言同样也需要证明我是我。为了实现双向的认证我们在生产环境启用了安全等级最高的基于共享密钥实现的Kerberos认证。
说起Kerberos认证的原理我想举一个有趣的例子。
你肯定去过游乐场吧! 为了进游乐场,首先你需要提供你的身份证,实名购买一张与你身份绑定的门票。在进入游乐场之后呢,每个游乐设施前,都有一个票据授权机器,你需要刷一下你的门票,授权机器会生成一个该游乐设施的票据,你拿着这个票据就可以玩这个游乐设施了。
当然,当你想玩另外一个游乐设施的时候,同样需要刷一下你们的门票,生成对应游乐设施的票据。而且你的门票是有有效期的,在有效期内,你可以尽情地玩游乐设施,一旦超过有效期,你需要重新购买你的门票。
![](https://static001.geekbang.org/resource/image/0d/0d/0ddf10ccb97b12cd25e8e1fe88dfd90d.jpg "Kerberos 认证原理示意图
")
Kerberos认证与上面这个故事类似在上面的故事中TGTTicket-granting ticket可以看作是门票Client首先使用自己的密钥文件Keytab和用户标识Principal去认证服务器AS购买TGT认证服务器确认是合法的用户Client会获得TGT而这个TGT使用了TGSTicket-granting service的Keytab加密所以Client是没办法伪造的。
在访问每个Server前Client需要去票据授权服务TGS刷一下TGT获取每个服务的票据STST使用了Client要访问的Server的Keytab加密里面包含了TGS 认证的用户信息Client是无法伪造ST的。
最后基于每个服务的票据以及客户端自己生成的加密客户认证信息Autenticator访问每个服务。每个Server都有归属于自己的KeytabServer只有使用Server自己的Keytab才能解密票据ST这就避免了Client传给了错误的Server。
与此同时解密后票据中包含TGS认证的客户信息通过与Authenticator 中Client生成的客户信息进行对比如果是一致的就认为Client是认证通过的。
一般在Hadoop中我们会使用Kinit 工具完成TGT的获取TGT 一般保存24小时内。**我介绍Kerberos原理其实是想让你知道Kerberos对于Hadoop集群来说是一个非常安全的认证实现机制我推荐你使用Kerberos 实现Hadoop集群的安全认证。**
你可能会问Kerberos 使用的是Principal标识用户的它又是怎么和OpenLDAP中的用户打通的呢 其实我们访问HDFS使用的是PrincipalHadoop可以通过配置hadoop.security.auth\_to\_local将Principal映射为系统中的OpenLDAP的用户。用户注册时平台会为每一个新注册的用户生成Principal以及相对应的Keytab文件。
认证完成之后呢就要解决哪些客户可以访问哪些数据的问题了。我推荐你使用Ranger来解决权限管理的问题。
**为什么要选择Ranger呢**因为Ranger 提供了细粒度的权限控制Hive列级别基于策略的访问控制机制支持丰富的组件以及与Kerberos的良好集成。权限管理的本质可以抽象成一个模型“用户-资源-权限”。
数据就是资源,权限的本质是解决哪些人对哪些资源有权限。
![](https://static001.geekbang.org/resource/image/d1/93/d1407e801aa4e89f54bbc8e2e2384093.jpg)
在Ranger中保存了很多策略每一个资源都对应了一条策略对于每个策略中包含了很多组许可每个一个许可标识哪个用户或者组拥有CRUD权限。
讲完了用户、认证和权限实现机制,那你可能会问,**权限的申请流程是什么样子的呢?**
在数据中台中每一张表都有对应的负责人当我们在数据地图中找到我们想要的数据的时候可以直接申请表的访问权限然后就会发起一个权限申请的工单。表的负责人可以选择授权或者拒绝申请。申请通过后就可以基于我们自己的Keytab访问该表了。
**另外,需要特别强调的是,**由于数据中台中会有一些涉及商业机密的核心数据,所以数据权限要根据数据资产等级,制订不同的授权策略,会涉及到不同的权限审批流程,对于一级机密文件,可能需要数据中台负责人来审批,对于一般的表,只需要表的负责人审批就可以了。
## 机制四:操作审计机制
进行到第三步,权限控制的时候,其实已经大幅降低了数据泄露的风险了,但是一旦真的出现了数据泄露,我们必须能够追查到到底谁泄露了数据,所以,数据中台必须具备审计的功能。
![](https://static001.geekbang.org/resource/image/e6/e4/e60423e0a54035a06dc0885a67fc99e4.jpg)
由于用户每次访问数据都要对权限进行验证所以在校验权限的同时可以获取用户访问表的记录Ranger支持审计的功能用户的访问记录会由部署在各个服务HDFSHBase等等上的插件推送到Audit Server上然后存储在Solr中Ranger提供了API接口查询表的访问记录。但是必须指出的是Ranger开启Audit 后,会对服务内的插件性能产生影响。
除了敏感数据泄露的风险,我还看到一些企业想要对开发和生产环境进行物理隔离。为什么企业会有这个诉求呢?
首先,很多传统公司的数据开发都是外包人员,从企业的角度,不希望数据开发直接使用生产环境的数据进行测试,从安全角度,他们希望生产和测试从物理集群上完全隔离,数据脱敏以后,给开发环境进行数据测试。
其次涉及一些基础设施层面的组件升级比如HDFS、Yarn、Hive、Spark等贸然直接在生产环境升级往往会造成兼容性的事故所以从安全性的角度企业需要有灰度环境而用开发环境承担灰度环境的职能是一个不错的选择。
最后,虽然可以为生产和开发环境设置不同的库和队列,从而实现隔离,避免开发任务影响线上任务和数据,但会导致任务上线需要改动代码,所以最理想的,还是实现开发和生产环境两套集群,同一套代码,在开发环境对应的就是开发集群,提交上线后,就发布到生产集群。
这些就是企业希望开发和生产集群物理隔离的原因,那我们接下来看一看该如何满足。
## 机制五:开发和生产集群物理隔离
在面对这个需求时,我们遇到了两类完全不同的企业群体。
一部分来自传统企业,尤其是金融行业,他们对安全性的要求远大于对效率的诉求,严格禁止数据开发使用线上数据进行测试,他们希望有两套完全不同的环境,包括操作平台,任务在开发环境进行开发,配置任务依赖,设置稽核规则和报警,然后由运维人员进行审核后,一键发布到生产环境。当数据开发需要对数据进行测试时,可以同步生产环境的局部数据(部分分区),数据会进行脱敏。
![](https://static001.geekbang.org/resource/image/01/b2/01844c9d1a63f2874bf2a6ffdb8e3eb2.jpg)
上图是该模式下的部署架构。
通过这张图我们可以看到,开发和测试环境本身是两套完全独立的平台,因为每次数据测试,都需要同步生产环境的数据,所以这种模式下,数据开发的效率会有比较大的影响,但是优势在于对数据安全实现了最高级别的保护。
与这部分客户不同的是,很多企业需要同时兼顾安全和效率,他们没有办法接受同步生产环境数据,而是需要在开发环境能够直接使用线上的数据进行测试。
![](https://static001.geekbang.org/resource/image/99/c8/99e170d0a50a6a8718987556c04697c8.jpg)
上图展示了该模式下的部署架构。
我们可以看到大数据平台和任务调度系统Azkaban都是一套然后HiveYarn和HDFS都是两套两套集群通过Metastore 共享元数据。
这样做的一个好处在于一个集群的Hive可以直接访问另外一个集群的数据。在同一个Metastore中开发环境的数据在\_dev库中生产环境的数据在\_online库中用户在代码中不需要指定库在任务执行时根据运行环境自动匹配库。例如在开发环境执行Hive默认会使用\_dev库下的表而在生产环境执行Hive默认会使用\_online库下的表从而实现了不需要改代码可以实现一键发布。
上面两种部署模式,你可以根据你所在的企业实际情况进行选择,对安全性要求高,推荐第一种方案,对于效率要求高,同时兼顾一定的安全性,就推荐第二种方案。
## 课堂总结
以上就是这节课的全部内容了,总的来说,我为你介绍了解决数据中台安全问题的五大制胜法宝,相信通过这些保障机制,你可以解决数据中台遇到的安全问题了。最后,我再强调几个重点:
* 数据备份要同时兼顾备份的性能和成本推荐采用EC存储作为备份集群的存储策略
* 数据权限要实现精细化管理基于OpenLDAP+Kerberos+Ranger可以实现一体化用户、认证、权限管理
* 开发和生产环境物理隔离,我提到了两种部署模式,需要综合权衡效率和安全进行选择。
![](https://static001.geekbang.org/resource/image/ba/26/babcbf9505bfcc8156469e888ddd8826.jpg)
## 思考时间
在课程的最后,我还是留一个思考题,来与你进行互动。
引入权限管理,势必会对数据研发效率产生影响,同时已有的任务必须重构,进行认证改造。你是如何思考安全和效率之间的优先关系的? 欢迎在留言区与我互动。
最后,感谢你的阅读,如果这节课让你有所收获,也欢迎你将它分享给更多的朋友。
**HDFS EC 存储介绍:**
[https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/HDFSErasureCoding.html](https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/HDFSErasureCoding.html)