【问题标题】:More scalable way to write this Node.js logic for retrieving and updating CSV data from Google Cloud Storage?编写此 Node.js 逻辑以从 Google Cloud Storage 检索和更新 CSV 数据的更具可扩展性的方式?
【发布时间】:2020-07-19 07:31:04
【问题描述】:

我正在创建我的第一个 Node.js REST API 测试项目,用于检索奖品。该逻辑旨在执行以下操作:

  • 从与项目关联的 Google Cloud Storage 存储分区中检索 CSV
  • 解析 CSV
  • 查找未填充“已声明”列的第一行
  • 将“已声明”列更新为“已声明!”
  • 在 Google Cloud Storage 中覆盖 CSV 文件中的数据
  • 返回与该行关联的奖品名称

我的逻辑目前在本地工作,但我想知道是否有更好、更具可扩展性的代码编写方式。我将以每天约 10 万用户的 500/分钟速率限制对其进行测试,最终将传递一个外部用户 ID 以存储在“已声明”列中。 CSV 中总共有 500k 行(奖品)。

我正在使用的代码如下。任何使其可扩展的建议将不胜感激!提前谢谢你。

const csv = require('csv-parser');
const fs = require('fs');
const jsonexport = require('jsonexport');

const bucketName = 'MY-BUCKET';
const filename = 'MY-CSV';

const {Storage} = require('@google-cloud/storage');

const storage = new Storage({keyFilename: "MY-KEY.json"});

const myBucket = storage.bucket(bucketName);
const file = myBucket.file(filename);

let dataArray = [];

file.createReadStream()
  .pipe(csv())
  .on('data', function (data) {
    dataArray.push(data);
  })
  .on('end', function(){
    let prize = dataArray.find(element => element.Claimed == "");
    prizeName = prize.Prize_name;
    prize.Claimed = "claimed!";
    jsonexport(dataArray,function(err, transformedData){
      if(err) return console.log(err);
      file.save(transformedData, function(err) {
        if(err) return console.log(err);
      });
    });
    return prizeName
});

【问题讨论】:

  • 顺便说一句,欢迎来到 StackOverflow!您对新用户的提问格式很好,似乎已经阅读 (stackoverflow.com/help/how-to-ask) 并了解降价编辑器。也不要忘记给为您提供有用数据的用户投票并将问题标记为已回答或与社区分享您自己的答案。万一你自己发现了。
  • 让我猜一猜,您使用与*.csv 打交道只是因为在您的项目中使用 Google 表单作为前端界面?
  • 您好@AlexZeDim,感谢您的回复和客气话!我会确保投票并标记已回答的问题,谢谢您的建议。 -- 我使用*,csv 是因为我想让数据在谷歌云存储和谷歌表格之间来回移动变得容易。例如,很容易从表格中以 CSV 格式下载数据。你能推荐另一种格式吗?
  • 是的,我只是输入if I were you的答案

标签: node.js rest csv google-cloud-storage


【解决方案1】:

好的,我有这方面的经验。根据一个问题,它更多的是关于性能,我建议基本代码可以正常工作。

我猜瓶颈是fscreateReadStream。它工作正常,但它不是异步的 (this question shows us why)。

实际上是这样,但是...如果你想立即存储它,你会用你的文件淹没你的 RAM

const fs = require('fs');
const readFile = promisify(fs.readFile);
let file = await readFile(`${path_}/${file}`, {encoding: 'utf8'});

因此,即使您有 10 个具有 50k 用户的文件,而不是一个具有 500k 用户的文件。您也需要一次解析所有 10 个文件,但是当您同步进行时..

嗯,你的逻辑不会像你想象的那样快 10 倍。

顺便说一句,如果你有另一个代码执行相同的功能,但你不知道如何衡量它的性能速度,使用这个:

console.time('benchmark_name')
/* Some action here */
console.timeEnd('benchmark_name')

我知道我的答案根本不是答案,但这就是我解决这个问题的方法,就好像我是你

  • 删除 CSV - 它只会给您带来问题,尤其是当您处理 100K+ 行时。
  • 尝试云基础设施:如果您需要将数据存储在某个地方,例如使用MongoDB Atlas (free tier)。并且不要忘记在相关列上添加一些索引。所以就目前而言,您不需要fs,它完全可以流式传输。

在这种情况下,专注于 Mongo Atlas 只是一种选择,您可以使用 Azure Cosmos DB 或其他任何东西。甚至使用AWS / GCP free tier VPS 并启动任何适合您的需求 数据库。关键是——远离 Google 表格/云端硬盘。

为什么要避免使用 CSV / Google Drive?

它们并没有那么糟糕,您可能会想,但会问自己,如果 google drive / csv 是存储数据的有效方式,为什么人们使用数据库而不是将所有信息存储在一个大的 *.csv 文件中?我想这个比喻是有道理的。

回到我们未来的数据库..

就目前而言,您只需要连接到您的数据库并修改它的值。您可以通过一个查询一次修改您需要的所有内容,而不是:

let prize = dataArray.find(element => element.Claimed == "");

您不需要逐行查找每一行。这就是您所询问的宝贵的可扩展性

您唯一需要的是:AWS Lambda、MongoDB Stitch/Realm、webhook、API 来修改您在数据库中的数据或添加到您的表单(如果您的数据应该通过 http 表单更新)。顺便说一句,如果您害怕并且还没有准备好跳起来离开 Google 表格,您可以read this article first and try to connect Google Sheets and your DB(在这种情况下是 MongoDB,但 Google 表格支持 Google Script,所以连接任何其他数据库不会是一个大问题)

因此,所有这些步骤都将帮助您的应用更具可扩展性,正如您所要求的那样。也使用 DB 将解决数据验证等任何其他问题..

作为一个相反的站点,在我的一个项目中,我依赖于一个数据源,该数据源实际上发布了一个大的*.csv 表。它有多大? 65K+ 行,查找和更新其中的每个值,需要 7-12 分钟的资源时间。天哪,我多么讨厌那个使用 csv 而不是 API 端点/数据库连接器的人。

【讨论】:

  • 非常感谢您的详细回复!这非常有帮助。关于你所说的一次修改所有内容,我有一个问题。由于将从中调用 API 的工具的结构,此过程需要一次完成一个,而不是批量完成。一个 API 调用需要检索一个奖品,然后使用用户更新该单行。这会改变你的答案吗? -- 另外,有没有你推荐使用的数据库?我正在考虑选择拥有最大免费套餐的那个。
  • @user5779866m 好吧,这取决于您需要“多少操作”。我的意思是您喜欢通过js 代码对 DB 手动触发脚本进行操作,那么您根本不需要 http API 端点。但是,例如,如果我是 user 并想加入您的赠品,那么我应该以某种方式注册。所以我应该手动向我询问您的数据库,或者通过register via web form 自己做,当我按下register 按钮时,AWS Lambda 或 Mongo Stitch 会将我添加到您的数据库。
  • @user5779866 至于数据库,由你决定。使用您需要或想要的一切。 Mongo(例如)超级容易学习和快速。但它是面向文档的。 PostgeSQL 是相对模型和开源的。拿一些你熟悉的东西。
猜你喜欢
  • 2021-08-25
  • 2020-11-26
  • 1970-01-01
  • 2017-04-13
  • 2020-01-15
  • 1970-01-01
  • 2017-01-24
  • 1970-01-01
  • 2023-04-08
相关资源
最近更新 更多