用于从 SFTP 服务器进行无服务器日志提取(文件下载)的 Google Cloud Platform 解决方案

2023-12-09

今天有一个问题,在我输入答案时被删除了(不知道为什么)。由于答案很长,我决定复制/重新创建它并提供我的答案反正。也许这对某人有用。


这是原来的问题:

我们有一个 SFTP 服务器,其中转储 Apache、Nginx、Wordpress 日志。我们希望将这些日志备份到 Cloud Storage,同时解析这些日志的内容并插入到 BigQuery 表中。我通常使用 Cloud Functions(NodeJS 或 Python),我首先想到的是它作为首选解决方案。

但是,Cloud Function 有一个触发器,如果​​我的目标是让程序持续监视/观察/侦听 SFTP 文件夹中的新文件,则该触发器没有意义。如果我的要求不太严格,我可以按计划触发它,比如每小时触发它来读取 SFTP 文件夹中的新文件。当新文件转储到 Cloud Storage 时,Cloud Functions 也会起作用,触发该函数解析日志文件并将其插入 BigQuery。

如果我坚持持续侦听 SFTP 文件夹的要求,您能否建议一个更好的设计解决方案以及我需要组合哪些 GCP 服务(除了 Cloud Storage 和 BigQuery)才能实现这一目标?

如果要求不太严格,我的解决方案是否足够好? 附:我刚刚发现 SFTP 凭据具有只读权限。所以通过添加后缀来重命名文件是没有问题的。我应该使用像 MemoryStore 这样的缓存来记住哪些文件已完成吗?


长读。

从我的角度来看,这是一个非常大的问题。解决方案不仅需要代码开发,还需要大量的设计思考和决策(包括一些妥协)。

根据我的个人经验(我开发了两次这样的解决方案,在生产中维护它等),可以将云功能与一组 GCP 资源一起使用 - 秘密管理器、pubsub 主题、firestore 集合、服务帐户和 IAM等等...根据您的要求(我不知道详细信息)和上下文 - 您可能需要创建一个由一些(假设在两个到五个之间)不同的云功能组成的功能组件。二、如果您的文件较小(每个最多100M),每天的文件数量不大(几千或几万个文件),并且您有权在下载后从SFTP服务器上删除原始文件。

如果您没有这样的权限 - 应该有一些其他进程可以清理“旧”或“已下载”文件。否则,最终解决方案将无法工作(当仅下载文件列表,而不是文件,而只是文件列表时,需要超过 540 秒)。

SFTP 是一个“被动”组件 - 如果有新文件到达,它不会通知我们,因此我们这边应该有一些“主动”组件来发起与 SFTP 服务器的连接。这是一种“拉动”交互,并且有规律性(即每 10 分钟、15 分钟或 20 分钟)连接到 SFTP 服务器并检查是否有任何新内容可供下载。

下一个。云函数是幂等的,不可能仅在云函数中存储/保留文件下载的状态。应该有一些外部(相对于云功能)服务来维护每个文件下载过程的状态机。我使用了 Firestore。它非常方便并且延迟非常小。 firestore 集合中的每个文档都代表“文件下载过程”的反映 - 一个状态机以及大量元数据、状态转换历史记录等。

Cloud Functions 有 2 个重要限制:

  1. 540 秒超时。
  2. 2GB 内存。

这意味着下载过程(以及任何其他活动)不应超过 540 秒。如果要将任何数据存储在(云功能的)内存中,则数据块应小于 2Gb。

超时限制会影响进程吗? - 是的,它可以。整个过程的瓶颈是SFTP服务器和GCP存在点之间的“带宽”。文件越大 - 下载所需的时间越长,尤其是在并行下载许多文件时。

因此,很快该算法将按以下方式工作:

