我需要从Postgres数据库获取数据到Accumulo数据库。我们希望使用序列文件来运行map / reduce job来执行此操作,但不确定如何启动。出于内部技术原因,我们需要避免使用Sqoop。
没有Sqoop会有可能吗?再说一次,我真的不知道从哪里开始。我是否编写了一个java类来将所有记录(数百万)读入JDBC并以某种方式将其输出到HDFS序列文件中?
感谢您的任何意见!
P.S。 - 我应该提到使用分隔文件是我们现在遇到的问题。我们的一些是包含分隔符的长字符字段,因此无法正确解析。该字段甚至可能包含一个标签。我们想直接从Postgres转到HDFS而不进行解析。
答案 0 :(得分:1)
您可以使用Avro序列化数据,虽然它不会很快(特别是在示例中使用python时),然后将其加载到hdfs中。
假设你有数据库foo:
postgres=# \c foo
You are now connected to database "foo" as user "user".
foo=#
foo=# \d bar
Table "public.bar"
Column | Type | Modifiers
--------+-------------------------+---------------------------------------------------
key | integer | not null default nextval('bar_key_seq'::regclass)
value | character varying(1024) | not null
您可以创建如下的avro架构:
{"namespace": "foo.avro",
"type": "record",
"name": "bar",
"fields": [
{"name": "id", "type": "int"},
{"name": "value", "type": "string"}
]
}
然后逐行序列化您的数据:
import psycopg2
import avro.schema
from avro.datafile import DataFileReader, DataFileWriter
from avro.io import DatumReader, DatumWriter
schema = avro.schema.parse(open("foo.avsc").read())
writer = DataFileWriter(open("foo.avro", "w"), DatumWriter(), schema)
c = psycopg2.connect(user='user', password='s3cr3t', database='foo')
cur = c.cursor()
cur.execute('SELECT * FROM bar')
for row in cur.fetchall():
writer.append({"id": row[0], "value": row[1]})
writer.close()
cur.close()
c.close()
或者,您可以使用普通的json序列化数据。
答案 1 :(得分:0)
您可以将数据从数据库导出为CSV或制表符分隔或管道分隔或Ctrl-A(Unicode 0x0001)分隔文件。然后你可以将这些文件复制到HDFS并运行一个非常简单的MapReduce作业,甚至可以只包含一个Mapper并配置为读取你使用的文件格式并输出序列文件。
这将允许在Hadoop集群的服务器之间分配用于创建序列文件的负载。
此外,最有可能的是,这不是一次性交易。您必须定期将Postgres数据库中的数据加载到HDFS中。他们可以调整MapReduce作业以合并新数据。
答案 2 :(得分:0)
http://sqoop.apache.org/应该按照你的要求行事。