Làm thế nào tôi có thể tối ưu hóa tốc độ cho tốc độ?


22

Tôi đang sử dụng pgrouting trên cơ sở dữ liệu postgis được tạo thông qua osm2pgrouting. Nó thực hiện rất tốt trên một tập dữ liệu giới hạn (3,5k cách, tất cả các đường dẫn ngắn nhất A * tìm kiếm <20 ms).

Tuy nhiên, vì tôi đã nhập một hộp giới hạn lớn hơn (122 nghìn cách) từ europe.osm, hiệu suất đã giảm đi rất nhiều (một con đường ngắn nhất có giá khoảng 900ms).

Tôi sẽ nghĩ rằng việc sử dụng A * hầu hết các cạnh đó sẽ không bao giờ được truy cập khi chúng ở ngoài đường.

Những gì tôi đã làm cho đến nay trong một nỗ lực để cải thiện tốc độ:

  • Đặt một chỉ mục trên cột hình học (không có hiệu ứng đáng chú ý)
  • Tăng bộ nhớ của tôi từ 8GB lên 16GB
  • Thay đổi cài đặt bộ nhớ postgresql (shared_buffers, effect_cache_size) từ (128MB, 128MB) thành (1GB, 2GB) (không có hiệu ứng đáng chú ý)

Tôi có cảm giác rằng hầu hết các công việc đang được thực hiện trong thư viện C Boost, nơi đồ thị đang được thực hiện để tối ưu hóa postgresql sẽ không cho tôi kết quả tốt hơn nhiều. Khi tôi thực hiện các thay đổi nhỏ đối với nhóm hàng tôi chọn cho A * cho mỗi tìm kiếm, tôi hơi sợ rằng thư viện boost không thể lưu trữ biểu đồ của tôi và phải xây dựng lại tất cả các cạnh 122k mỗi lần (mặc dù nó sẽ chỉ sử dụng rất tập hợp con giới hạn mọi truy vấn). Và tôi không biết bao nhiêu chi tiêu để làm điều đó so với tìm kiếm con đường ngắn nhất thực tế.

Có ai trong số các bạn sử dụng pgrouting trên bộ dữ liệu OSM 122k trở lên không? Tôi nên mong đợi hiệu suất nào? Những cài đặt nào ảnh hưởng đến hiệu suất nhất?


2
Tôi không phải là một chuyên gia về trải nghiệm, nhưng bạn có thể lưu trữ kết quả không, ví dụ, nếu bạn biết một tuyến phụ phổ biến luôn được sử dụng, bạn có thể kiểm tra trước không? do đó, bạn phải làm ít tìm kiếm hơn? Ngoài ra, van bạn giới hạn tìm kiếm để Arterials và sưu tập?
dassouki

1
Tôi cho phép atm tìm kiếm miễn phí, vì vậy tôi không nghĩ rằng tôi có thể giả định nhiều cho các tuyến phụ. Ngoài ra, tôi đang lưu trữ kết quả của các tìm kiếm trong x phút cuối cùng, nhưng điều đó không giúp tôi cho các tìm kiếm mới. Tôi có cảm giác rằng A * trên kích thước này vẫn phải thực sự nhanh miễn là tôi có thể giữ toàn bộ biểu đồ tĩnh trong bộ nhớ. Phải có những người định tuyến theo cách này trên cả một quốc gia biết cách cải thiện hiệu suất.
mrg

1
Một lựa chọn khác là xây dựng ma trận O / D (ma trận gốc / ma trận đích). Đây là một kỹ thuật chúng tôi sử dụng trong kỹ thuật giao thông. chia mạng thành các khu vực, vì vậy giả sử một thành phố lớn có thể có 100 khu. Mỗi khu vực sẽ có một trung tâm giả. Kết nối trung tâm với mạng của bạn thông qua một liên kết giả. Sau đó, bạn có thể sửa sang lại toàn bộ mạng của mình dưới dạng 100 x 100 chuyến (tổng cộng 10.000 chuyến). Khi người dùng thực hiện tìm kiếm, pgrouting phải tìm một tuyến đường được đóng vào liên kết trung tâm hoặc hình nộm ở phía gốc và đích.
dassouki