1/ 第一个云函数每隔 15 分钟触发一次(云调度程序 => PubSub 主题 => 云函数)。云功能读取所有 SFTP 连接和所有数据管道的配置(即来自 GCS 存储桶的 json 文件)(因为该组件可能与许多 SFTP 服务器一起使用,并且对于每个 SFTP 服务器可能有许多数据管道),然后从Secret Manager(对于每个 SFTP 服务器),然后连接到 SFTP 服务器,并下载每个连接/管道的可用文件列表。因此,对于我们知道的每个文件 - 连接(SFTP 服务器)、管道(即源目录)、文件名、文件大小、文件修改时间戳。我对 SFTP 服务器不再抱有任何期望。对于每个连接和数据管道,我们都会编写一个文件列表(取决于配置,并且应该是灵活的),最多可包含 5、8 或 10,000 个文件。该列表作为 json 结构被作为消息推送到 PubSub 主题(如果需要,还可以包含一些附加元数据)。因此,如果我们有 2 个 SFTP 服务器,每个服务器中有 3 个管道,则至少会有 6 条消息。如果 SFTP 服务器中的目录包含超过 5K、8K 或 10K 文件,则可能会更多。此时,我们不知道这些文件是否已下载,或者下载过程正在进行中,或者已经失败,或者这是一个新文件。 部署此函数时 - “最大实例数”参数的值为 1。

2/ 第二个云功能由包含文件列表的 PubSub 消息触发(对于某些 SFTP 服务器和某些管道)。对于传入列表中的每个文件,云功能应该决定要做什么:

  1. 这是一个新文件,应该下载它。
  2. 下载正在进行中,我们需要等待更多 - 什么也不做。
  3. 这是一个已经下载的文件,我们什么也不做。
  4. 这是正在下载,但时间太长 - 可能下载崩溃了,应该重新下载。
  5. 这是……可能还有更多的情况需要处理……

现在需要 firestore 集合。集合中的每个文档 - 反映该文件发生的情况;所有内容都记录在那里 - 下载过程何时开始、何时(或是否)完成等等。文档 ID 是基于可用元数据计算的哈希值 - 连接(SFTP 服务器)、管道(即源目录)、源文件名、源文件大小、源文件修改时间戳。所有这些都来自于消息。

例如,我们计算哈希并检查集合中是否存在此类文档。如果不存在 - 创建一个新文档,因为这是一个可供下载的全新文件。然后编写一条 json 消息并将其推送到第二个 PubSub 主题中 - 下一个云函数将对其进行处理。如果它存在 - 有必要决定我们将如何处理它 - 不执行任何操作(因为它已经下载,或者因为下载可能仍在进行中)或再次触发其下载 - 编写一条 json 消息并推送它进入第二个 PubSub 主题...

部署此函数时,“最大实例数”参数的值介于 4 到 12 之间(根据我的经验)。

3/ 第三个云功能由 PubSub 消息触发,其中包含要下载的文件的详细信息。需要完成以下步骤:

  1. 检查该文件没有被其他云功能下载
  2. 更新 firestore 文档 - 我们开始下载过程
  3. 获取配置详细信息(来自 GCS 中的 json 文件)
  4. 获取连接详细信息(来自 Secret Manager)
  5. 连接和下载
  6. 将下载的文件保存到目标GCS存储桶中
  7. 更新 firestore 文档 - 我们完成了下载过程

部署此函数时,“最大实例数”参数的值介于 10 到 30 之间(根据我的经验)。

这是一个非常简短的描述,基于最简单的假设(即您没有大于 100Mb 的文件或/并且连接良好)。

一些额外的事情要记住。

1/ 准确的记录。具有一致字段的Json结构将被定期记录。我建议创建一个接收器,以便可以在 BigQuery 表中分析日志。

2/ 服务帐户和 IAM。所有这些都应该在仅用于给定组件的自定义服务帐户下运行。将提供相关的 IAM 角色。

3/ 云 NAT。 SFTP(根据我的经验)仅适用于特定的静态 IP 地址(它们不允许来自任何地址的连接)。因此,网络、子网、IP 地址、路由器、NAT——所有这些都需要创建和配置。 IP 地址将提供给 SFTP 服务器所有者,以允许访问。要使用“vpc 连接器”参数部署的云函数。

