속도에 맞게 분쇄를 어떻게 최적화 할 수 있습니까?


22

osm2pgrouting을 통해 생성 된 postgis 데이터베이스에서 pgrouting을 사용하고 있습니다. 제한된 데이터 세트 (3.5k 방식, 모든 최단 경로 A * 검색 <20ms)에서 매우 우수합니다.

그러나 europe.osm에서 더 큰 경계 상자 (122k 방법)를 가져 오기 때문에 성능이 크게 떨어졌습니다 (최소 경로 비용은 약 900ms).

나는 A *를 사용하면 대부분의 가장자리가 방해가되지 않으므로 방문하지 않을 것이라고 생각합니다.

속도를 향상시키기 위해 지금까지 한 일 :

  • 지오메트리 열에 인덱스를 넣습니다 (눈에 띄는 효과 없음)
  • 메모리가 8GB에서 16GB로 증가했습니다.
  • postgresql 메모리 설정 (shared_buffers, effective_cache_size)을 (128MB, 128MB)에서 (1GB, 2GB)로 변경하십시오 (눈에 띄는 효과 없음)

나는 대부분의 작업이 그래프가 만들어지는 C Boost 라이브러리에서 수행되고 postgresql을 최적화해도 더 나은 결과를 얻지 못한다고 생각합니다. 모든 검색에 대해 A *에 대해 선택한 행 집합을 약간 변경하면 부스트 라이브러리가 그래프를 캐시 할 수 없으며 매번 122k 가장자리를 모두 다시 작성해야한다고 두려워합니다. 쿼리마다 제한된 하위 집합). 그리고 실제로 가장 짧은 경로 검색과 비교하여 얼마나 많은 비용을 소비하는지 알 수 없습니다.

122k 이상의 OSM 데이터 세트에서 그라우팅을 사용하는 사람이 있습니까? 어떤 성능을 기대해야합니까? 어떤 설정이 성능에 가장 영향을 줍니까?


2
나는 pgrouting 전문가는 아니지만 공통 하위 경로가 항상 사용된다는 것을 알고 있다면 결과를 캐시 할 수 있습니까? 따라서 더 적은 검색을해야합니까? 또한 검색을 동맥 및 수집기로 제한합니까?
dassouki

1
무료 검색 ATM을 허용하므로 하위 경로에 대해 많은 것을 가정 할 수 있다고 생각합니다. 또한 지난 x 분 동안의 검색 결과를 캐싱하지만 새로운 검색에는 도움이되지 않습니다. 전체 그래프를 메모리에 정적으로 유지할 수있는 한이 크기의 A *가 여전히 빠르다는 느낌이 있습니다. 성능 향상 방법을 알고있는 전국으로이 길을가는 사람들이 있어야합니다.
mrg

1
다른 옵션은 O / D 매트릭스 (원산지 / 목적지 매트릭스)를 구축하는 것입니다. 이것은 우리가 교통 공학에 사용하는 기술입니다. 네트워크를 여러 영역으로 나누면 대도시에 100 개의 영역이있을 수 있습니다. 각 구역에는 더미 중심이 있습니다. 더미 링크를 통해 중심을 네트워크에 연결하십시오. 그런 다음 전체 네트워크를 100 x 100 트립 (총 10,000 트립)으로 리모델링 할 수 있습니다. 사용자가 검색을 수행 할 때 pgrouting은 출발지 및 목적지 측의 중심 또는 더미 링크에 닫힌 경로를 찾아야합니다.
dassouki

2
누군가가 한 영역에서 다음 영역으로 가고 싶지만 중심을 통과하면 이상한 결과를 얻지 못합니까? 또는 영역이 더 떨어져있을 때만 사용합니까? 고객이 A에서 B로 가장 빨리 가고 싶어하면 솔루션이 가장 합리적이지만 내 경우에는 여가를 위해 걷기, 자전거 등을 걷고 싶어하고 독특한 경로를 선택하고 강제로 가지 않으려는 고객을 처리해야합니다. 표준 경로를 통해.
mrg

3
멀티 모달 솔루션 (자전거, 도보, 대중 교통, 운전)을 찾고 있다면 OpenTripPlanner를 사용하는 오레곤의 TriMet 멀티 모달 라우팅 사이트 인 Portland (triet.org/news/releases/oct15-rtp)를 실제로 살펴 봐야합니다. htm
RyanDalton 16:15에

답변:


10

이와 같은 작업에 직면 할 때 기본 목표는 합리적입니다. '직감'에 따라 매개 변수를 변경하지 마십시오. 직감은 할리우드에서는 효과가있는 것처럼 보이지만 현실 세계에 사는 우리에게는 그렇지 않습니다. 글쎄, 적어도 내 직감 ;-).