2
Bạn sẽ không nhận được kết quả kỳ lạ nếu ai đó muốn đi từ vùng này sang vùng khác nhưng họ được chuyển qua trung tâm của họ? Hay bạn chỉ sử dụng điều này khi các khu vực cách xa nhau? Giải pháp của bạn có ý nghĩa nhất nếu khách hàng muốn đi nhanh nhất từ ​​A đến B, nhưng trong trường hợp của tôi, tôi phải đối phó với những khách hàng muốn đi bộ, đạp xe, vv để giải trí và muốn chọn những tuyến đường độc đáo và không bị buộc phải đi thông qua các tuyến đường tiêu chuẩn.
mrg

3
Nếu bạn đang tìm kiếm một giải pháp đa phương thức (xe đạp, đi bộ, vận chuyển công cộng, lái xe), bạn thực sự nên xem qua trang web định tuyến đa phương thức TriMet của Portland, Oregon, sử dụng OpenTripPlanner: trimet.org/news/release/oct15-rtp. htm
RyanDalton

Câu trả lời:


10

Khi phải đối mặt với các nhiệm vụ như thế này, mục tiêu chính của bạn là hợp lý. Đừng thay đổi thông số dựa trên 'cảm giác ruột'. Mặc dù ruột dường như hoạt động cho Hollywood nhưng nó không dành cho chúng ta sống trong thế giới thực. Chà, ít nhất không phải ruột của tôi ;-).

Bạn nên:

  1. thiết lập một số liệu có thể sử dụng và có thể lặp lại (như thời gian được yêu cầu bởi một truy vấn mở rộng)

  2. lưu kết quả số liệu trong một bảng tính và tính trung bình chúng (loại bỏ tốt nhất và tồi tệ nhất). Điều này sẽ cho bạn biết nếu những thay đổi bạn đang thực hiện đang đi đúng hướng

  3. giám sát máy chủ của bạn bằng cách sử dụng top và vmstat (giả sử bạn đang bật * nix) trong khi các truy vấn đang chạy và tìm kiếm các mẫu quan trọng: nhiều io, cpu cao, trao đổi, v.v. Nếu cpu đang chờ i / o thì hãy cố gắng cải thiện hiệu suất đĩa (điều này nên dễ dàng, xem bên dưới). Nếu CPU thay vào đó là 100% mà không có bất kỳ hoạt động nào đáng kể trên đĩa, bạn phải tìm cách cải thiện truy vấn (điều này có lẽ sẽ khó hơn).

Để đơn giản, tôi cho rằng mạng không đóng vai trò quan trọng nào ở đây.

Cải thiện hiệu suất cơ sở dữ liệu

Nâng cấp lên phiên bản Postgres mới nhất. Phiên bản 9 tốt hơn nhiều so với các phiên bản trước. Nó là miễn phí nên bạn không có lý do gì phải không.

Đọc cuốn sách tôi đề nghị đã ở đây .

Bạn thực sự nên đọc nó. Tôi tin rằng các chương liên quan cho trường hợp này là 5,6,10,11

Cải thiện hiệu suất đĩa

  1. Nhận một ổ đĩa SSD và đặt toàn bộ cơ sở dữ liệu vào nó. Hiệu suất đọc nhiều khả năng sẽ tăng gấp bốn lần và hiệu suất ghi cũng sẽ cải thiện triệt để

  2. gán thêm bộ nhớ cho postgres. Lý tưởng nhất là bạn có thể chỉ định đủ bộ nhớ để toàn bộ (hoặc phần nóng nhất) có thể được lưu vào bộ nhớ, nhưng không quá nhiều để xảy ra hoán đổi. Trao đổi là rất xấu. Điều này được đề cập trong cuốn sách được trích dẫn trong đoạn trước

  3. vô hiệu hóa atime trên tất cả các đĩa (thêm tùy chọn noatime vào fstab)

Cải thiện độ hoàn hảo của truy vấn

Sử dụng các công cụ được mô tả trong sách được trích dẫn ở trên để theo dõi truy vấn / tìm kiếm của bạn và tìm các điểm dừng đáng để tối ưu hóa.

Cập nhật

Sau khi nhận xét tôi đã xem mã nguồn cho thủ tục được lưu trữ

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

và dường như một khi truy vấn đã được điều chỉnh thì sẽ không còn nhiều chỗ để cải thiện vì thuật toán chạy hoàn toàn trong bộ nhớ (và thật không may, chỉ trên một cpu). Tôi e rằng giải pháp duy nhất của bạn là tìm một thuật toán tốt hơn / nhanh hơn hoặc một thuật toán có thể chạy đa luồng và sau đó tích hợp nó với các postgres bằng cách tạo một thư viện như pgrouting hoặc sử dụng một số phần mềm trung gian để lấy dữ liệu (và có thể lưu trữ bộ đệm) đưa nó vào thuật toán.

