Як я можу оптимізувати pgrouting для швидкості?


22

Я використовую pgrouting на базі даних postgis, створеній через osm2pgrouting. Він працює дуже добре на обмеженому наборі даних (3,5 к. Способів, усі найкоротші A * шляху пошуку <20 мс).

Однак, оскільки я імпортував більшу обмежувальну скриньку (122 тис. Шляхів) з europe.osm, продуктивність значно знизилася (найкоротший шлях коштує близько 900 мс).

Я думаю, що за допомогою A * більшість цих країв ніколи не будуть відвідуватися, оскільки вони не в дорозі.

Що я зробив поки що, намагаючись поліпшити швидкість:

  • Поставте індекс на стовпчик геометрії (жодного помітного ефекту)
  • Збільшив пам'ять з 8 ГБ до 16 ГБ
  • Змініть налаштування пам’яті postgresql (спільні_буфери, ефективні_cache_size) з (128MB, 128MB) на (1GB, 2GB) (жодного помітного ефекту)

У мене таке відчуття, що більша частина роботи проводиться в бібліотеці C Boost, де робиться графік, так що оптимізація postgresql не дасть мені кращих результатів. Оскільки я вношую незначні зміни до набору рядків, які я вибираю для A * для кожного пошуку, я трохи боюся, що бібліотека boost не може кешувати мій графік і повинна кожного разу перебудовувати всі 122 кромки (хоча вона буде використовувати лише дуже обмежений підмножина кожного запиту). І я поняття не маю, скільки витрачено на це, порівняно з фактично найкоротшим пошуком шляху.

Чи використовує хто-небудь із вас програвання на базі даних 122k або більше OSM? Якої продуктивності слід очікувати? Які налаштування найбільше впливають на продуктивність?


2
Я не є експертом по шифрування, але чи можете ви кешувати результати, наприклад, якщо ви завжди знаєте, що загальний підрозділ завжди використовується, чи можете ви його попередньо кешувати? отже, вам доведеться робити менше пошуків? Крім того, ван ви обмежуєте пошуки артеріалів та колекціонерів?
dassouki

1
Я дозволяю вільний пошук атм, тому я не думаю, що я можу припустити багато для під маршрутів. Також я кешую результат пошуку останніх х хвилин, але це не допомагає мені в нових пошуках. У мене таке відчуття, що A * за цим розміром все ще повинен бути дуже швидким, доки я можу зберігати весь графік статичним у пам'яті. Мають бути люди, які прямують цілою країною, які знають, як покращити ефективність.
мр

1
Іншим варіантом було б побудувати матрицю O / D (матриця початку / призначення). Це методика, яку ми використовуємо в машинобудуванні. розділити мережу на зони, так що скажімо, велике місто може мати 100 зон. У кожній зоні був би фіктивний центроїд. Підключіть центроїд до своєї мережі за допомогою макетного посилання. Тоді ви можете переробити всю свою мережу як 100 х 100 поїздок (10 000 поїздок загалом). Коли користувач здійснює пошук, pgrouting повинен знайти маршрут, закритий до центральної або манекенової лінії на стороні початку та призначення.
dassouki

2
Хіба ви не отримуєте дивних результатів, якщо хтось хоче перейти від однієї зони до іншої, але вони проходять через свої центроїди? Або ви використовуєте це лише тоді, коли зони знаходяться далі один від одного? Ваше рішення має найбільш сенс, якщо клієнти хочуть швидше дістатися від А до Б, але в моєму випадку мені доводиться мати справу з клієнтами, які хочуть гуляти, їздити на велосипеді тощо для дозвілля і хочуть вибрати унікальні маршрути і не змушені їхати стандартним маршрутом.
мр

3
Якщо ви шукаєте мультимодальне рішення (велосипед, прогулянка, громадський транспорт, поїздка), вам слід поглянути на Портленд, багатомодальний маршрут маршрутизації TriMet в Орегоні, який використовує OpenTripPlanner: trimet.org/news/releases/oct15-rtp. htm
RyanDalton

Відповіді:


10

Якщо ви стикаєтесь з такими завданнями, ваша основна мета - бути раціональним. Не змінюйте парами на основі "відчуття кишки". Хоча кишка, здається, працює для Голлівуду, це не для нас, хто живе в реальному світі. Ну, принаймні, не моя кишка ;-).

