如何在nifi中更快地将数据从DB2转储到Cassandra

时间:2019-12-03 08:49:23

标签: cassandra db2 apache-nifi

我有一个需要使用Apache Nifi将数据从DB2加载到Cassandra的要求。 我的DB2表有大约4万条记录,花了大约15分钟才能完成将数据转储到cassandra的过程。 我已为此用例附加了2张当前nifi流的图像。每秒只能读取100条以上的记录。 任何人都可以让我知道-如何调整流/处理器,以便我们可以提高数据转储的速度(减少时间)。

  1. DB2 to Cassandra Nifi Flow - Before Execute script starts
  2. After Execute script started

在附加执行脚本的地方,我们正在为Cassandra转储准备插入语句。

import java.io
from org.apache.commons.io import IOUtils
from java.nio.charset import StandardCharsets
from org.apache.nifi.processor.io import StreamCallback
import json
import csv
import io
import datetime

class TransformCallback(StreamCallback):
    def _init_(self):
        pass
    def process(self,inputStream,outputStream):
        inputdata = IOUtils.toString(inputStream,StandardCharsets.UTF_8)
        text = csv.reader(io.StringIO(inputdata))
        l = []
        for row in text:
            mon = row[0].strip()
            modified_date = str(datetime.datetime.strptime(str(mon), "%d%b%Y").strftime("%Y-%m-%d"))
            row[0] = modified_date
            row[1] = row[1].strip()
            row[2] = row[2].strip()
            l.append(row)
        values_str = json.dumps(l)
        leng = len(l)
        for i in range(leng):
            obj = json.loads(values_str)[i]  ## obj = dict
            newObj = {
                  "date": obj[0],
                  "max": obj[1],
                  "city": obj[2]
                }
            insert_query = ("INSERT INTO model.test_data JSON '"+json.dumps(newObj , indent=4)+"';").encode('utf-8')
            outputStream.write(bytearray(insert_query))


flowFile = session.get()
if flowFile != None:
    flowFile = session.write(flowFile,TransformCallback())
    flowFile = session.putAttribute(flowFile, "filename",flowFile.getAttribute('filename').split('.')[0]+'_result.json')
    session.transfer(flowFile, REL_SUCCESS)
    session.commit()

1 个答案:

答案 0 :(得分:0)

我不得不说,所需的转换可能与两个标准处理器有关:

  • ConvertRecord将CSV记录转换为json
  • ReplaceText将INSERT INTO添加到...

如果您仍然想使用脚本,我可以帮助您解决问题。 以下脚本适用于ExecuteGroovyScript处理器。


每个呼叫处理一个流文件

它将转换流文件中的所有行,因此,不需要在此处理器之前按行分割文件。

import groovy.json.JsonOutput

def ff=session.get()
if(!ff)return

ff.write{rawIn, rawOut->
    rawOut.withWriter("UTF-8"){w->
        rawIn.withReader("UTF-8"){r->
            //iterate lines from input reader and split each with coma
            r.splitEachLine( ',' ){row->
                //build object (map)
                def obj = [
                    "date": row[0],
                    "max" : row[1],
                    "city": row[2]
                ]
                //convert obj to json string
                def json = JsonOutput.toJson(obj)
                //write data to output
                w << "INSERT INTO model.test_data JSON '" << json << "';" << '\n'
            }
        }
    }
}

REL_SUCCESS << ff

每个呼叫处理多个流文件

与先前类似,但具有流文件列表处理fflist.each{ff-> ...}

import groovy.json.JsonOutput

def fflist=session.get(1000)
if(!fflist)return

fflist.each{ff->
    ff.write{rawIn, rawOut->
        rawOut.withWriter("UTF-8"){w->
            rawIn.withReader("UTF-8"){r->
                //iterate lines from input reader and split each with coma
                r.splitEachLine( ',' ){row->
                    //build object (map)
                    def obj = [
                        "date": row[0],
                        "max" : row[1],
                        "city": row[2]
                    ]
                    //convert obj to json string
                    def json = JsonOutput.toJson(obj)
                    //write data to output
                    w << "INSERT INTO model.test_data JSON '" << json << "';" << '\n'
                }
            }
        }
    }

    REL_SUCCESS << ff
}