Почему Spark долго вытаскивает данные из базы
Я использую hadoop со spark sql. Обычно когда я вытаскиваю 1000 колон, то это занимает 1-2 сек, но когда больше 2 тыс,то spark зависает и подгружает данные через мин
spark-submit --deploy-mode client --master yarn --num-executors=40 --executor-cores=2 --executor-memory=5G /home/hdoop/SparkApplication/demo-0.0.1-SNAPSHOT.jar
@Configuration
@EnableAutoConfiguration(exclude = {org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration.class})
public class SparkConfig {
@Value("Test Spark Application")
private String appName;
@Value("local[*]")
private String masterUri;
@Bean
public SparkConf sparkConf() {
return new SparkConf()
.setAppName(appName)
.setMaster(masterUri)
.set("spark.sql.debug.maxToStringFields", "1000")
.setJars(new String[]
{"/home/hdoop/SparkApplication/demo-0.0.1-SNAPSHOT.jar"
,"/home/hdoop/SparkApplication/spark-core_2.12-3.0.1.jar"
,"/home/hdoop/SparkApplication/postgresql-42.2.10.jar"});
}
@Service
@EnableAutoConfiguration(exclude = {org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration.class})
public class StackOverFlow implements Serializable {
@Autowired
private SparkConf sparkConf;
public List<Order> getObject(String param, String value, Long limit) {
Encoder<Order> orderEncoder = Encoders.bean(Order.class);
SparkSession session = SparkSession
.builder()
.config(sparkConf)
.getOrCreate();
if (!session.sqlContext().isTraceEnabled()) {
SparkSession.setActiveSession(session);
}
Dataset<Row> jdbcDF = session.read()
.format("jdbc")
.option("url", "jdbc:postgresql:postgres:5432//orders")
.option("driver", "org.postgresql.Driver")
.option("query", "select * from orders o where " + param + " = '" + value + "' limit " + limit)
.option("user", "root")
.option("password", "password")
.load();
List<Order> orders = jdbcDF.as(orderEncoder).collectAsList();
session.stop();
return orders;
}
Ответы (1 шт):
Автор решения: Alex Ott
→ Ссылка
Тут надо смотреть с обоих сторон:
- Какой план генерируется со стороны PostgreSQL - используются ли индексы, и т.п. для данных запросов.
- Спарк читает данные из БД в один поток, даже если имеется несколько экзекуторов. Существуют техники для паралеллизации чтения, такие как указание нескольких queries, или параметров типа numPartitions, etc. (документация) Например, вот ответы на эту тему: 1, 2
- Некоторые драйвера имеют не особо хорошие начальные параметры, так что можно посмотреть в сторону тюнинга
fetchsizeи прочих параметров описанных в документации. Например, еслиfetchsizeпо умолчанию 50, то для выборки 1000 строк нужно будет сделать 20 чтений, а если его увеличить до 1000, то это произойдет за раз.