用于将数据集下载/流式传输给用户的集群设计

时间:2018-10-10 13:19:37

标签: apache-spark hadoop cloudera-cdh

在我们的系统中,传统上,我们有两个组件:Cloudera Hadoop集群(CDH)和OpenShift“后端”系统。在HDFS中,我们有一些巨大的.parquet文件。

我们现在有一项业务要求,以“实时”将“按给定过滤条件的用户导出数据”作为可下载文件。因此,流程为:用户输入类似SQL的过滤器字符串,例如user='Theo' and command='execution'。然后,他以过滤字符串作为参数将GET /export请求发送到我们的后端服务。用户现在应该从Web浏览器中获得一个“下载文件”,并立即开始以CSV格式下载该文件(即使其大小为数TB甚至PB,也可以由用户选择是否尝试并等待那么长时间)。实际上,集群应该在发送结果之前同步,但不要在单个节点上缓存整个响应,而只能以用户的“互联网速度”接收数据并将其直接流式传输给用户。 (例如10 oder 100 MB的缓冲区)。

我现在面临如何最好地满足此要求的问题。我的考虑:

我想为此使用Spark。 Spark会读取Parquet文件,轻松应用过滤器,然后将过滤结果“集结”给驱动程序,驱动程序又将数据流回请求的后端/客户端。在此任务期间,如果将数据发送到后端/用户的速度太慢,驱动程序当然不应耗尽内存,而应让执行程序以与“消耗”相同的速度传递数据。

但是,我在这里遇到了一些问题:

  1. 标准用例是用户具有细粒度的过滤器,因此他的导出文件仅包含1000行之类的内容。如果我针对每个请求通过spark-submit提交新的Spark作业,由于初始化和查询计划的创建,我已经陷入了数秒的等待时间(即使它与读取和过滤数据一样简单)。我想避免这种情况。
  2. 群集和后端严格隔离。理想的情况是,操作人员根本不希望我们从后端访问群集,但是群集应该只调用后端。我们可以“打开”一个端口,但是我们可能无法争论“我们的后端将运行spark驱动程序,但作为执行后端连接到集群”。
  3. 如果我们运行“服务器火花作业”,是否有“不良设计气味”,即我们向集群主服务器提交模式为“客户端”的应用程序,该应用程序还会为HTTP请求打开一个端口,并且仅在请求,但始终使spark上下文保持打开状态(并且可以通过固定URL从我们的后端访问)?我知道有一个“ spark-job-server”项目可以做到这一点,但是由于Spark和Jobs的本质,它仍然感觉有些奇怪,“自然”的工作是下载文件而不是24小时正在运行的服务器不时等待执行一些管道步骤。
  4. 我不知道如何限制获取火花结果,以使执行程序以一定速度发送,以便在用户请求PB时驱动程序不会耗尽内存。对此有何建议?

毕竟,Spark是此任务的不错选择,或者您对此处的更好工具有任何建议吗? (最好不要在CDH 5.14环境中,因为我们没有让操作团队安装任何其他工具)。

0 个答案:

没有答案