4/ 进度和监控 - 3 个信息源 - firestore 收集、Stackdriver 日志、BigQuery 表。

再说一遍,这是我内心深处的一个非常简单的描述。如果您有具体问题或想讨论,请告诉我。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于从 SFTP 服务器进行无服务器日志提取(文件下载)的 Google Cloud Platform 解决方案 的相关文章

  • 如何在 JAX-RS 过滤器中记录请求处理时间

    我有 JAX RS Web 应用程序 我想记录从获取请求到响应的时间量 在 Spring Boot 中使用 servlet 过滤器很容易 但我的应用程序中的过滤器无法正常工作 Provider public class RequestLog
  • ANTLR 和 Eclipse(或任何像样的 IDE)

    我已经使用 ANTLRv3IDE 插件在 Eclipse 中使用 ANTLR 一段时间了 虽然它并不完美 而且有点过时 但它的工作相当不错 现在 我希望将我正在创建的另一个 DSL 切换到 ANTLRv4 然而 Eclipse 的支持似乎非
  • 直接从浏览器将文件上传到 Azure Blob 存储?

    是否可以创建一个 html 表单以允许 Web 用户直接将文件上传到 azure blob 存储 而无需使用其他服务器作为中介 S3 和 GAW blobstore 都允许这样做 但我找不到任何对 azure blob 存储的支持 编辑 2
  • Pandas、大数据、HDF 表以及调用函数时的内存使用情况

    简短的问题 当 Pandas 在 HDFStore 上工作时 例如 mean 或 apply 它是否将内存中的完整数据作为 DataFrame 加载 还是将逐条记录作为 Serie 进行处理 详细描述 我必须处理大型数据文件 并且我可以指定
  • 从 STL 列表中删除项目

    我想创建一个函数 如果符合特定条件 则将项目从一个 STL 列表移动到另一个列表 这段代码不是这样做的方法 迭代器很可能会被擦除 函数失效并导致问题 for std list
  • facebook php - 如何获取专辑封面照片

    我需要使用 PHP SDK Facebook 获取专辑封面照片 我尝试 https graph facebook com ALBUM ID picture type album 但我得到默认图像 例如 获取用户 https graph fa
  • 将其元素添加到另一个列表后清除列表

    我正在做一个程序 它获取更多句子作为参数 我制作了 2 个列表 一个称为 propozitie 其中包含每个句子 另一个称为 propozitii 其中包含所有句子 问题是 当我在遇到 后清除 propozitie 列表时 它也会清除 pr
  • 利用重力效果拖动元素

    我想完成类似于 photoshop com 和此网站的功能 http mrdoob com projects chromeexperiments google gravity http mrdoob com projects chromee
  • iPhone 中的 NSNotification

    我正在将 NSSNotifcation 发送到 iPhone 应用程序中的另一个视图控制器 但它的观察者方法收到两次通知 这可能如何 任何人都可以指导我 我已经使用此代码来发布通知 NSNotificationCenter defaultC
  • removeall 和removeif 的用例

    我找到了这个 fun main val list MutableList
  • 如何将tchar指针转换为char指针

    我想将 tchar 转换为 char 这可能吗 如果是的话该怎么做 我使用unicode设置 A TCHAR要么是一个普通的char or a wchar t取决于您的项目的设置 如果是后者 您需要使用WideCharToMultiByte
  • 在合并的单元格中选择、插入照片并将其居中

    我是一名研发面包师 正在为我的团队制作食谱模板 模板中有照片 但我需要轻松地允许他们单击一个按钮 打开照片的文件选择器 然后将该照片放在合并的单元格中 我其实不太擅长做这个 Sub InsertPhotoMacro Dim photoNam
  • jqGrid刷新本地数据(JSON对象)

    我正在尝试将 jqGrid 与本地数据一起使用 但发现了几个问题 我正在初始化这样的事情 function refreshGrid grid results grid jqGrid data results datatype local c
  • 无法在 Python 2.4 中解码 unicode 字符串

    这是Python 2 4 中的 这是我的情况 我从数据库中提取一个字符串 它包含一个变音的 o xf6 此时 如果我运行 type value 它会返回 str 然后我尝试运行 decode utf 8 但收到错误 utf8 编解码器无法解
  • 如何在没有 Visual Studio 的情况下将新文件添加到 .csproj 文件

    如何添加新文件到 csproj从命令提示符 我认为没有任何工具可以响应命令行上的 add project 命令来执行此操作 但我认为您可以幸运地创建一个程序 脚本来直接操作 csproj 文件的 XML 内容 csproj 文件的结构如下所
  • C# amo 获取角色完整

    我正在开发一个 SSAS 项目 其中除其他事项外 我需要获取 C 中表格多维数据集的完整用户列表 目前我让它以这样的方式工作 我可以获得角色 但数据不完整 当我调用 Server Database Roles 为了便于阅读而简化 属性并枚举
  • SQLite HAVING 比较错误

    我有一个测试 SQLite 表 用于存储带有值的报告数据 CREATE TABLE IF NOT EXISTS test fact daily revenue date TEXT revenue NUMERIC product TEXT I
  • 类模板的 C++ 静态成员 - 链接器警告“多重定义”[重复]

    这个问题在这里已经有答案了 假设出于某种原因 我想要一个类模板 MyTemp 和一些静态数据成员 smDummyVar Mytemp h ifndef MY TEMP H define MY TEMP H template
  • 使用 nginx 在云上部署 django 和 React

    我有一个 digitalocean 服务器 并且已经使用 Gunicorn 和 nginx 部署了 Django 后端服务器 如何在同一台服务器上部署 React 应用程序 您可以构建 React 应用程序并使用 Nginx 提供其静态文件
  • WiX Heat:预构建事件在构建服务器上过早触发

    我正在为我的 Visual Studio 解决方案收集一个目录 到目前为止 它在我的本地系统上运行可能是因为项目构建顺序得到了尊重 当我在构建服务器上运行安装程序时 它会找到正确的目录 但在构建安装文件时尚未创建该目录 它抛出一个HEAT5

