首页 > 解决方案 > osm2pgsql 导入速度很慢

问题描述

使用 osm2pgsql 方法的导入速度非常慢。我需要提示如何加快导入速度。

服务器设置

6 Core Xenon
20 GB Ram
1400 GB SAS

我的 SAS 驱动器的速度测试

hdparm -tT /dev/sda2
/dev/sda2:
 Timing cached reads:   7492.82 MB/sec
SG_IO: 240.88 MB/sec

导入脚本

osm2pgsql --slim -r pbf -S mapfeatures_export.style -C 14000 -l --number-processes 5 -U osmdata --create --multi-geometry -d osmdatabase planet-190603.osm.pbf 

运行期间的 osm2pgsql 控制台输出

osm2pgsql version 0.96.0 (64 bit id space)

Using built-in tag processing pipeline
Using projection SRS 4326 (Latlong)
Setting up table: planet_osm_point
Setting up table: planet_osm_line
Setting up table: planet_osm_polygon
Setting up table: planet_osm_roads
Allocating memory for dense node cache
Allocating dense node cache in one big chunk
Allocating memory for sparse node cache
Sharing dense sparse
Node-cache: cache=14000MB, maxblocks=224000*65536, allocation method=11
Mid: pgsql, cache=14000
Setting up table: planet_osm_nodes
Setting up table: planet_osm_ways
Setting up table: planet_osm_rels

Reading in file: /home/osmdata/planet-190603.osm.pbf
Using PBF parser.
Processing: Node(5234820k 342.0k/s) Way(15203k 0.20k/s) Relation(0 0.00/s)

我测试了一个 SSD 设置,其中导入速度为 50k/s,但它太贵了。

我遵循了来自https://www.geofabrik.de/media/2012-09-08-osm2pgsql-performance.pdf的优化工具链

希望,还有一些额外的选项可以调整。

标签: osm2pgsql

解决方案


直接回答:尝试将 -C 降低到 4096 左右,您可能没有足够的内存用于 postgres 和 osm2pgsql 进程。此外,尝试使用“--flat-nodes /tmp/mycache.bin”来加速处理直接本地存储而不是使用数据库。也可以尝试 --unlogged 但阅读文档以确保您可以接受后果。

其他想法,如果您在云环境中,请使用性能更高的机器进行加载,例如 aws r5a.2xlarge,然后使用更接近 t3.medium 的机器来提供内容。在云中,您可以将机器用于不同的目的,甚至可以使用 fargate 之类的容器主机进行处理,并且只在运行负载或更新时付费。

我当前在 64G 内存机器上的配置:

  osm2pgsql --create --slim --flat-nodes /tmp/osm-cache.bin -C 18000 --database postgres --unlogged -H osmsource.cu932j20s2i5e.us-east-1.rds.amazonaws.com -U gisloader -W /osmdata/north-america-latest.osm.pbf
  • 使用默认 -C(与 -C 800 相同)加载北美:
    • 节点(1137243k 1202.2k/s)路(92064k 70.22k/s)关系(291320 55.28/s)(停止)
  • 使用-C 11000:
    • 节点(1137243k 3203.5k/s)方式(92064k 70.28k/s)关系(47320 80.87/s)(停止,关系#下降)
    • pct 内存为 27%
  • 使用 --number-processes 5 -C 9000
    • 处理:Node(1137243k 3203.5k/s) Way(92064k 69.96k/s) Relation(226630 54.97/s)(停止)
  • 仅使用 -C 19000 (受监控的线程,默认情况下似乎使用 n-2 个线程)
    • Node(1137243k 3176.7k/s) 取消了类似的性能
  • 增加到一台7.2T nvme ssd驱动和12cpu的96G内存的机器

    • Node(1137243k 6729.3k/s) Way(92064k 90.17k/s) Relation(957280 69.26/s) 解析时间:15012s
  • r5a.2xlarge

  • db.r5.large postgres 11.5 其余为默认值(根据您的需要,rds 实例可能更小,但高于 90% 的 rds cpu 和服务器在负载期间打开和关闭的内存利用率相当高,仅使用约10% 中央处理器)。您需要运行 rds 中的命令来激活扩展(在下面列出或在 aws 文档中搜索这些命令)。加载后,您可能会考虑使用较小的实例类来控制成本或备份/恢复到您自己的机器,或者在 db 位于 rds 实例上时将其关闭。如果您有内存和快速驱动器,则从我读过的内容本地运行会更快。

其他想法:当然可以调整这些设置以获得更好的性能,但对于快速设置,这似乎表现良好并且便宜,只要您在加载后的正常操作期间不将机器留在这些尺寸。上述架构只需大约 8 美元即可加载北美,因此几乎不值得进一步优化。

如果在本地运行 postgres,下一步提高速度的想法:

  • 更多内存
  • 用于平面节点位置的高速临时驱动器或 raid0 存储,因为上面的机器只会推动大约 190MB/s。您需要选择不同类型的机器来使用本地临时 ssd 驱动器,但使用 m5ad 之类的东西,您可以将两个本地 ssd 驱动器绑定到一个 raid0 阵列中,仅受您希望在服务器类和数量上花费的限制驱动器。
  • 更快可能每小时更贵,但是如果您可以平衡负载速度和成本,您可能会发现租用大型机器的能力可能会与时间平衡,并且在两端与时间之间具有高成本尾部,并且成本是长期的低成本中间区域类似但可以缩短时间(成本/小时与速度/小时通过成本优化大致平衡)。如果时间允许,这将是一项有趣的研究。

来自https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html#Appendix.PostgreSQL.CommonDBATasks.PostGIS的任何人的 RDS 命令

create extension postgis;
create extension fuzzystrmatch;
create extension postgis_tiger_geocoder;
create extension postgis_topology;
create extension hstore;

alter schema tiger owner to rds_superuser ;
alter schema tiger_data owner to rds_superuser ;
alter schema topology owner to rds_superuser ;
\dn
CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$ BEGIN EXECUTE $1; RETURN $1; END; $f$;
SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO rds_superuser;')
  FROM (
SELECT nspname, relname
FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid)
WHERE nspname in ('tiger','topology') AND
relkind IN ('r','S','v') ORDER BY relkind = 'S')
s;

--TEST--
SET search_path=public,tiger;   

select na.address, na.streetname, na.streettypeabbrev, na.zip
from normalize_address('1 Devonshire Place, Boston, MA 02109') as na;
select topology.createtopology('my_new_topo',26986,0.5);

--setup for loading
create user gisloader with encrypted password 'somepassword';
create schema gis;
grant all privileges on schema gis to gisloader;

推荐阅读