HTH


Tôi đã đọc các phần của cuốn sách mà bạn đề nghị. Tập dữ liệu của tôi vẫn đủ nhỏ để phù hợp hoàn toàn với bộ nhớ vì vậy tôi nghĩ hiệu suất đĩa không phải là nút cổ chai (tôi sẽ kiểm tra tốt hơn tài nguyên của mình khi kiểm tra để xác nhận điều này). Tôi nghĩ Postgresql chỉ hoạt động trong quy trình mở rộng khi nó thực hiện một lựa chọn đơn giản * từ bảng để cung cấp thư viện C Boost với hàng / bộ dữ liệu để thực hiện tìm kiếm thực ((ai đó có thể xác nhận điều này) vì vậy tôi sợ rằng không có gì Nhiều thứ để đạt được trong chính Postgresql. Câu trả lời của bạn có vẻ rất tốt đối với hiệu suất của Postgresql nhưng có lẽ không phải như vậy đối với hiệu suất cụ thể.
mrg

@mrg Tôi thực sự đã nghĩ về điều đó, nhưng tôi muốn chắc chắn rằng bạn đã không bỏ đi những quả treo thấp. Nghĩ về nó bạn đã đi từ 20ms cho 3,5k đến 900ms cho 122k, đó là, imho, không hoàn toàn xấu. Chúc may mắn
unicoletti

Ổ đĩa thể rắn giúp tăng hiệu suất (tốc độ tương tự với bộ nhớ đệm)
Mapperz

Theo kinh nghiệm của tôi, nếu sử dụng pgrouting trên tất cả các tập dữ liệu (bảng) thì không có lợi ích lớn từ công cụ Postgres. Index thậm chí không được sử dụng nên vô dụng. Trên mỗi truy vấn, toàn bộ bảng được tải vào bộ nhớ. bộ đệm và bộ đệm được chia sẻ cũng không mang lại bất kỳ lợi ích hiệu năng nào vì mọi truy vấn sẽ tải tất cả bảng vào bộ nhớ. Nếu bất cứ ai đã thành công để sử dụng lại dữ liệu được tải trong bộ nhớ cho các truy vấn tiếp theo, vui lòng cho chúng tôi biết. Chỉ có thể tăng hiệu suất có thể tôi thấy trong các ổ SDD, nhưng tôi chưa bao giờ thử nghiệm nó. Nhiều bộ nhớ hơn chỉ cho phép truy vấn đồng thời nhiều hơn, không phải hiệu suất.
Mario Miler

8

Tôi có cùng một vấn đề và sắp hỏi về danh sách gửi thư, cảm ơn mọi người!

Tôi đang sử dụng Chụp sao với một triệu rưỡi hàng trên bảng định tuyến. Phải mất gần mười giây để tính toán nó. Với 20k hàng phải mất gần ba giây. Tôi cần Chụp sao vì tôi cần hạn chế rẽ.

Dưới đây là một số ý tưởng tôi đang cố gắng thực hiện:

  • Trên SQL, nơi pgRouting có được các cách, hãy sử dụng st_buffer để nó không có mọi cách, mà chỉ là các cách "gần đó":

    chọn * từ shortest_path_sh Boot_star ('CHỌN CHỌN. * TỪ định tuyến định tuyến, (chọn st_buffer (st_en phong (st_collect (hình học)), 4) làm hình học từ định tuyến trong đó id =' | | source_ || 'hoặc id =' | | target | | ') e WHERE Rout.geometry && e.geometry', nguồn, đích, true, true);

Nó đã cải thiện hiệu năng, nhưng nếu cách cần đi ra ngoài bộ đệm, nó có thể trả về lỗi "không tìm thấy đường dẫn", vậy ... bộ đệm lớn? vài cuộc gọi tăng bộ đệm cho đến khi nó tìm thấy một cách?

  • Các tuyến nhanh được lưu trữ

Giống như dassouki đề xuất, tôi sẽ lưu trữ một số tuyến đường "hữu ích" để nếu khoảng cách quá dài, nó có thể đi qua các tuyến đường nhanh này và chỉ cần tìm đường vào và ra.

  • Bảng phân vùng theo chỉ số gis

Nhưng tôi cho rằng, nếu nó đi vào bộ nhớ, nó không thực sự quan trọng ... Dù sao đi nữa, nên kiểm tra nó.

Xin vui lòng, tiếp tục gửi bài nếu bạn tìm thấy một ý tưởng khác.

Ngoài ra, bạn có biết nếu có một số pgRouting được biên dịch cho Postgres9 không?


+1 Dường như có một số ý tưởng hữu ích và mang tính xây dựng ở đây. Xin lưu ý rằng nếu bạn muốn câu hỏi của mình được trả lời, thì tốt nhất nên đặt câu hỏi đó thành một câu hỏi mới. Câu hỏi thường gặp của chúng tôi sẽ cho bạn biết làm thế nào để tiến hành.
whuber

Délawen, tôi cũng đã suy nghĩ về ý tưởng đầu tiên của bạn (ST_Buffer) và thấy trước vấn đề tương tự. Tuy nhiên, lợi thế có thể là 2 cách: bộ dữ liệu nhỏ hơn và do đó nhanh hơn và vì quá trình xử lý đang được thực hiện trong Postgresql, bạn có cách để tối ưu hóa lại. Tôi đang sử dụng Ubuntu 11 trong đó postgresql 8.4 là phiên bản mới nhất.
mrg

mrg, tôi đã biên dịch pgRouting trên Ubuntu Maverick cho PostgreSQL 9.0 mà không gặp vấn đề gì nhiều. Có thể tìm thấy Postgis cho PostgreSQL 9.0 tại đây: ppa.launchpad.net/pi-deb/gis/ub Ubuntu maverick / gói amd64 chính
Délawen

Tôi đã đưa ra 2 ý tưởng. 1) Kết hợp 'các tuyến nhanh được lưu trong bộ nhớ cache' và 'st_buffer'. Bằng cách đó, bạn đảm bảo tìm thấy một tuyến đường và mọi người sẽ không bị ép buộc trên cùng một tuyến đường. 2) Chỉ sử dụng postgis để điền vào biểu đồ tĩnh (với Boost (C), nx_spatial (Python), neo4j (Java), v.v.) và sử dụng lại biểu đồ đó cho mọi truy vấn tìm kiếm.
mrg