随机推荐

  • 如何在 Inno Setup 中根据操作系统版本选择要复制的文件?

    我已经使用 Inno setup 构建了一个安装程序 最近发现有些应用程序在Windows XP下无法运行 这些应用程序在 Windows 7 及更高版本上运行良好 我需要根据用户安装的 Windows 版本复制文件并相应地创建程序菜单快捷
  • 使用react-native检查手机上是否安装了Metamask应用程序

    我正在使用构建一个应用程序react native 我正在使用 React Native 的Linking用于在手机上安装的 Metamask 应用程序中打开我的网站链接的 API 这Linking opneURl url 如果设备上安装了
  • Node.js 无法连接到 MongoDB

    我对 Node js 和 MongoDB 都很陌生 我正在遵循本指南 http howtonode org express mongodb使用 Node js 和 MongoDB 创建一个简单的博客 当节点尝试连接到 MongoDB 时 它
  • SQL 中 XML 分解的替代方案

    我尝试使用 XQuery 将 XML 分解到临时表中 nodes如下 但是 我遇到了性能问题 粉碎需要花费很多时间 请给我一个关于替代方案的想法 我的要求是将批量记录传递给存储过程并解析这些记录并根据记录值执行一些操作 CREATE TAB
  • Protractor:使用 browser 或 browser.driver 方法?

    使用时protractor 全局变量browser似乎具有以下所有功能browser driver 我特意问这个是因为我不确定是否使用browser wait or browser driver wait因为它们看起来都是相同的方法 而且我
  • Json 问号(“??????”)而不是希伯来字符

    我正在从我的数据库获取包含希伯来语单词的数据 然后我从以下位置获取这些数据ResultSet放入一个字符串 然后放入一个JSONObject 这是代码 response setContentType application json Str
  • 了解 awk 分隔符 - 在基于正则表达式的字段分隔符中转义

    我有以下 shell 命令 awk F print 2 这个命令是做什么的 使用分隔符分割成字段 sometext E g echo this line passed to awk awk F print 2 line Editor s n
  • 使用 R 和 Lattice 的 XYZ 图中高程数据的颜色渐变

    我有一堆 XYZ 数据 其中 X 和 Y 是坐标 Z 应该是高程 LiDAR 点 我正在尝试使用基于 Z 值的梯度来绘制该点云 这是我到目前为止所拥有的 Read the CSV file with the LiDAR point clou
  • 序列化字节数组与 XML 文件

    我大量使用字节数组通过网络来回传输对象 原始数据 我采用了 java 的方法 通过让类型实现 ISerialized 它包含两个方法 作为接口的一部分 ReadObjectData 和 WriteObjectData 任何使用此接口的类都会
  • 计算字符串宽度(以像素为单位)以模拟自动换行时出现奇怪的行为

    尝试获取 C 中的字符串宽度来模拟自动换行和文本位置 现在用 richTextBox 编写 richTextBox 的大小是 555x454 px 我使用等宽字体 Courier New 12pt I tried TextRenderer
  • Bootstrap 3 移动设备上的多个菜单合并为一个

    我已经和菜单斗争了一段时间了 我想要的是顶部菜单和侧面菜单 为了在移动设备上有用 这两个菜单都需要折叠成可在手机上访问的菜单 这实际上可能吗 或者我是否必须为不同的屏幕尺寸编写不同的解决方案 Thanks html
  • 伪析构函数调用不会销毁对象

    考虑以下代码 include
  • Android 按钮的拖放

    我在 android 中工作 我正在使用一个按钮 现在我想执行该按钮的拖放操作 这是我的 main xml
  • 用Java显示CMD窗口

    我使用此代码启动 cmd 文件 try String line Process p Runtime getRuntime exec myPath punchRender cmd BufferedReader input new Buffer
  • 如何以编程方式禁用Android硬件按钮?

    我正在开发具有锁定功能的 Android 应用程序 请建议我如何以编程方式禁用所有硬键 在这里 我使用下面的代码来禁用后退按钮 我希望以编程方式为 Android 中的所有硬键 如主页 菜单按钮 通知栏 提供此功能 用于后退按钮 在活动或片
  • 如何获取调用 python 函数的脚本名称?

    我知道 file 包含包含代码的文件名 但是有没有办法获取调用该函数的脚本 文件的名称 如果我有一个名为filenametest b py def printFilename print file 我将函数导入filenametest a
  • SCSS编译后将@import保留在CSS末尾

    我们需要把 import在我的 CSS 文件的末尾 例如 SCSS import reset css Body font 0 8em arial import customation css 编译为 import reset css bod
  • Bootstrap:在小屏幕上重新排序 3 列

    我在尝试使用 bootstrap HTML 和 CSS 对列重新排序时遇到一些问题 目前 我的布局是这样的 B 和 C 包含在单个列中 而 A 本身有一个列 在台式机和平板电脑上 这样就可以了 但我需要为小型设备重新排序内容以获得如下内容
  • 在sql server中分割字符串

    我在数据库中有一个以逗号分隔的字符串 就像 苹果 香蕉 菠萝 葡萄 我需要根据逗号分割这个字符串并迭代它 由于sql server中没有内置函数 是否有任何有效的方法可以实现这个目标 试试这个功能 CREATE FUNCTION dbo f
  • 用于从 SFTP 服务器进行无服务器日志提取(文件下载)的 Google Cloud Platform 解决方案

    今天有一个问题 在我输入答案时被删除了 不知道为什么 由于答案很长 我决定复制 重新创建它并提供我的答案反正 也许这对某人有用 这是原来的问题 我们有一个 SFTP 服务器 其中转储 Apache Nginx Wordpress 日志 我们