당신은해야합니다 :

  1. 사용 가능하고 반복 가능한 메트릭 설정 (예 : pgrouting query에 필요한 시간)

  2. 메트릭 결과를 스프레드 시트에 저장하고 평균을냅니다 (최고 및 최저). 변경 사항이 올바른 방향으로 가고 있는지 알려줍니다

  3. 쿼리가 실행되는 동안 top 및 vmstat (* nix를 사용한다고 가정)를 사용하여 서버를 모니터링하고 많은 패턴, io, high cpu, swapping 등 많은 패턴을 찾으십시오. cpu가 i / o를 기다리는 경우 개선을 시도하십시오. 디스크 성능 (이것은 쉬워야합니다 (아래 참조)). CPU가 디스크를 많이 사용하지 않고 100 % 인 경우 쿼리를 개선 할 수있는 방법을 찾아야합니다 (아마도 더 어려울 것입니다).

단순화를 위해 네트워크가 여기서 중요한 역할을하지 않는다고 가정합니다.

데이터베이스 성능 향상

최신 Postgres 버전으로 업그레이드하십시오. 버전 9는 이전 버전보다 훨씬 좋습니다. 무료이기 때문에 이유가 없습니다.

내가 이미 여기에서 추천 한 책을 읽으 십시오 .

당신은 정말로 그것을 읽어야합니다. 이 사건과 관련된 장은 5,6,10,11이라고 생각합니다

디스크 성능 향상

  1. SSD 드라이브를 가져 와서 전체 데이터베이스를 넣으십시오. 읽기 성능은 거의 4 배가되고 쓰기 성능도 크게 향상됩니다.

  2. postgres에 더 많은 메모리를 할당하십시오. 이상적으로는 전체 (또는 가장 인기있는 부분)를 메모리에 캐시 할 수 있도록 메모리를 충분히 할당 할 수 있어야하지만 너무 많이 스왑이 발생하지 않아야합니다. 교환은 매우 나쁘다. 이에 대해서는 이전 단락에서 인용 한 책에서 다룹니다.

  3. 모든 디스크에서 atime을 비활성화합니다 ( fstab에 noatime 옵션 추가 ).

쿼리 성능 향상

위에 인용 된 책에 설명 된 도구를 사용하여 쿼리를 추적하고 최적화 할 가치가있는 정지 점을 찾으십시오.

최신 정보

주석 후 저장 프로 시저의 소스 코드를 살펴 보았습니다.

https://github.com/pgRouting/pgrouting/blob/master/core/src/astar.c

쿼리가 조정되면 알고리즘이 메모리에서 완전히 실행되므로 불행히도 CPU가 하나뿐이므로 개선의 여지가 훨씬 더없는 것 같습니다. 유일한 해결책은 더 나은 / 더 빠른 알고리즘 또는 멀티 스레드를 실행할 수있는 알고리즘을 찾은 다음 pgrouting과 같은 라이브러리를 만들거나 미들웨어를 사용하여 데이터를 검색 (및 캐시)하여 postgres와 통합하는 것입니다. 알고리즘에 공급하십시오.

HTH


나는 당신이 추천 한 책의 일부를 읽었습니다. 내 데이터 세트는 여전히 메모리에 완전히 들어갈 정도로 작기 때문에 디스크 성능에 병목 현상이 없어야한다고 생각합니다 (이를 확인하기 위해 테스트 할 때 리소스를 확인하는 것이 좋습니다). Postgresql은 테이블에서 간단한 선택 *를 수행 할 때 실제 검색을 수행하기 위해 행 / 튜플로 C Boost 라이브러리에 피드를 제공 할 때 pgrouting 프로세스에서만 작동한다고 생각합니다 (누군가 이것을 확인할 수 있음). 많은 PostgreSQL을 그 자체로 얻기 위해 당신의 대답은 특정 성능을 pgrouting에 대한 PostgreSQL의 성능이 아주 좋은 것 같지만 아마 그래서..
MRG

@mrg 나는 실제로 그것을 생각했지만, 당신이 낮은 매달려 과일을 남기지 않기를 원했습니다. 그것을 생각하면 당신은 3.5k의 경우 20ms에서 122k의 경우 900ms로갔습니다. 행운을 빕니다
unicoletti

솔리드 스테이트 드라이브는 성능을 향상시킵니다 (캐싱과 비슷한 속도)
Mapperz

내 경험에 따르면 모든 데이터 세트 (테이블)에서 pgrouting을 사용하면 Postgres 엔진의 이점이 없습니다. 색인은 쓸모가 없어서 사용되지도 않습니다. 모든 쿼리에서 전체 테이블이 메모리에로드됩니다. 공유 버퍼와 캐시는 모든 쿼리가 모든 테이블을 메모리에로드하기 때문에 성능상의 이점을 제공하지 않았습니다. 추후 쿼리를 위해 메모리에로드 된 데이터를 재사용하는 사람이 있으면 알려주십시오. SDD 드라이브에서는 성능이 향상 될 수 있지만 테스트 한 적은 없습니다. 더 많은 메모리는 성능이 아닌 더 많은 동시 쿼리 만 허용합니다.
마리오 밀러

8

나는 똑같은 문제를 겪었고 메일 링리스트를 물어 보려고 했으므로 모두에게 감사합니다!

내가 사용하고 슈팅 스타 라우팅 테이블 만 반 행이. 계산하는 데 거의 10 초가 걸립니다. 20k 행으로 거의 3 초가 걸립니다. 회전 제한이 필요하기 때문에 슈팅 스타가 필요합니다.