Ти повинен:

  1. встановити корисну та повторювану метрику (як, наприклад, час, необхідний для запиту прутирування)

  2. збережіть метричні результати в електронній таблиці та середнє значення (відкиньте найкращі та гірші). Це підкаже, чи вносяться зміни у правильному напрямку

  3. слідкуйте за своїм сервером за допомогою верхніх і vmstat (припускаючи, що ви перебуваєте на * nix) під час запуску запитів, і шукайте значущі шаблони: багато io, високий процесор, заміна тощо. Якщо процесор чекає вводу / виводу, то спробуйте покращити продуктивність диска (це повинно бути легко, див. нижче). Якщо натомість процесор знаходиться на 100% без будь-якої значної дисковості, вам доведеться знайти спосіб поліпшити запит (це, мабуть, буде складніше).

Для простоти я припускаю, що мережа тут не відіграє значної ролі.

Поліпшення продуктивності бази даних

Оновіть до останньої версії Postgres. Версія 9 настільки краща, ніж попередні версії. Це безкоштовно, тому у вас немає причин, щоб не.

Прочитайте книгу, яку я рекомендував уже тут .

Ви дійсно повинні його прочитати. Я вважаю, що відповідні глави для цієї справи 5,6,10,11

Поліпшення продуктивності диска

  1. Отримайте накопичувач SSD і покладіть на нього всю базу даних. Виконання читання, швидше за все, вчетверо, а продуктивність запису також повинна кардинально покращитися

  2. призначити більше пам’яті постгресам. В ідеалі ви повинні мати можливість призначити достатню кількість пам’яті, щоб ціла (або найгарячіша частина) була збережена в пам’яті, але не надто багато, щоб відбулося заміну. Обмін дуже поганий. Це висвітлено в книзі, цитованій у попередньому пункті

  3. відключити Atime на всіх дисках (додати noatime опції Fstab)

Покращення продуктивності запитів

Скористайтеся інструментами, описаними в наведеній вище книзі, щоб відстежити свій запит / запити та знайти зупинки, які варто оптимізувати.

Оновлення

Після коментарів я переглянув вихідний код збереженої процедури

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

і, здається, що після налаштування запиту не буде набагато більше можливостей для вдосконалення, оскільки алгоритм повністю працює в пам'яті (і, на жаль, лише на одному процесорі). Я боюся, що ваше єдине рішення - знайти кращий / швидший алгоритм або алгоритм, який може запускати багатопотоковість, а потім інтегрувати його з postgres, створюючи бібліотеку типу pgrouting або використовуючи деяке проміжне програмне забезпечення для отримання даних (і, можливо, кешування) подайте його до алгоритму.

HTH


Я прочитав частини рекомендованої вами книги. Мій набір даних ще достатньо малий, щоб повністю вміститись у пам'ять, тому я думаю, що продуктивність диска не повинна бути вузьким місцем (я краще перевіряю свої ресурси при тестуванні, щоб підтвердити це). Я думаю, що Postgresql вступає в гру лише в процесі pgrouting, коли він виконує простий вибір * з таблиці, щоб подати бібліотеку C Boost з рядками / кортежами для здійснення реального пошуку ((може хтось це підтвердити), тому я боюся, що цього не буде багато , щоб отримати в самому Postgresql Ваш відповідь здається дуже хорошою продуктивності Postgresql але , можливо , не так для pgrouting продуктивності конкретної ..
MRG

@mrg Я насправді про це думав, але хотів бути впевнений, що ти не залишив позаду низькорослих плодів. Думаючи про це, ти перейшов від 20 мс до 3,5 к 900 м за 122 к., Що, не так вже й погано. Удачі
unicoletti

Твердотільні накопичувачі підвищують продуктивність (схожі на швидкість кешування)
Mapperz

На моєму досвіді, якщо використовувати pgrouting у всіх наборах даних (таблиці), це не має великої користі від двигуна Postgres. Індекс навіть не використовується, тому його марний. По кожному запиту вся таблиця завантажується в пам'ять. спільні буфери та кеші також не принесли користі для продуктивності, оскільки кожен запит завантажує всю таблицю в пам'ять. Якщо комусь вдалося повторно використати завантажені дані в пам'яті для подальших запитів, будь ласка, повідомте нам. Єдине можливе підвищення продуктивності, яке я бачу на накопичувачах SDD, але я ніколи його не тестував. Більше пам’яті дозволяє лише більше одночасних запитів, а не продуктивності.
Маріо Мілер

8

У мене якраз та сама проблема, і ось-ось я хотів запитати у списках розсилки, тож дякую всім!

