簡體   English   中英

如何將大數據流轉換為gzip壓縮的base64字符串

[英]How to convert a large stream to a gzipped base64 string

我正在構建一個分析平台,我想先壓縮ETL(提取轉換負載)作業,然后再將其存儲在數據庫中。 在開始編寫代碼之前,我想知道是否有一些經驗的人可以告訴我如何正確地做。 我想gzip數據,然后將其轉換為base64字符串。 我是簡單地gzip轉換為base64還是不能正常工作?

這是我目前用於這些大型數據集的過程。

var streamObj = athenaClient.execute('my query').toStream()
var data = [];

redis.set('Some Dashboard Data', '[')

streamObj.on('data', function(record) {
    // TODO gzip record then convert to base64
    if (data.length === 500) {
        let tempData = JSON.stringify(data);
        data = []
        redis.append('Some Dashboard Data', tempData.slice(1, tempData.length - 1) + ',')
        }
        data.push(record);
    })
}

如果這不可能,有沒有辦法存儲壓縮后的字符串?

讓node.js環境通過使用流提供的背壓來控制內存。

我會考慮這種解決方案:

inputStream
    .pipe(zlib)
    .pipe(transformToBase64Stream)
    .pipe(redisCli);

zlib是本機的,因此不會引起任何問題。 要轉換為base64,可以編寫轉換流或使用外部工具 要將結果按流傳輸redis ,可以在管道模式下生成子進程redis-cli 如大量插入和redis cli文章中所述,建議將其用於大數據,但您必須自己處理redis協議。 閱讀提供的文章,讓我知道它是否有助於解決您的問題。

只是為了進一步闡述Zilvinas的答案。 我將向大家展示我是如何工作的。

const athena = require('./athena')
const redis = require('./redis')
const zlib = require('zlib')
const Stream = require('stream')

exports.persistStream = (config, query, name, transform) => {
return new Promise((resolve, reject) => {
    let recordCount = 0

    var transformStream = new Stream.Transform({ writableObjectMode: true, readableObjectMode: true})
    transformStream._transform = function (chunk, encoding, done) {

        recordCount++

        if (transform) chunk = transform(chunk)

        let jsonChunk = JSON.stringify([chunk])

        switch (true) {
            case recordCount === 1: 
                jsonChunk = jsonChunk.slice(0, jsonChunk.length - 1); break
            default:
                jsonChunk = ',' + jsonChunk.slice(1, jsonChunk.length - 1); break
        }
        this.push(jsonChunk)
        done();
    };

    transformStream._final = function (done) {
        this.push(']')
        done()
    }

    const gzip = zlib.createGzip()

    let buffers = []

    var stream = athena.execute(query)
        .toStream()
        .pipe(transformStream)
        .pipe(gzip)

    gzip.on('data', (chunk) => {
        buffers.push(chunk)
    })

    gzip.on('end', function () {
        let buffer = Buffer.concat(buffers)
        redis.set(name, buffer.toString('base64'), (err, response) => {
            zlib.gzip(config, (err, buff) => {
                redis.set(name + ' Config', buff.toString('base64'), (err, response) => {
                    if (err) {
                        console.log(err)
                        reject()
                    } else {

                        console.log(name + ' succeeded')
                        resolve()
                    }
                })
            })
        })
    })

    stream.on('error', (err) => {
        console.log(err)
        reject()
    })
})
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM