360回扫样本存储系统Xstore的设计与实践

2019 年 11 月 14 日

360回扫样本存储系统Xstore的设计与实践

今天为大家梳理了一下在【360 互联网技术训练营第 16 期——大数据与微服务之路】上,360 核心安全高级服务端开发工程师高吴林涧分享的《基于 Hadoop 的回扫样本存储系统 XStore 的设计与实践》。本文是具体内容,希望能对大家有所帮助。


为何我们需要一个样本存储系统


1 核心安全流程概述


在 360 用户安全中,云查杀占着很大的比重,除了贡献大量的查杀结果之外,也节省了用户的计算资源。云查杀的大体流程是:


如果用户检测一个尚未被收录的样本文件(pc 文件,安卓 apk 软件包等),那么用户会将样本上传至样本存储系统, 然后检测大流程会使用多类的扫描器,对样本文件进行查杀,返回查杀结果,并记录


如果用户检测一个已经收录的样本文件,那么直接从云查杀中返回这个样本文件的黑白情况。


以上流程大致可以表示为下图:



2 存储系统主要用途


在这里,我们以安卓手机软件(.apk)为例。新收集的 apk 软件 会直接落地在存储系统中。存储系统主要为了满足 3 个使用需求:


1.APK 样本实时上传收集


2.对 APK 样本实时检测服务提供样本文件下载服务


3.一旦样本检测的扫描器/模型/规则发生变化, 则对已收集的样本进行回溯扫描



基于这样的功能性需求,我们设计并开发了样本存储系统 Xstore。


3 目标存储文件的特征


在设计具体的系统架构之前,我们有必要对这个样本文件存储系统所要存储的目标对象做一个特征的分析,以便更好地设计出贴合实际需求的架构。


依旧以占比较大、较典型的 apk 样本作为例子。我们待存储的 apk 样本有如下特征:


  • 大小:单个文件平均大小50M,波动在10k至3G之间,总容量为10-100PB这个量级

  • 数量:总量在10-100亿级别,每日增量为百万级别

  • 以写入和读取为主,几乎不更新,无物理删除

  • 读取方式为随机+顺序读取

  • 高价值,要求提供容灾和备份方法


4 存储系统的非功能性需求


在考虑了存储目标的特性和功能需求之后,我们得出了这个系统所需要满足的非功能性需求。


  • 实时存取:需要提供易用性高的实时性存取接口

  • Hadoop友好:为了方便使用MR/YARN/SPARK进行批量扫描,系统需要Hadoop易用

  • 可水平扩展的存储空间和计算资源

  • 强备份需求、容灾需求

  • 优秀的顺序读取性能,以满足频繁的批量扫描需求

  • 高安全性


基于以上提到的功能性和非功能性需求,我们就可以开始设计一个满足这些需求的存储系统架构了。


Xstore 存储系统的技术选型


我们最终选择 HDFS 来满足下列黄色的需求。然而 HDFS 对下列红色的需求支持确实不好。



1 核心存储技术栈


于是我们考虑使用 HDFS+HBase 的方式,来存储底层的数据。使用 HDFS 存储样本文件本身。使用 HBase 来存储样本文件的元信息。


在 HDFS 中,由于受文件数的限制,我们将样本进行了合并,暨在一个大文件中,存储若干个小文件。这些小文件的偏移量由 HBase 记录。整体的存储内容结构看起来如下图:



在 HDFS 中


我们在一个大小约为 2G(可配置)的.mrg 文件中,存储了若干个样本块。每个样本块包含样本头文件信息,和样本文件本身的二进制内容。每个样本块如同乐高积木一样叠拼成一个整体。


在长度为 256 字节的头文件中,记录了样本文件的实际偏移量、文件实际长度、校验位、文件名等信息。这使得我们可以通过样本的头文件直接进行样本文件的遍历。


在 HBase 中


记录文件长度、文件偏移量等头文件中拥有的信息用于随机读取。同时也记录了诸如上传状态、合并状态等标记位信息,方便业务上进行状态判断或者业务扩展。