Điều gì về việc giảm chi phí (tức là tăng ưu tiên) cho các cạnh 'nhanh' như đường cao tốc khi khoảng cách giữa điểm bắt đầu và điểm kết thúc lớn hơn ngưỡng? Hệ số tăng cũng có thể liên quan đến khoảng cách: lớn hơn cho khoảng cách dài hơn, nhỏ hơn cho ngắn hơn.
unicoletti

5

Chúng tôi vừa tạo một nhánh trong git cho một lối đi ngắn nhất bị giới hạn lần lượt @ https://github.com/pgRouting/pgrouting/tree/trsp

Xin lỗi chưa có tài liệu nào, nhưng nếu bạn đặt câu hỏi trong danh sách pgRouting, tôi sẽ ở đó và sẽ trả lời. Mã này chạy nhanh hơn nhiều so với ngôi sao băng và dựa trên thuật toán Dijkstra.

-Steve


0

Tôi có một bảng lộ trình nguồn chứa ~ 1200000 cạnh. Trên i7 của tôi với SSD, phải mất 12 giây để tạo tuyến đường. Ý tưởng của tôi để tăng hiệu suất là chia bảng cạnh thành nhiều bảng mức thu phóng. Tôi có nghĩa là mức độ giống hệt với gạch google. Ở mức thu phóng thứ 8, ví dụ, tôi có 88 bảng. Mỗi bảng chứa một tập hợp con đường và các khu vực của chúng chồng lên nhau để tính toán một tuyến đường giữa hai điểm nằm cách nhau không quá 290 km mất 2 giây. Ở thời điểm tính toán cấp 9 giảm xuống 0,25 giây và chúng ta có 352 bảng. Giải trí của tất cả các biểu đồ trong trường hợp chúng tôi chỉnh sửa đường mất không quá một giờ. Cách triệt để để tăng tốc độ định tuyến là sử dụng thuật toán Floyd-Warshall. Nhưng không ai biết phải mất bao nhiêu để tính ma trận tiền thân trên rất nhiều cạnh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.