Я використовую Shooting Star з мільйоном з половиною рядків на таблиці маршрутизації. На його обчислення потрібно майже десять секунд. З 20k рядками це займає майже три секунди. Мені потрібна Shooting Star, оскільки мені потрібні обмеження повороту.

Ось кілька ідей, які я намагаюся реалізувати:

  • У SQL, де pgRouting отримує шляхи, використовуйте st_buffer, щоб він не отримував усі шляхи, а лише "сусідні" способи:

    виберіть * з shorttest_path_shooting_star ('SELECT маршруту. * FUT від маршрутизації маршрутизації, (виберіть st_buffer (st_envelope (st_collect (геометрія)), 4) як геометрію з маршрутизації, де id =' || source_ || 'або id =' || ціль | | ') e WHERE ruut.geometry && e.geometry', джерело, ціль, вірно, правда);

Це покращило продуктивність, але якщо шлях потрібно вийти за межі буфера, він може повернути помилку "не знайдено шлях", так що ... великий буфер? кілька викликів збільшують буфер, поки він не знайде спосіб?

  • Швидкі кешовані маршрути

Як запропонував dassouki, я буду кешувати кілька «корисних» маршрутів, тому якщо відстань буде занадто довгою, вона може пройти ці швидкі маршрути і просто доведеться знаходити шлях у них та виходити з них.

  • Таблиця розділів за індексом gis

Але я вважаю, що, якщо це йде в пам'ять, це насправді не має значення ... Слід перевірити це, все одно.

Будь ласка, продовжуйте публікувати повідомлення, якщо знайдете іншу ідею.

Крім того, чи знаєте ви, чи є якийсь скомпільований pgRouting для Postgres9?


+1 Тут є деякі корисні та конструктивні ідеї. Зверніть увагу, що якщо ви хочете, щоб відповіді на ваші запитання, то краще сформулювати їх як нове запитання. Наш FAQ допоможе вам розповісти, як діяти.
whuber

Делавен, я також думав над твоєю першою ідеєю (ST_Buffer) і передбачаю ту саму проблему. Перевага, однак, може бути двостороннім: набір даних менший і, отже, швидший, і оскільки більша частина обробки виконується в Postgresql, у вас знову є можливість оптимізувати його. Atm, я використовую Ubuntu 11, де postgresql 8.4 - остання версія.
мр

mrg, я склав pgRouting на Ubuntu Maverick для PostgreSQL 9.0 без особливих проблем. Postgis для PostgreSQL 9.0 можна знайти тут: ppa.launchpad.net/pi-deb/gis/ubuntu maverick / main amd64 Packages
Delaven

Я придумав 2 ідеї. 1) Комбінація "швидких кешованих маршрутів" та "st_buffer". Таким чином ви гарантуєте пошук маршруту, і люди не будуть вимушені на той самий маршрут. 2) Використовуйте postgis лише для заповнення статичного графіка (з Boost (C), nx_spatial (Python), neo4j (Java) тощо) та повторно використовуйте цей графік для кожного пошукового запиту.
мр

Що щодо зниження вартості (тобто підвищення переваги) для «швидких» країв, як шосе, коли відстань між початком і кінцем перевищує поріг? Коефіцієнт підсилення також може бути пов'язаний з відстанню: більший на більші відстані, менший на коротший.
unicoletti

5

Ми тільки що створили гілку в git для обмеження повороту найкоротшим шляхом @ https://github.com/pgRouting/pgrouting/tree/trsp

Вибачте, поки що немає документації, але якщо ви задасте запитання у списку pgRouting, я завишу там і відповім. Цей код працює набагато швидше, ніж зіркова стрілка, і базується на алгоритмі Дікстра.

-Став


0

У мене є таблиця маршруту джерела, яка містить ~ 1200000 ребер. На моєму i7 із SSD потрібен 12 секунд, щоб створити маршрут. Моя ідея збільшити продуктивність - розділити краєву таблицю на кілька таблиць рівня масштабування. Я маю на увазі рівень, ідентичний плиткам Google. Наприклад, на 8-му рівні масштабування я маю 88 таблиць. Кожна таблиця містить підмножину доріг, і їх ділянки перекриваються одна з одною, щоб обчислити маршрут між двома точками, які розташовані не далеко за 290 км один від одного, займає 2 секунди. На 9-му рівні час обчислення падає до 0,25 сек і маємо 352 таблиці. Відтворення всіх графіків на випадок редагування доріг займає не більше години. Радикальним способом збільшення швидкості маршрутизації є використання алгоритму Floyd-Warshall. Але ніхто не знає, скільки потрібно для обчислення матриці попередника на стільки ребер.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.