我需要对一个大小为100亿行的三列表t(s,p,o)运行200万个查询。每列的数据类型都是string。
只有两种类型的查询:
select s p o from t where s = param select s p o from t where o = param
如果我使用java threadpoolexecutor将表存储在postgresql数据库中,需要6个小时。
你认为spark能更快地处理查询吗?最好的策略是什么?以下是我的想法:
把这张table放进一张table里 dataframe
并针对Dataframe启动查询。
把这张table放进一张table里 parquet
并启动对此数据库的查询。
使用spark 2.4对postgresql数据库启动查询,而不是直接查询。
使用spark3.0对加载到pg strom(支持gpu的postgresql扩展模块)中的数据库启动查询。
谢谢,
2条答案
按热度按时间g6ll5ycj1#
在现有mysql或postgressql服务器上使用apachespark(无需将数据导出或流式传输到spark或hadoop)可以将查询性能提高10倍以上。使用多个mysql服务器(replication或percona xtradb cluster)可以提高某些查询的性能。您还可以使用spark cache函数来缓存整个mysql查询结果表。想法很简单:spark可以通过jdbc读取mysql或postgressql数据,还可以执行sql查询,因此我们可以直接将其连接到db并运行查询。为什么这样更快?对于长时间运行的(例如,报告或bi)查询,它可以更快,因为spark是一个大规模并行系统。例如,mysql每个查询只能使用一个cpu核,而spark可以使用所有集群节点上的所有核。
但我建议您不要使用sql(hbase、cassandra等)或新的sql解决方案进行分析,因为当数据规模增加时,它们的性能会更好。
relj7zay2#
静态数据?Spark;否则调postgres
如果这100亿行是静态的或者很少更新,那么最好的办法就是使用带有适当分区的spark。并行化带来了神奇的效果,所以内核越多越好。您希望将目标对准每个分区大小约为半gig的分区。
通过运行
SELECT pg_size_pretty( pg_total_relation_size('tablename'));
将结果除以可用于spark的内核数,直到得到1/8到3/4 gig。如果您真的有静态数据或希望快速从故障中恢复,请另存为parquet。
如果源数据经常更新,那么您需要在postgres中添加索引。它可以像在每一列上添加索引一样简单。在postgres中分区也会有帮助。
坚持发帖。较新的数据库不适用于像您这样的结构化数据。有并行化选项。奥罗拉,如果你在aws。
斯特罗姆警长不会在这里为你工作。你有一些列的简单数据。让他们进出一个gpu是要放慢你太多。