2 抽象例子


在这里,引入一个抽象的例子方便理解这样设计的目的和初衷。


咱们抛开之前所有的技术话题不谈,想一个抽象的例子来方便更好地理解这个架构形式:


假设我们需要设计一个住宿小区,小区有两个主要的需求,一个是挨家挨户收取物业费,另一个是对顽固不交的业主,按照其业主姓名,上门收取物业费。

显而易见,为了容纳更多的人,同时占地面积足够小,小区内肯定不能是平房。而是采用楼房的形式,将一户一户人家叠在一起。但是楼房有个问题是,没有办法精准的定位一户人家。所以如常识所见,我们给每个在楼房里的住户,都标记了门牌号,诸如3单元904等。

与此同时,为了方便管理每个户主和其门牌号的对应关系,我们用一张表格进行记录。Key为户主姓名,value为对应的门牌号(哪个楼几单元几零几)。

在收取相应的物业费时,我们既可以直接挨家挨户的按着门牌号逐户收取,也可以通过查询户主信息表,对某个户主专门收取。


这个抽象例子其实跟我们 Xstore 的组件组织方式,是如出一辙的。



Xstore 存储系统架构图



根据以上的技术栈使用方法以及对应的业务需求,我们最终的得出了如下的 Xstore 存储系统架构图。下面我们自底向上的进行每层系统的解释。


1 数据层


这一层主要负责原始组件的接入。我们主要使用的组件包括之前提到的 HBase 和 HDFS,以及尚未提到的用于提供分布式文件锁功能的 ZooKeeper。数据层负责将原始的组件进行简单的封装,并向上层暴露组件自己本身的接口,诸如文件的 get/put ,hbase key 的 get 等。


2 存储逻辑层


对于底层暴露原始接口的数据层,存储逻辑层主要负责对其原始接口进行二次封装,以便进行业务上的整合。这里主要提供了以下三个接口服务:


1.文件头协议:设计实现了文件头,存储文件相关信息。


2.文件合并:将文件头+文件内容作为一个块,合并到固定文件中


3.文件索引服:根据文件 key 等信息,从 HBase 中查询相关信息。


3 数据访问层


在逻辑层之上,是数据访问层。这一层负责实际对数据的访问。对外暴露可以作为单独服务进行的接口。接口实际操作底层数据层的数据,以数据逻辑层作为媒介。主要提供的数据访问接口有:


1.文件寻址服务:通过文件的 key 和逻辑层的索引服务,对外提供文件 key 到 HDFS 实际路径的映射关系查询


2.冗余备份处理:使用基于 HDFS 的冗余备份,实现存储文件的备份处理


3.分布式文件锁:使用 ZooKeeper,提供 HDFS 文件操作时候的分布式文件锁


4.文件的增删改查处理


4 网络层


在对外提供服务时,我们引入了文件分片传输,以方便网络 IO 的均衡,也减小了传输包的差异性。同时使用 RPC 对外提供类似的文件服务以补充 HTTP 协议的不足。负载均衡搭建在下载前端机之上,保证整个服务的稳定性


5 服务封装


在线部分我们提供了 http/rpc 相关的接口,以及 PHP 和 Python 的 sdk 支持。而离线部分,我们基于 Hadoop,提供了回扫管理器、调度器等子系统。


服务现状


Xstore 上线一年以来,存储了约 10 亿个、21PB 的样本文件。每日增量约 140 万个、30TB 的样本文件。类型包括 apk、elf、qex、沙箱产出、pc 训练样本等等,服务项目约 20 余个。


  • 在线业务部分,日均吞吐约20TB, QPS 2-3k,每日约两千万次文件请求。

  • 离线业务部分,Xstore回扫服务了17个组内组外业务,响应扫描器迭代,为扫描器产出保驾护航。全量apk样本回扫可在5小时内完成。


优化改进实例


