jjzjj

mysql - 为什么 Sequelize 在 3120 条记录后暂停?

coder 2023-10-22 原文

我有一个用 Nodejs 编写的系统,它首先必须将非常大的 csv 文件中的记录导入数据库。使用Sequelize作为我的 ORM,我创建了一个简单的模型,如下所示:

"use strict";
const Sequelize = require('sequelize');
const sequelize = new Sequelize('mm', 'root', 'password', {
    host: 'localhost',
    dialect: 'mysql',
    logging: true,
    pool: {max: 5, min: 0, idle: 100000},
});
const Index = sequelize.define('index', {
    value: {type: Sequelize.FLOAT}
});

然后我编写了以下代码来遍历文件中的行,解释这些行,并将它们写入数据库:

let readline = require('readline');
let moment = require('moment');

let lineReader = readline.createInterface({
    input: require('fs').createReadStream('files/price_index.csv')
});

lineReader.on('line', function (line) {
    let splitted = line.split(',');
    let dt = moment(parseInt(splitted[0]));
    let value = parseFloat(splitted[1]);
    console.log(dt.format(), value);
    Index.create({value: value, createdAt: dt});
});

这工作正常,但它在每 3120 条记录后暂停约 3 秒。我尝试了 sqlite 和 mysql,但它总是在恰好 3120 条记录后暂停。

看到 Sequelize 也在那些 3120 条记录之后开始记录插入查询,我认为这种行为的原因是某种缓存机制,它将所有查询放入队列中,直到它无事可做,或者如果它达到了恰好 3120 条记录的神奇查询缓存限制。

我尝试在 Sequelize 的初始化中增加 pool.max 数字,但这似乎没有任何区别。

谁能证实我的缓存想法,或者解释一下这种行为的真正原因是什么?我能以某种方式改变这种行为,使其具有一致的吞吐量吗?欢迎所有提示!

最佳答案

我认为 3120 行将是 the high water mark for the createReadStream buffer which is 64KiB .当缓冲区已满时,Node 将停止读取。

看起来 3120 个 line 事件都在同一个 Node 事件 tick 上运行,因此您处理了 3120 行,并为下一个 tick 安排了 3120 个异步 Index.create 调用.因此,您最终需要在每一侧进行大量处理。要么读取和调度查询,要么处理大量的调度查询。

当 3120 line 事件函数完成时,会发生一些垃圾收集,并且计划的 3120 sequelize create 调用有机会执行它们的操作。这是数据中的“暂停”,但 Node 仍在处理。所有 create 调用都需要几秒钟才能完成,然后进行更多的垃圾收集并返回到下一个 csv 数据 block 及其所有 line 事件。这个过程就这样来回进行。

在一个包含 10000 行的 csv 文件中,我看到 ~ 3 个查询能够在所有 10000 行 csv 数据被读取并计划插入之前运行。

一致的吞吐量

您可能想使用 Readable Stream用更小的 block 。然后根据 sequelize 插入完成来阻止读取。您可能需要自己处理线路而不是使用 readline .如果 csv 文件适合内存,只需读取整个文件,因为调度会更容易。

也许使用类似 queue 的东西管理插入,允许您的 Sequelize 池 max 作为 concurrency。然后,一旦队列的 length 足够低,就允许读取再次发生。

虽然我不知道最终结果是否会更快,但最终结果可能非常相似。

关于mysql - 为什么 Sequelize 在 3120 条记录后暂停?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47052410/

有关mysql - 为什么 Sequelize 在 3120 条记录后暂停?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  6. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  7. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  8. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  9. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  10. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

随机推荐