Spark 데이터 프레임에서 Postgres 테이블에 이르기까지 수백만 개의 레코드를 삽입하는 가장 효율적인 방법은 5 천만입니다. 과거에도 대량 복사 및 배치 크기 옵션을 사용하여 스파크에서 MSSQL 까지이 작업을 수행했습니다
.
Postgres에 대해 비슷한 점이 있습니까?
내가 시도한 코드와 프로세스를 실행하는 데 걸린 시간을 추가하십시오.
def inserter():
start = timer()
sql_res.write.format("jdbc").option("numPartitions","5").option("batchsize","200000")\
.option("url", "jdbc:postgresql://xyz.com:5435/abc_db") \
.option("dbtable", "public.full_load").option("user", "root").option("password", "password").save()
end = timer()
print(timedelta(seconds=end-start))
inserter()
그래서 천만 개의 레코드에 대해 위의 접근 방식을 수행 했으며 5 개의 병렬 연결을 지정했으며 numPartitions
배치 크기는 200k 입니다.
프로세스에 소요 된 총 시간은 0 : 14 : 05.760926 (14 분 5 초)입니다.
시간을 줄일 수있는 다른 효율적인 접근 방법이 있습니까?
사용할 수있는 효율적이거나 최적의 배치 크기는 무엇입니까? 배치 크기를 늘리면 작업이 더 빨라 집니까? 또는 5 개 이상의 연결을 열면 프로세스가 더 빨라집니다.
온 1000 만 개 기록을 위해 평균 14 분 나쁘지 않다 , 그러나 거기에서 사람을 찾고 도움이 대답을하기 전에이 질문에 이런 짓을 했 겠어요.
답변
나는 실제로 얼마 전에 같은 일을했지만 Apache Sqoop을 사용했습니다.
이 질문에 답하기 위해 Spark와 PostgresSQL 간의 통신, 특히 Spark에서 PostgreSql으로 흐르는 데이터를 최적화하려고 노력해야한다고 말하고 싶습니다.
그러나 스파크 쪽을 잊지 마십시오. 파티션 수가 너무 많으면 PostgreSQL이 지원하는 최대 연결 수에 비해 파티션 수가 너무 많으면 파티션이 너무 많고 각 파티션에 대한 연결을 여는 경우 mapPartitions 를 실행하는 것은 의미가 없습니다. org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
.
삽입 과정을 조정하기 위해 다음 단계에 따라 문제에 접근합니다.
- 파티션 수는 중요합니다. 파티션 수를 확인한 다음 원하는 병렬 연결 수에 따라 파티션을 조정하십시오. 파티션 당 하나의 연결을 원할 수 있으므로 여기
coalesce
에 언급 된 것처럼 확인하는 것이 좋습니다 . - postgreSQL 인스턴스가 지원하는 최대 연결 수를 확인하고 그 수 를 늘리십시오 .
- COPY 명령을 사용하여 PostgreSQL에 데이터를 삽입하는 것이 좋습니다 . 다음 은 postgreSQL 삽입 속도를 높이는 방법에 대한 자세한 답변입니다.
마지막으로,이 일을하는 데는 총알이 없습니다. 위에서 언급 한 모든 팁을 사용할 수 있지만 실제로는 데이터와 사용 사례에 따라 다릅니다.