已有的架构能够满足基本的功能需求,但是经常会因为底层存储组件 HBase 或者 HDFS 的故障(诸如访问缓慢,resionserver 切换需要时间等),从而引起业务方在上传样本时候出现卡顿或者服务停滞。为了解决这个问题,我们着手进行了 Web 服务架构上的改进。


先来看一下现有的 Web 在线服务架构图:



当用户上传样本文件时,首先通过域名解析和负载均衡将具体请求转发到某一前端机上。然后在前端机上,我们部署了 Xstore 的文件存储服务,将通过 HTTP 等协议收到的文件包,流式的直接写入 HDFS,并操作更改 HBase。这样的好处是显而易见的,文件不落盘,不会对本地磁盘 IO 造成过多的负担。与此同时由于不过多更改用户上传的包,所以文件的一致性得到了保证。


但是这样架构的缺点也是明显的。首先,过长的数据链条使得整个业务流程变得易碎。样本包文件要经过负载均衡 ,前端 Web 机,HDFS 等诸多组件。其中单个组件的故障会直接影响到这个包的落地。于此同时,这个架构方式将原本服务于离线的 HDFS 和 HBase 变得在线化了,这对组件实时性要求变高的同时,也违背了我们的设计初衷。


于是我们重新组织了在线部分的系统架构,得到了如下的架构图:



我们可以看到,在文件存储服务和前端机之间,我们搭建了一套文件缓存服务。这个文件缓存服务的用途主要是:


1.接受 Web 前端机收到的文件,并且形成文件队列,异步的写入 Xstore 底层存储


2.除了支持上传文件的接受以外,也同时提供 HTTP 的文件下载服务。根据文件的 key,查询其实际的存储机器/路径/地址,并提供这个文件的下载 url。


在这次 tradeoff 中,我们牺牲了磁盘存储空间和 Xstore 归档的实时性,换来的是对底层存储组件的低依赖和访问速度的保证。


优化之后的用户时序图如下:



其他业务相关的优化策略,就不在本文的讨论范围之内了。


本文转载自公众号 360 云计算(ID:hulktalk)。


原文链接:


https://mp.weixin.qq.com/s/ZSxV10xvbJSu7z8OsaXDhA


2019 年 11 月 14 日 16:36130

评论

发布
暂无评论
发现更多内容

架构师训练营Lesson2-Homework

强哥

极客大学架构师训练营 依赖倒置

架构师训练营第二周作业

fenix

架构师训练营 第二周【作业】

小K

架构师训练营第二周【作业】

atlasman

学习心得

蒜泥精英

架构师第二课总结

Dennis

架构师实现架构目标的主要手段(第2周学习总结)

李德政

极客大学架构师训练营

第二周作业

重新来过

架构师训练营第二周总结

15359861984

2020-06-13-第二周学习总结

路易斯李李李

架构师第二周作业

跨域刀

极客大学架构师训练营

第二周总结

跨域刀

极客大学架构师训练营

架构师训练营第二周作业

草原上的奔跑

Python 核心技术与实践 string

Bonaparte

Python string

架构师训练营 - 第二周学习总结

清风徐徐

<<架构师训练营>> 第二周作业

0x12FD16B

依赖倒置

wei

架构师训练营第二周学习总结

人世间

极客大学架构师训练营

架构师训练营-第二周作业

清风徐徐

单例模式 极客大学架构师训练营 组合模式

依赖倒置原则的个人理解

潜默闻雨

隔离原则优化 Cache 类的设计

潜默闻雨

学习总结 - 架构师训练营 - 第二周

走过路过飞过

架构师Week2作业

熊威

第二次作业

蒜泥精英

编程与设计

eazonshaw

架构师训练营-第二周作业

坂田吴奇隆

极客大学架构师训练营

2020-06-13-第二周作业

路易斯李李李

架构师训练营 - 第二周作业

teslə

架构师训练营第二章作业

吴吴

第二周 - 学习总结

molly

极客大学架构师训练营

week2 homework

360回扫样本存储系统Xstore的设计与实践-InfoQ