如何避免超时错误并行将大文件加载到mysql中

问题描述 投票:2回答:1

我必须循环浏览单独存储在单个csv文件中的几组数据 - 大约1500个文件。每个文件代表给定日期的活动量,每个文件中的数据量基本上从无到有。

我的过程是我将数据加载到R,预处理和清理,然后我插入到本地mysql表中。这可以作为单个循环正常运行。

为了提高加载速度,我尝试将循环移动到并行进程中,我有几个工作程序预处理单独的文件,然后将每个文件加载到数据库中。

当某些文件很大时,我遇到错误,dbwritetable调用需要一些时间来处理。这似乎会锁定表,不允许其他进程完成写入,从而导致超时错误。

我对mysql相当新,我模糊地意识到我可以在数据库级别更改mysql超时时间(我相信使用conf文件)。这是最好/唯一的解决方案吗?我希望将所有控件保持在R级别,这样我就可以更轻松地在不同的机器上运行此代码。我想知道是否有另一种方法可以保持队列中的进程并在表可用时按顺序写入负载。

更新:

我认为这是一个关于如何处理超时的简单问题,但听起来需要更多信息。这是一个例子 - 它并不复杂。

  Bluetooth.loadloop <- foreach(i=jump:LoopLength, .inorder=TRUE) %dopar% {


    Start.Time <- Sys.time()
    x <- filenames[i]  

    if(!length(readLines(x))) {
      Stats <- data.frame(
        i=i, 
        time=difftime(Sys.time(),Start.Time,units='secs'),
        DataList= 0 )

      source("/Shared_Functions/MYSQL_LOGIN.r" )
      invisible(dbWriteTable(con, name="RawData_Loadloop_Stats_Bluetooth",value=Stats, append=TRUE, row.names=FALSE))
      dbDisconnect(con)
      print( "Zero length");

      return("Zero length")
    } else {


      ### Loads Data from CSV
      print(paste(i,"Start"))
      datalist <-readLines(x,encoding="UTF-8")
      filelocation <- (paste(i,x))
      datalist.length <- length(datalist)
      print(datalist.length)


      ### Proceses the individual fields 
      deviceID <- v1 <- gsub("([0-9]+),.*", "\\1", datalist)
      Time <- v2 <- gsub("[0-9]+,([0-9]+),.*", "\\1", datalist)
      Label <- v3 <- gsub("^[0-9]+,[0-9]+,(.*),([a-zA-Z0-9:]+),([^,]+)$", "\\1", datalist)
      MacAddress <- v4 <- gsub("^[0-9]+,[0-9]+,(.*),([a-zA-Z0-9:]+),([^,]+)$", "\\2", datalist)
      Strength <- v5 <- gsub("^[0-9]+,[0-9]+,(.*),([a-zA-Z0-9:]+),([^,]+)$", "\\3", datalist)

      Label <- BlueToothFilterRules(Label)
      Encoding(Label) <- 'UTF-8'
      BlueToothTable <- data.frame(i=i, DeviceID = deviceID, Time= Time, Label= Label, Mac = MacAddress, Strength= Strength, stringsAsFactors = FALSE)

      Stats <- data.frame(
        i=i, 
        time=difftime(Sys.time(),Start.Time,units='secs'),
        DataList= datalist.length
      )

      ### Writes to the Database
      source("/Shared_Functions/MYSQL_LOGIN.r" )
      dbSendQuery(con, 'set character set "utf8"')
      invisible(dbWriteTable(con, name="RawData_Events_Bluetooth",value=BlueToothTable, append=TRUE, row.names=FALSE))
      invisible(dbWriteTable(con, name="RawData_Loadloop_Stats_Bluetooth",value=Stats, append=TRUE, row.names=FALSE))
      dbDisconnect(con)
      print(paste(i,"END"));

      return("Finished")
    }
  }

因此,当这个并行运行时,就像我说的那样,它在写入时会出现瓶颈,导致超时。

我不知道如何处理user3666197所说的内容,除此之外还有为这些故障做好准备的好处,并且在处理它们时有很好的设计。

将读数与写入分开也不是一个现实的选择,因为生成的对象太大而无法很好地处理。

我知道并行运行这将提供有限的改进,因为存在瓶颈,但它会通过允许其他工作人员加载并处理原始数据而同时加载所有内容来减少总处理时间。

所以我的原始问题仍然是 - 如何最好地处理mysql写入队列,因此当并行运行时,它不会创建超时错误?

谢谢

