|
导读:本次分享次要包罗四个方面:
存储现状存储减速存储办事化将来布局分享佳宾|丁天宝/孙颢宁 Shopee Data Infra
编纂整顿|冯蕾蕾 我爱我家
内容来源|大数据存储架构峰会(3月26日)
出品社区|DataFun
01
存储现状
1. 存储构造
3zmwwrn1c2j.jpg
目前虾皮的存储构造从上到下次要分为存储层、调度层、计算引擎层战争台办理层,在引擎层有 Spark、Flink、pRESTo;调度层有 Yarn;存储次要是 HDFS 和 Ozone,对接存储层的也有一些APP,例如保举和搜寻等等。
2. 存储范围
zung1j4vq4f.jpg
咱们的存储集群范围有几千台,存储范围约数百 PB,文件数量约几十亿,最大 QPS 约几十万。
02
存储减速
1. Presto 优化减速查问
存储减速部份,次要次要是针对 Presto,它是咱们存储零碎的一个使用小户。目前 Presto 的集群范围大略数千实例,TP90 大略两分钟,天天读取文件大略有几十 PB,查问量大略天天数十万。
bogayew4gni.jpg
ktz5jmfm4b1.jpg
通过长期的使用发现,HDFS 机能常常不不乱,Presto 的查问也会有颤动景象。所以就发生了既晋升查问速度又包管查问不乱性的需要。目前对比主流的改进形式是添加加 cache,cache 中对比主流的形式是使用 Alluxio。Alluxio 计划中相对于经典的形式是 Presto Worker 和 Alluxio Worker 部署在一同,HDFS 挂载在 Alluxio 目录上,Presto 经过 Alluxio 拜候 HDFS,缓存 Alluxio 本人办理。
hzuk5vxwopa.jpg
在这类 Alluxio+Presto 经典解决计划中也存在一些问题:
虾皮的存储容量是 PB 级别,缓存容量是 TB 级别,大略有千分之一的差距;这样就必需定制化缓存容量去合乎 Presto 运转的一些要求;假如数据不在 Alluxio 中,需求先将数据导入到 Alluxio 中,通过尝试,咱们发现第一次数据导入都会损耗对比长期。解决计划:
对 HMS:设置标记,告知 Presto 缓存在 Presto 仍是在 Alluxio 中;对 Alluxio Worker:设计 Cache Manger,自定义缓存战略,提前加载缓存;有了这个标记当前 Presto 就能间接去查 HDFS,不需求经过 Alluxio 去直达。2. Cache Manager 架构和完成细节
为理解决以上问题,咱们设计了一个 Cache Manager 零碎。首先来看一下Cache Manager 的总体架构:
opxo3qdrmuf.jpg
Cache Manager 经过 load/unload/mount 发给 Alluxio,Alluxio 从HDFS 加载数据;按照一些缓存战略去加载一些热表;提供了一些 API 接口,能够进行一些输出和输入;经过 Kafka 的 HDFS 对曾经加载的缓存进行一些修正;在HMS上打一些标记,这样计算引擎就能从 HMS 失掉并从 Alluxio 去加载数据。接上去来看一下 Cache Manager 的一些完成细节。
热表:经过 Presto 的查问日志,天天生成的 Hive 表,按日期分区,统计每个表每一个天的热度,即拜候次数。缓存战略
y0xvlr4thkm.jpg
从热表中失掉比来七天加权拜候最频繁的表,取每个表比来的 m 个分区,把这些分区从 HDFS 加载到 Alluxio 中,把这些瓜葛存储到数据库中,而后在 HMS 设置标记。留意的是,这是一个对比高级的版本,后续会不停迭代优化。
① HMS 标记:采取 key 的形式
qvhhags42uq.jpg
Key 是 Cach,Value 是数据核心,而后是 Alluxio 以及 Alluxio 的NameService,咱们会有多种 Alluxio 的办事。假如分区存在,会设置在 partition 属性上,假如分区不存在,则设置在 table 属性上。右图表现的是 Presto 去 HMS 查问,假如在 Alluxio 上就去 Alluxio 查问,假如不在就去 HDFS 查问。
gl2ebhdiyht.jpg
举个例子,示例中,打上 tag 标记后,咱们看到分区属性上有个 Cache 属性,标识这个缓存是在哪一个 Alluxio 上。
② 接口:有多种接口
f55luqw2ki0.jpg
咱们提供了一些接口,有按照门路的接口和表的接口,还有一些办理员接口。门路和表的接口都是一些 mount, unmount, load, query,表的 load 接口会对比细化一些。
3. 成果展示
rpibmuotch2.jpg
目前 Alluxio 正在上线中,数据收集不彻底,但现有的测试数据能够看出整个从 Alluxio 读比整个从 HDFS 查问最高能够达到 55.51% 的晋升。
4. Alluxio 社区奉献
ckf13jp5awy.jpg
03
存储办事化
1. 业务痛点问题
大少数业务数据存储到 HDFS不同业务使用的开发言语各异目前 HDFS 的非 JAVA 客户端不完美2. 解决计划
为了给业务人员提供更成熟便捷的拜候形式,从存储办事化的角度登程,结合咱们对 Alluxio 的调研,提供了下列两种解决计划。
(1)Fuse for HDFS:在 Fuse 中能够像在当地拜候数据同样来拜候 HDFS 的数据,咱们提供了两种部署模式:物理机部署 Alluxio Fuse 办事,以及 Kubernetes 部署 Alluxio Fuse 办事。
(2)S3 for HDFS:经过 S3 API 拜候 Alluxio 办事。S3 对多种言语反对,能够解决开发言语差别的问题,同时 Alluxio 对 S3 接口兼容,使用 S3 接口拜候 HDFS 中数据十分便捷,咱们终究抉择采取这类形式来晋升用户体验。
3. 理解 fuse
d40uksex4ky.jpg
Fuse 属于一个用户态的软件零碎,由两部份组成:内核模块以及用户空间守护过程。Fuse 给用户和开发者带来了极大的方便。在内核模块的反对下,开发者只需求完成规范的 POSIX 协定接口就能具有一个自定义的文件零碎。
右侧这幅图是一个 Fuse 办事的架构图,当用户在被挂载的目录履行文件操作时,就会触发零碎调用,VFS 将这些操作路由至 Fuse driver,Fuse driver 创立申请将其放入到申请队列中,Fuse daemon 经过块装备从内核队列中读取申请,进而履行自定义的逻辑操作。
4. 物理机部署 Alluxio Fuse
ecwyhpvznet.jpg
先看一下右侧的这幅图,Alluxio Fuse 的办事就至关于后面讲的 Fuse deamon,在启动 Alluxio Fuse 的时分,至关于进行了一个挂载操作,它会调用 libfuse 的办法,向 kernel 去注册挂载点以及回调函数。在挂载目录下履行的操作就是履行的回调函数逻辑,像图中形容的 ls 指令最初失掉的后果就是对挂载的 Alluxio 目录履行的list操作的后果。
在使用 Alluxio Fuse 以前,咱们需求装置 libfuse 。目前社区的版本是反对 libfuse2 的,libfuse3 应该也在开发过程中。完成形式当初有两种,一个是 JNR-Fuse 一个是 JNI-Fuse。JNR-Fuse 是一个集体保护的名目,所以泛起问题的话纷歧定可以及时地的解决。而 JNI-Fuse 是由 Alluxio 社区来保护的,而且在并发场景下 JNI-Fuse 机能更佳。因而咱们选择了 JNI-Fuse 作为咱们的完成形式。
Alluxio Fuse 有两种部署模式,一种是集成到 worker 过程,这样可以省去 rpc 调用,另外一种是独自部署在一个客户机上,目前咱们使用的是独自部署的模式,由于咱们的用户的运用客户端纷歧定和 worker 在同一个节点,所以选择更加灵敏的独立部署模式。
虽然 Alluxio Fuse 反对规范的 POSIX 协定,然而它的重点是提供读办事,由于目前的次要使用场景是减速 AI 训练,这是一个典型的读的场景。关于随机写的反对目前还不敷好。而咱们的办事化需要可能不仅仅是读申请,这也是咱们前面需求改进的点,以更好地反对用户需要。
5. K8s CSI 部署 Alluxio Fuse
ebxev04muzz.jpg
在引见完物理机部署之后,咱们再来看一下如安在 K8s 集群部署。利用 K8s的 CSI 能够将 Alluxio Fuse 办事部署到 K8s 上,CSI 是一个容器的规范存储接口。借助 CSI 的容器编排才能,咱们能够将恣意的存储零碎袒露给容器,从而使用这些存储办事。右侧这幅图就是 Alluxio 如何使用 CSI 的原理图。咱们能够看到下面部份次要是 CSI 部份, 其中一部份是由 K8S 社区保护的组件(右侧部份),而咱们更需求关注的是左侧需求开发者去定义的部份,次要包罗 CSI Controller 和 CSI nodeServer。Controller 作为管制端,完成了创立、删除、挂载、卸载等功用。而 NodeServer 端是进行详细的 mount 操作的节点。在 Alluxio 的 CSI 傍边,NodeServer 以 daemonset 模式部署到每个 Node 节点上。
要使用定义好的 Alluxio Fuse 的办事,只需用户在定义 PV 时,指定使用 Alluxio CSI 这类办事来提供数据挂载办事就能,而且需求指定好 Alluxio办事零碎中以业务的目录作为挂载点。而后在创立业务 POD 的时分,它就会在 NodeServer下来启动一个 Alluxio Fuse 办事,同时业务 POD 就能拜候挂载在 Alluxio 傍边的目录了。这类模式下,一个 NodeServer 上可能会有多个 Fuse 过程,这样可以勤俭资源。然而它有一个弊病就是一旦这个 NodeServer 泛起了异样,那末其中运转的多个 Fuse 办事都会遭到影响,与其对应使用这个 Fuse 办事的 Container 都会遭到影响,咱们必需重启一切的业务 POD 能力正常拜候文件。
6. K8s sidecar 模式部署 Alluxio Fuse
uieb3vcrfjo.jpg
为了不 NodeServer 挂掉之后发生的影响,咱们又引入此外一种模式。就是 K8s 的 sidecar模式,sidecar 模式就是在用户配置业务 Container 的YAML文件中,会配置一个 Alluxio Fuse 的办事。至关于在启动一个业务 Container 的时分,会额定地提供一个 Alluxio Fuse Container 。这个 Alluxio Fuse Container 次要就是用来挂载 Alluxio 目录用的,而且这两个 Container 能够同享存储网络等资源的。这样业务Container 就能拜候Alluxio Fuse挂载的目录。这类模式下每个 POD 均可以有一个 Container,部署配置对比灵敏,并且每个容器之间互不影响。然而由于每个 Fuse 过程都会占用一个容器,这样会额定损耗一部份资源。
部署模式总结:
1ue0cansvxh.jpg
简略回顾一下这三种模式的特征:
关于物理机部署,由于是要部署到用户的每个客户机上,客户机是对比扩散的,所以它的部署本钱要高一些。而关于 K8S 模式,由于它是部署在每个node 上,所以运维本钱相对于来讲会稍低一些。而关于资源的使用,由于物理机部署就是启动一个过程,而 K8S 的模式会开启一个 NodeServer 或者开启一个独自的 Container 去部署这个办事,所以会占用一些额定的资源。sidecar模式,由于对每个业务 Container 都会启用一个 Alluxio Fuse 的办事,这样占用资源相较于 CSI 模式会更高一些。
独立性方面,物理机部署由于采取的是独立部署,不会受 worker 的影响,也不会影响 worker。每个业务使用的 Fuse办事也是相互不影响的。K8S CSI 模式由于是在NodeServer 上能够部署多个 Fuse 过程,所以可能会遭到 NodeServer 的影响。K8S sidecar 模式也是独立部署的,不会发生任何影响。
7. 理解 S3
p5m0le3jpyl.jpg
除了挂载操作的形式以外,咱们还提供此外一种办事化的形式,就是使用 S3 SDK。S3 是亚马逊的一个地下的云存储办事零碎,是存储对象用的。其特征是提供了丰硕的客户端 SDK,咱们就是要借助这些丰硕的 SDK 来完成对 Alluxio 傍边文件的拜候。
在此也引见一下 S3 的一些根本概念。Bucket 是 S3 顶用于存储对象的容器;object 是 S3 中存储的根本实体;Key 是存储桶中对象的独一标识符;region 在 S3 的办事中能够选择一个区域供 S3 存储创立的桶。上面看一下咱们是如何利用 S3 的 SDK 来提供存储办事的 。
8. S3 for HDFS
gayqryjajxt.jpg
利用 S3 的 SDK 来拜候数据次要是依赖于几点:
首先 Alluxio能够挂载 HDFS 数据。Alluxio提供了 Proxy 的办事,Proxy 办事是兼容 S3 API 的,所以能够反对更多的用户经过更多的言语,使用 S3 SDK 来经过发送申请到 Alluxio Proxy,解析成对 Alluxio 的申请,从而来拜候数据。
9. Proxy 映照瓜葛
f3osnplftv4.jpg
左侧这幅图履行的是一个 mount 指令。将 HDFS 傍边的 projects 目录挂载到 Alluxio傍边的 projects 目录。下边分别是 HDFS 中的门路以及 Alluxio 傍边的门路。它们是一一对应的瓜葛。
Proxy 办事在做解析的时分,把 Alluxio 的一级目录作为 bucket 来进行映照,其子目录和文件构成 key,至关于经过这个 bucket 和 key 咱们就能失掉一个 object 对象。右侧的图就是一个 S3 的 Java SDK 申请 Proxy 办事的 demo,能够看到,其bucket设置为首级目录,目录的其他部份作为 key 能够获得到这个对象。
10. 完成 Proxy Authentication
当初社区提供的Proxy办事并无提供 S3 所拥有的认证功用,因而咱们本人为 Proxy 办事添加了认证功用。
S3 的 SDK 发起申请时,会将申请转换为 REST 申请,而且在客户端按照拿到用户的 ID 以及 secret ,再加之申请傍边的申请信息,生成一个签名,而后把这个签名放到申请傍边。
咱们在 Proxy 办事中添加了用于解析认证申请和校验认证的办法。由于在申请中带有 ID 信息,咱们能够拿着 ID 去 secret manager 掏出它的 secret 信息,从新在 Proxy 办事端生成新的签名,与申请中带来的签名进行对比,从而判别这个认证是不是经过。
右图是亚马逊官网给出的计算步骤,咱们能够看到它就是解析 request 申请和计算签名的一个进程。使用了加密算法,屡次加密之后失掉了三个字段,而后进行最初的编码以及加密编码,才失掉的这个签名。
十一. 办事架构
再来看一下咱们全部的办事架构。图的右半部份是一个集群,它的后端是HDFS 的数据。咱们把一切的方才引见到的办事模式都在这个图上进行了展现。能够看到有三个橘黄色客户端,下面是一个使用 S3 的 SDK 的客户端,它经过负载平衡,将申请发送到某个 Proxy 办事,经网络发送到 Alluxio 集群进行解析之后,数据就会前往到客户端。
上面这个客户端使用的是在物理机部署的模式,在当地物理机去部署一个 Alluxio Fuse ,用户经过拜候 Alluxio Fuse 挂载的目录,进而获得到 Alluxio 傍边的数据。
最下边是一个 K8s 集群。右侧是集群里的一个 pod。这是一个 sidecar 模式,一个客户端和 Alluxio Fuse 的 Container,它们之间同享存储。由于 K8S 是有本人的网络办事定义的,经过这个网络衔接到外边的网络办事,进而能够拿到 Alluxio 中的数据。
十二. Alluxio 社区奉献
咱们在使用 Alluxio 办事的过程当中也发现了一些问题,并踊跃地反馈给了社区,次要是 proxy 与 fuse 相干的问题。
04
将来布局
将来布局次要在下列两小气面:
在存储减速方面,咱们还会将 Spark 和 Hive 接入 Alluxio;CacheManager 添加自顺应的缓存战略,达到更优的缓存使用;在存储办事化方面,咱们也会对 CSI 进行优化,将 Fuse 独立于 nodeserver 办事;关于 Fuse 办事,由于咱们提供的场景不仅仅是读,所以,咱们需求按照业务需要完美对 POSIX 接口反对。明天的分享就到这里,谢谢大家。
|分享佳宾|
丁天宝|Shopee engineer
多年大数据教训,波及存储、引擎、调度、大数据开发等等。也有丰硕的后端开发教训,前端也能做一点。
孙颢宁|Shopee engineer
多年大数据存储研发教训,目前就职于Shopee,担任Alluxio的研发任务。
|对于DataFun|
专一于大数据、人工智能技术运用的分享与交流。发动于2017年,在北京、上海、深圳、杭州等城市举行超过100+线下和100+线上沙龙、论坛及峰会,已约请超过2000位专家和学者参预分享。其大众号 DataFunTalk 累计出产原创文章800+,百万+浏览,15万+精准粉丝。 |
|