如何使用python客户端将大量行从InfluxDB导出到CSV?

时间:2018-01-04 19:15:31

标签: python influxdb influxdb-python

我正在尝试将大量行(160.000.000+)从InfluxDB导出到csv文件。到目前为止,我只是在运行查询的机器上炸毁内存。我迷失了如何在不吹出运行导出的机器的内存的情况下导出这么多行。对此有何看法?我也没有运气试过CLI。

我尝试过以下代码..

def export_to_csv_file(self, file_name, header, query):
    logger.info("Executing query {}".format(query))
    dfs = pd.DataFrame(self.client.query(query, chunked=True, chunk_size=10000).get_points())
    dfs.to_csv('dummy.txt', index=False, columns=header, encoding='utf-8')

有关如何成功导出数据的任何提示或提示。

1 个答案:

答案 0 :(得分:1)

这可以通过 Influx_inspect CLI工具+一些bash / grep / tr / cut后处理来完成。它对我有用,没有内存问题从InfluxDB v1.2.4导出> 300M行。

关键是使用 Influx_inspect - 像influx -database 'metrics' -execute 'select * from cpu' -format 'csv'这样的命令惨遭失败。

这样的脚本将以涌入行协议格式创建包含数据的文件:

#!/bin/bash
month=2017-04

db=YOUR_DBNAME
rp=autogen
datadir=/data/influxdb/data
waldir=/data/influxdb/wal
outdir=/somepath/influx_export

for d in 0{1..9} 10 ; do
    echo $(date) Running time influx_inspect export -database $db -retention $rp -datadir $datadir -waldir $waldir -compress -start ${month}-${d}T00:00:00Z -end ${month}-${d}T23:59:59Z -out $outdir/export.${month}-${d}.lineproto.gz
    time influx_inspect export -database $db -retention $rp -datadir $datadir -waldir $waldir -compress -start ${month}-${d}T00:00:00Z -end ${month}-${d}T23:59:59Z -out $outdir/export.${month}-${d}.lineproto.gz
    echo $(date) Done
done

然后可以使用后处理步骤将这些lineproto文件转换为CSV。

在我看来,输出文件中的数据行看起来像:

# some header lines then data lines:
device_interfaces,device=10.99.0.6,iface_in=998,iface_out=87 packets=1030000i 1488358500000000000
device_interfaces,device=10.99.0.6,iface_in=998,iface_out=87 packets=2430000i 1488358800000000000
device_interfaces,device=10.99.0.6,iface_in=998,iface_out=875 bytes=400000i 1488355200000000000
device_interfaces,device=10.99.0.6,iface_in=998,iface_out=875 bytes=400000i 1488356400000000000
device_interfaces,device=10.99.0.6,iface_in=998,iface_out=875 packets=10000i 1488355200000000000

这里的不好之处在于测量的数据字段以单独的行和随机顺序排列。

在我的情况下,转换脚本只是将每个测量数据字段(数据包和字节)放到一个单独的CSV文件中(我稍后在数据库中加入它们)。您可能需要自定义或编写自己的。

MEASUREMENT=YOUR_MEASUREMENT_NAME
for file in *lineproto.gz ; do
   echo -e "--- $(date) Processing file $file ...."

    for field in packets bytes ; do
       # uncompress, strip some header lines, delete junk chars and measurement name, replace spaces with comma
       gzip -dc ${file} | grep "${MEASUREMENT},device" | grep $field | tr -d a-zA-Z_=- | tr -s ' ' , | cut -b1 --complement >> field_${field}.csv
       echo -e "Conversion for $db field ${field} done"
    done
    echo -e "--- File $file processed at $(date)"
done