mysql r database parallel-processing rmysql
1个回答
0
投票

在MCVE制定的问题中没有代码,让我们在答案中没有任何代码。

While all the due mathematical formulations are in the tail section of this,一个人类可读的故事可能是更好地掌握主要TimeOut问题的根本原因:

使用并行语法构造函数? 在许多地方和许多时尚的句法上可行,但......

这里(总是)的一点是,它是否有意义。为了回答这个问题,我们必须知道使用它的所有成本的总和。

在我们享受使用“加速”结果之前,成本是我们的核心动力,即处理加速,我们需要支付的时间开销。


让我们举一个例子 - 科德角机场故事:

一个城市的市长决定建造一条新的高速公路,以便让受欢迎的公民能够更快地骑到科德角一角的机场。

这听起来很合乎逻辑。因此,他们开始投资,为所有新购买的土地(购买房产以筹集新的道路)支付了数百名业主,石矿工挖掘所有需要的岩石,用适当大小的石头研磨它的磨坊,沙子水泥和沥青,高速公路所需,推土机的操作人员将公路岩石基地,混凝土供应商用于及时混合和交付水泥,公路建设正在进行中等等。

经过几个月或几年(取决于当地经济,承包商的表现,城市预算及其与机场的距离......确定),高速公路已经完工并举行了开幕式。

目前有两件事情是肯定的 - 成本 - 用钱建造这样的高速公路需要多少钱,加上 - 延迟 - 在第一辆车可以从城市到达之前需要多长时间至于机场。

最后一点是 - 净速度达到了 - 所以这个新的,100平行的车道宽高速公路最后的速度有多快,如果与旧的和多年来使用的,可爱的乡村道路相比。

结果?

首先是已知的性能基准:

汽车A,B,C,D,...... X,Y,Z都已经开始大约几个月(几年)前往机场,以40英里/小时的速度舒适地开着,都到了机场大约一个小时,一个接一个,以纯粹的[SERIAL]方式。没有什么性感,但是坚实,可重复的结果,下次,这些将再次享受几乎相同的结果。

和新的并行车手相比:

汽车A1,A2,A3,... A100,B101,... B200,...... Z2600都有相同的目标,尽快到达机场,但不得不等待几个月(年)为了建造新的高速公路(一个明显的处理设置延迟),接下来需要几分钟才能在这条新高速公路上享受超快速的行程,德国没有速度限制,所以200英里每小时? 300英里每小时?没问题。

直到,在100平行车道的新高速公路上以300英里/小时的速度驾驶汽车的惊人的3分钟超快速体验已经到达海岸线,接下来,每辆车都必须排队等待下一个渡船抵达(可容纳约30辆汽车,也提供所有传统的本地交通)。

鉴于渡轮线路有一个服务RTT(往返时间 - 装载前30辆汽车,去科德角,卸载汽车并装载那些返回,从科德角回到大陆港口)约40分钟,游戏是差不多结束了。

结果: - 整个A组:Z has made the task in T0 +01:00:00时间 - <= 30-parallel-riders has made the same in T0 +8760:23:00的第一个子集 - <= 30-parallel-riders has made the same in T0 +8760:43:00的下一个子集 - <= 30-parallel-riders has made the same in T0 +8761:03:00的下一个子集 - <= 30-parallel-riders has made the same in T0 +8761:23:00的下一个子集 - <= 30-parallel-riders has made the same in T0 +8761:43:00的下一个子集 - <= 30-parallel-riders has made the same in T0 +8762:03:00的下一个子集 ... - <= 30-parallel-riders has made the same in T0 +8788:43:00的最后一个子集

所有这一切都给出了条件: - 在这29小时内没有出现过本地交通 - 第一艘渡轮空无一人,准备好在他们到达时开始装载第一套约30辆汽车 - 没有出现过渡船服务中断或时间表服务违规行为


故事的结局:

在现实世界中没有“更好”的结果是可能的,在真实硬件上的资源受限的并行计算图形执行中不可能有更好的结果。

结语:

在其他真正的[CONCURRENT]设置中只有一个“just”-[PARALLEL]元素可能会很昂贵 - 幸运的是,所有成本~x.000.000.000 USD和~8760+小时神奇地只是“免费”, 但 真正的计算永远不会那么宽容 并且代码将始终支付所有费用,总是(设计方面,代码执行方面),因此应该做出适当的工程努力和适当的设计保养,以免获得任何<< 1加速。

© www.soinside.com 2019 - 2024. All rights reserved.