kem*_*mri 5 shell-script curl stdout gnu-parallel
我正在从美国国家公路交通安全管理局 API 中提取大约 25,000,000 个 VIN 编号的 VIN 规范。这是大量数据,因为我没有以任何方式转换数据,curl
似乎是一种比 Python 更高效、更轻量级的完成任务的方式(因为 Python 的 GIL 使并行处理有点痛苦)。
在下面的代码中,vins.csv
是一个包含 2500 万个 VIN 的大样本的文件,分成 100 个 VIN 的块。这些将被传递给使用 4 个内核的 GNU Parallel。一切都nhtsa_vin_data.csv
在最后倾倒。
$ cat vins.csv | parallel -j10% curl -s --data "format=csv" \
--data "data={1}" https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/ \
>> /nas/BIGDATA/kemri/nhtsa_vin_data.csv
Run Code Online (Sandbox Code Playgroud)
这个过程开始时每分钟写入大约 3,000 个 VIN,随着时间的推移逐渐变慢(目前约为 1,200/分钟)。
nhtsa_vin_data.csv
随着规模的增长而增加开销?>>
操作的方式有关吗?每个@slm 的第一个解决方案 - 使用并行的 tmp 文件选项将每个 curl 输出写入其自己的 .par 文件,最后合并:
$ cat vins.csv | parallel \
--tmpdir /home/kemri/vin_scraper/temp_files \
--files \
-j10% curl -s \
--data "format=csv" \
--data "data={1}" https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/ > /dev/null
cat <(head -1 $(ls *.par|head -1)) <(tail -q -n +2 *.par) > all_data.csv
Run Code Online (Sandbox Code Playgroud)
每个@oletange 的第二个解决方案 - 使用 --line-buffer 将输出缓冲到内存而不是磁盘:
$ cat test_new_mthd_vins.csv | parallel \
--line-buffer \
-j10% curl -s \
--data "format=csv" \
--data "data={1}" https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/ \
>> /home/kemri/vin_scraper/temp_files/nhtsa_vin_data.csv
Run Code Online (Sandbox Code Playgroud)
我发现这里建议的两个解决方案都非常有用和有趣,并且将来肯定会更多地使用这两个版本(用于比较性能和额外的 API 工作)。希望我能够运行一些测试,看看哪一个在我的用例中表现更好。
此外,像@oletange 和@slm 建议的那样运行某种吞吐量测试是明智的,因为 NHTSA 成为这里的瓶颈的可能性是不可忽略的。
我怀疑这>>
会导致您在分叉收集 API 数据的命令nhtsa_vin_data.csv
之间争用文件。curl
parallel
我会这样调整你的应用程序:
\n\n$ cat p.bash\n#!/bin/bash\n\ncat vins.csv | parallel --will-cite -j10% --progress --tmpdir . --files \\\n curl -s --data "format=csv" \\\n --data "data={1}" https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/\n
Run Code Online (Sandbox Code Playgroud)\n\n这将为您的命令提供curl
自己的独立文件来写入数据。
我获取了您提供给我的这 3 个 VIN 1HGCR3F95FA017875;1HGCR3F83HA034135;3FA6P0T93GR335818;
,并将它们放入名为 的文件中vins.csv
。然后我将它们复制了很多次,以便该文件最终具有以下特征:
$ tail -1 vins.csv | grep -o \';\' | wc -l\n26\n
Run Code Online (Sandbox Code Playgroud)\n\n行数\n\n$ wc -l vins.csv\n15 vins.csv\n
Run Code Online (Sandbox Code Playgroud)\n\n然后我使用这些数据运行我的脚本:
\n\n$ ./p.bash\n\nComputers / CPU cores / Max jobs to run\n1:local / 1 / 1\n\nComputer:jobs running/jobs completed/%of started jobs/Average seconds to complete\nlocal:1/0/100%/0.0s ./pard9QD3.par\nlocal:1/1/100%/10.0s ./paruwK9L.par\nlocal:1/2/100%/8.5s ./parT6rCS.par\nlocal:1/3/100%/7.3s ./pardzT2g.par\nlocal:1/4/100%/6.8s ./parDAsaO.par\nlocal:1/5/100%/6.8s ./par9X2Na.par\nlocal:1/6/100%/6.7s ./par6aRla.par\nlocal:1/7/100%/6.7s ./parNR_r4.par\nlocal:1/8/100%/6.4s ./parVoa9k.par\nlocal:1/9/100%/6.1s ./parXJQTc.par\nlocal:1/10/100%/6.0s ./parDZZrp.par\nlocal:1/11/100%/6.0s ./part0tlA.par\nlocal:1/12/100%/5.9s ./parydQlI.par\nlocal:1/13/100%/5.8s ./par4hkSL.par\nlocal:1/14/100%/5.8s ./parbGwA2.par\nlocal:0/15/100%/5.4s\n
Run Code Online (Sandbox Code Playgroud)\n\n当上述运行完成后,您可以将cat
所有文件放在一起以获得单个.csv
文件ala:
$ cat *.par > all_data.csv\n
Run Code Online (Sandbox Code Playgroud)\n\n执行此操作时请务必小心,因为每个文件对于其中包含的 CSV 数据都有自己的标题行。要处理从结果文件中取出标头:
\n\n$ cat <(head -1 $(ls *.par|head -1)) <(tail -q -n +2 *.par) > all_data.csv\n
Run Code Online (Sandbox Code Playgroud)\n\n在我的测试中,DOT 网站确实在查询继续访问其 API 时对其进行了限制。我在实验中看到的上述时间虽然很小,但随着每个查询发送到 API 网站而减少。
\n\n我在笔记本电脑上的表现如下:
\n\n$ seq 5 | parallel --will-cite --line-buffer \'yes {} | head -c 1G\' | pv >> /dev/null\n 5GiB 0:00:51 [99.4MiB/s] [ <=> ]\n
Run Code Online (Sandbox Code Playgroud)\n\n注意:以上内容借自 Ole Tange 的答案并进行了修改。它通过管道写入 5GB 数据parallel
并将其传输到pv >> /dev/null
. pv
使用它,我们可以监控通过管道的吞吐量并获得 MB/s 类型的测量结果。
我的笔记本电脑能够达到约 100MB/s 的吞吐量。
\n\n\n\n\n应用程序编程接口
\n\n对于 Batch\xe2\x80\x99 中的 \xe2\x80\x98Decode VIN(平面格式),是否有通过 URL 进行此查询的示例,类似于其他操作?
\n\n对于这个特定的 API,您只需将一组 VIN 放入框中,并用 \xe2\x80\x9c;\xe2\x80\x9d 分隔。您还可以在 \xe2\x80\x9c;\xe2\x80\x9d 之前指示型号年份,并用 \xe2\x80\x9c,\xe2\x80\x9d 分隔。您可以通过此服务输入的 VIN 数量有上限。
\n\n盒内示例为样本:5UXWX7C5*BA,2011;5YJSA3DS*EF
\n\n来源: https: //vpic.nhtsa.dot.gov/MfrPortal/home/faq搜索“rate”
\n
上面提到了使用API有一个上限:
\n\n\n\n\n您可以通过此服务输入的 VIN 数量有上限。
\n
归档时间: |
|
查看次数: |
713 次 |
最近记录: |