구현하려는 아이디어는 다음과 같습니다.

  • pgRouting이 방법을 얻는 SQL에서 st_buffer를 사용하여 모든 방법을 얻지 않고 "가까운"방법을 얻습니다.

    id = '|| source_ ||'또는 id = '|| target | 라우팅에서 지오메트리로 * from shortest_path_shooting_star ('SELECT rout. * from route rout, (st_buffer (st_envelope (st_collect (geometry)), 4)를 라우팅에서 지오메트리로 선택) ') e WHERE rout.geometry && e.geometry', 소스, 대상, 참, 참);

성능이 향상되었지만 버퍼 외부로 나가야 할 경우 "경로를 찾을 수 없음"오류를 반환 할 수 있습니다. 큰 버퍼? 방법을 찾을 때까지 버퍼를 증가시키는 여러 호출?

  • 캐시 된 빠른 경로

dassouki가 제안한 것처럼, 나는 "유용한"경로를 캐싱 할 것이므로 거리가 너무 길면이 빠른 경로를 통과 할 수 있고 길을 찾아야 만합니다.

  • gis 인덱스 별 파티션 테이블

그러나 메모리에 들어가면 실제로 중요하지 않다고 생각합니다. 어쨌든 테스트해야합니다.

다른 아이디어를 찾으면 계속 게시하십시오.

또한 Postgres9 용으로 컴파일 된 pgRouting이 있는지 알고 있습니까?


+1 여기에는 유용하고 건설적인 아이디어가 있습니다. 질문에 대한 답변을 받으려면 새 질문으로 공식화하는 것이 가장 좋습니다. 우리의 질문은 진행 방법을 알려줍니다.
whuber

Délawen, 나는 또한 당신의 첫 번째 아이디어 (ST_Buffer)에 대해 생각하고 동일한 문제를 예견했습니다. 그러나 이점은 두 가지 방법 일 수 있습니다. 데이터 세트가 더 작고 더 빠르며 Postgresql에서 더 많은 처리가 수행됨에 따라 다시 최적화 할 수있는 방법이 있습니다. Atm postgresql 8.4가 최신 버전 인 Ubuntu 11을 사용하고 있습니다.
mrg

mrg, PostgreSQL 9.0 용 Ubuntu Maverick에서 pgRouting을 많은 문제없이 컴파일했습니다. PostgreSQL 9.0 용 Postgis는 여기에서 찾을 수 있습니다 : ppa.launchpad.net/pi-deb/gis/ubuntu maverick / main amd64 패키지
Délawen

나는 2 가지 아이디어를 생각해 냈습니다. 1) '빠른 경로 캐시'와 'st_buffer'의 조합. 그렇게하면 경로를 찾을 수 있으며 사람들이 모두 같은 경로를 강요하지는 않습니다. 2) postgis 만 사용하여 정적 그래프 (Boost (C), nx_spatial (Python), neo4j (Java) 등)를 채우고 모든 검색어에 대해 해당 그래프를 재사용하십시오.
mrg

시작과 끝 사이의 거리가 임계 값보다 클 때 고속도로와 같은 '빠른'모서리에 대한 비용을 낮추는 (즉, 선호도를 높이는 것은 어떻습니까)? 부스트 팩터는 또한 거리와 관련이있을 수 있습니다. 거리가 멀수록 클수록 짧아 질수록 작아집니다.
unicoletti

5

우리는 회전 제한 최단 경로 @ https://github.com/pgRouting/pgrouting/tree/trsp에 대해 git에 지점을 만들었습니다.

죄송합니다. 아직 문서가 없지만 pgRouting 목록에 대해 질문을하면 거기에서 전화를 걸어 응답합니다. 이 코드는 슈팅 스타보다 훨씬 빠르게 실행되며 Dijkstra 알고리즘을 기반으로합니다.

-스티브


0

~ 1200000 개의 가장자리가 포함 된 소스 라우팅 테이블이 있습니다. SSD가 장착 된 i7에서는 경로를 만드는 데 12 초가 걸립니다. 성능을 높이려는 생각은 가장자리 테이블을 여러 확대 / 축소 수준 테이블로 나누는 것입니다. Google 타일과 동일한 수준을 의미합니다. 예를 들어 8 번째 확대 / 축소 수준에는 88 개의 테이블이 있습니다. 각 테이블에는 도로의 하위 집합이 포함되어 있으며 해당 영역이 서로 겹치므로 서로 290km 떨어진 두 지점 사이의 경로를 계산하는 데 2 ​​초가 걸립니다. 계산의 9 번째 수준에서 0.25 초로 떨어지고 352 개의 테이블이 있습니다. 도로를 편집하는 데 1 시간을 넘지 않는 경우 모든 그래프를 재현합니다. 라우팅 속도를 높이는 근본적인 방법은 Floyd-Warshall 알고리즘을 사용하는 것입니다. 그러나 많은 모서리에서 선행 행렬을 계산하는 데 얼마나 많은 비용이 드는지 아무도 모른다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.