我必须循环浏览单独存储在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")
}
}
所以当它并行运行时,就像我说的,它会在写操作时出现瓶颈,导致超时。
我不知道如何处理用户3666197所说的,另外,为这些错误做好准备并在处理这些错误时进行良好的设计也是件好事。
将readin与write分开也不是一个现实的选择,因为结果对象太大,无法很好地处理。
我知道,由于瓶颈的存在,并行运行这个程序将提供有限的改进,但是它将通过允许其他工作人员在加载所有内容的同时加载和处理原始数据来减少总的处理时间。
所以我最初的问题仍然是-如何最好地处理mysql写队列,以便在并行运行时不会产生超时错误?
谢谢你
最佳答案
在mcve公式化的问题中没有代码,让我们继续,答案中没有任何代码。
While all the due mathematical formulations are in the tail section of this,一个人类可读的故事可能是一个更好的方法来获得对主要问题根源的可靠理解:
使用并行语法构造函数?在许多地方和许多时尚中,语法上是可能的,但是…
这里的重点(总是)是,它是否有任何意义。为了回答这个问题,我们必须知道使用它的所有成本的总和。
成本是,由于我们的核心动机是处理速度加快,管理费用在我们需要及时支付之前,我们才能享受使用“加速”的结果。
让我们勾勒出一个例子——科德角机场的故事:
一个城市的市长大人决定修建一条新的高速公路,以便让受欢迎的市民能够更快地乘车前往科德角一角的机场。
这听起来合乎逻辑,很棒。于是,他们开始投资,向数百名房东支付了所有新获得的土地(买下这块地是为了修建新公路)、采石工人挖掘所有需要的岩石、磨坊工人将其磨成合适大小的石头、沙子、水泥和沥青,所有这些都是公路所需要的,推土机的操作人员将这些岩石铺设在路基上,混凝土供应商的混合和交付的水泥在一个及时的方式,随着公路建设前进等。
几个月或几年后(取决于当地经济、承包商的表现、城市预算和距机场的距离……当然),高速公路已经完工,开幕式也举行了。
目前有两件事是确定的——成本——修建这样的高速公路需要多少钱,再加上——延迟——第一辆车从城市开到机场需要多长时间。
最后一件事是——实现了净加速——所以这条新的、100条平行车道宽的公路最终有多快,如果与旧的、使用多年的、可爱的乡村公路相比的话。
结果呢?
首先是已知的性能基线:
汽车A,B,C,D…X,Y,Z都是在几个月(几年)前开始前往机场的,以~40英里/小时的速度舒适地行驶,并且都是以一种纯粹的TimeOut
方式在大约一个小时内到达机场的。没有什么性感的,但一个坚实的,可重复的结果,作为下一次,这些将享受几乎相同的结果再次。
与新的平行车手相比:
汽车A1,A2,A3,…A100,B101,…B200,…Z2600都有相同的目标,尽可能快的到达机场,但是却要等几个月(几年)的时间才能建成新的高速公路(明显的处理设置延迟),接下来在这条新高速公路上享受超快的旅程大约需要几分钟,有德国一样没有速度限制,那么200英里/小时?时速300英里?没问题。
在此之前,在100条平行车道宽的新高速公路上以300英里/小时的速度驾驶汽车的3分钟超快体验已经到达海岸线,接下来,每辆车都必须排队等候下一艘渡轮的到来(载客量只有大约30辆车,也服务于所有传统的当地交通)。
假设一条轮渡线有一个服务RTT(往返时间-装载前30辆车,前往科德角,卸下车,装载返回者,从科德角返回大陆港口)大约40分钟,游戏就快结束了。
结果:
-整组a:z[SERIAL]
时间
-<=30个平行车手的第一个子集has made the task in T0 +01:00:00
-<=30个平行车手的下一个子集has made the same in T0 +8760:23:00
-<=30个平行车手的下一个子集has made the same in T0 +8760:43:00
-<=30个平行车手的下一个子集has made the same in T0 +8761:03:00
-<=30个平行车手的下一个子集has made the same in T0 +8761:23:00
-<=30个平行车手的下一个子集has made the same in T0 +8761:43:00
…
-<=30个平行车手的最后一个子集has made the same in T0 +8762:03:00
所有这些条件如下:
-在这29个小时内,当地没有交通出现
-第一艘渡轮是空的,准备在第一批30节车厢到达港口后立即开始装货。
-没有出现渡轮服务中断或时间表服务违规的情况
故事的结尾:
在现实世界中,没有“更好”的结果是可能的,在资源受限的并行计算中,没有更好的结果是可能的。
后记:
在另一种情况下,has made the same in T0 +8788:43:00
设置中只有一个“just”[CONCURRENT]
元素可能会非常昂贵-幸运的是,所有的花费~x 000.000.000美元和~8760+小时神奇地“免费”,
但是
真正的计算从来没有这么宽容过
代码总是会支付所有的费用,总是(设计方面的,代码执行方面的),所以一个适当的工程努力和适当的设计注意总是到位的,不会得到任何[PARALLEL]
的加速惊喜。
关于mysql - 如何避免将大型文件并行加载到mysql中的超时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48058762/