Saya menggunakan pgrouting pada database postgis yang dibuat melalui osm2pgrouting. Ia bekerja sangat baik pada dataset terbatas (3.5k cara, semua jalur terpendek A * pencarian <20 ms).
Namun karena saya telah mengimpor kotak pembatas yang lebih besar (cara 122k) dari europe.osm kinerjanya turun banyak (biaya jalur terpendek sekitar 900 ms).
Saya akan berpikir bahwa menggunakan A * sebagian besar tepi tidak akan pernah dikunjungi karena mereka keluar dari jalan.
Apa yang telah saya lakukan sejauh ini dalam upaya meningkatkan kecepatan:
- Letakkan indeks pada kolom geometri (tidak ada efek yang terlihat)
- Meningkatkan memori saya dari 8GB menjadi 16GB
- Ubah pengaturan memori postgresql (shared_buffers, efektif_cache_size) dari (128MB, 128MB) menjadi (1GB, 2GB) (tidak ada efek yang terlihat)
Saya merasa bahwa sebagian besar pekerjaan sedang dilakukan di perpustakaan C Boost di mana grafik sedang dibuat sehingga mengoptimalkan postgresql tidak akan memberi saya hasil yang lebih baik. Saat saya melakukan perubahan kecil pada set baris, saya memilih A * untuk setiap pencarian. Saya agak takut bahwa boost library tidak dapat men-cache grafik saya dan harus membangun kembali semua tepi 122k setiap kali (walaupun itu hanya akan menggunakan yang sangat subset terbatas setiap kueri). Dan saya tidak tahu berapa banyak yang dihabiskan untuk melakukan itu dibandingkan dengan pencarian jalur terpendek yang sebenarnya.
Apakah ada di antara Anda yang menggunakan pgrouting pada 122k atau lebih banyak set data OSM? Kinerja apa yang harus saya harapkan? Pengaturan apa yang paling memengaruhi kinerja?
Jawaban:
Ketika dihadapkan dengan tugas-tugas seperti ini, tujuan utama Anda adalah bersikap rasional. Jangan mengubah params berdasarkan 'firasat'. Sementara usus tampaknya bekerja untuk Hollywood, itu tidak untuk kita yang hidup di dunia nyata. Yah, setidaknya bukan nyali saya ;-).
Anda harus:
menetapkan metrik yang dapat digunakan dan berulang (seperti waktu yang dibutuhkan oleh kueri pgrouting)
menyimpan hasil metrik dalam spreadsheet dan rata-rata hasilnya (buang yang terbaik dan terburuk). Ini akan memberi tahu Anda jika perubahan yang Anda lakukan mengarah ke arah yang benar
monitor server Anda menggunakan top dan vmstat (dengan asumsi Anda berada di * nix) ketika kueri sedang berjalan dan mencari pola yang signifikan: banyak io, cpu tinggi, swapping, dll. Jika cpu sedang menunggu i / o maka cobalah untuk meningkatkan kinerja disk (ini seharusnya mudah, lihat di bawah). Jika CPU 100% tanpa aktivitas disk yang signifikan, Anda harus menemukan cara untuk meningkatkan kueri (ini mungkin akan lebih sulit).
Demi kesederhanaan saya menganggap jaringan tidak memainkan peran penting di sini.
Meningkatkan kinerja basis data
Tingkatkan ke versi Postgres terbaru. Versi 9 jauh lebih baik daripada versi sebelumnya. Ini gratis sehingga Anda tidak punya alasan untuk tidak melakukannya.
Baca buku yang saya rekomendasikan di sini .
Anda benar-benar harus membacanya. Saya percaya bab-bab yang relevan untuk kasus ini adalah 5,6,10,11
Meningkatkan kinerja disk
Dapatkan drive SSD dan letakkan seluruh database di atasnya. Kinerja membaca kemungkinan besar akan empat kali lipat dan kinerja menulis juga harus meningkat secara radikal
tetapkan lebih banyak memori untuk postgres. Idealnya Anda harus dapat menetapkan memori yang cukup sehingga keseluruhan (atau bagian terpanas) dapat di-cache ke memori, tetapi tidak terlalu banyak sehingga terjadi pertukaran. Bertukar sangat buruk. Ini tercakup dalam buku yang dikutip pada paragraf sebelumnya
nonaktifkan atime pada semua disk (tambahkan opsi noatime ke fstab)
Meningkatkan kinerja permintaan
Gunakan alat yang dijelaskan dalam buku yang dikutip di atas untuk melacak permintaan Anda dan menemukan penghentian yang layak untuk dioptimalkan.
Memperbarui
Setelah komentar saya melihat kode sumber untuk prosedur tersimpan
https://github.com/pgRouting/pgrouting/blob/master/core/src/astar.c
dan tampaknya begitu permintaan telah disetel tidak ada banyak ruang untuk perbaikan karena algoritma berjalan sepenuhnya dalam memori (dan, sayangnya hanya pada satu cpu). Saya khawatir satu-satunya solusi Anda adalah menemukan algoritma yang lebih baik / lebih cepat atau yang dapat menjalankan multithreaded dan kemudian mengintegrasikannya dengan postgres baik dengan membuat perpustakaan seperti pgrouting atau menggunakan beberapa middleware untuk mengambil data (dan menyimpannya, mungkin) dan beri makan ke algoritma.
HTH
sumber
Saya hanya memiliki masalah yang sama dan akan bertanya di milis, jadi terima kasih untuk semua orang!
Saya menggunakan Shooting Star dengan sejuta setengah baris di tabel perutean. Diperlukan hampir sepuluh detik untuk menghitungnya. Dengan baris 20k dibutuhkan hampir tiga detik. Saya perlu Shooting Star karena saya perlu batasan belokan.
Berikut adalah beberapa ide yang saya coba terapkan:
Pada SQL di mana pgRouting mendapatkan cara, gunakan st_buffer sehingga tidak mendapatkan semua cara, tetapi hanya cara "terdekat":
pilih * dari shortest_path_shooting_star ('SELECT rout. * FROM routing rout, (pilih st_buffer (st_envelope (st_collect (geometry)), 4) sebagai geometri dari perutean di mana id =' || source_ || 'atau id =' || target | | ') e WHERE rout.geometry && e.geometry', sumber, target, benar, benar);
Ini meningkatkan kinerja, tetapi jika cara harus keluar buffer, itu dapat mengembalikan kesalahan "tidak ada jalan yang ditemukan", jadi ... buffer besar? beberapa panggilan meningkatkan buffer sampai menemukan jalan?
Seperti yang disarankan oleh dassouki, saya akan membuat cache beberapa rute "berguna" jadi jika jaraknya terlalu panjang, ia bisa melalui rute cepat ini dan hanya perlu menemukan jalan keluar-masuknya.
Tapi saya kira itu, jika masuk ke memori, itu tidak terlalu penting ... Bagaimanapun, harus mengujinya.
Tolong, terus posting jika Anda menemukan ide lain.
Juga, tahukah Anda jika ada beberapa pgRouting yang dikompilasi untuk Postgres9?
sumber
Kami baru saja membuat cabang di git untuk lintasan terpendek belokan terbatas @ https://github.com/pgRouting/pgrouting/tree/trsp
Maaf belum ada dokumentasi, tetapi jika Anda mengajukan pertanyaan pada daftar pgRouting, saya nongkrong di sana dan akan merespons. Kode ini berjalan jauh lebih cepat daripada bintang jatuh dan didasarkan pada algoritma Dijkstra.
-Steve
sumber
Saya memiliki tabel rute sumber yang berisi ~ 1200000 tepi. Pada i7 saya dengan SSD, dibutuhkan 12 detik untuk membuat rute. Ide saya untuk meningkatkan kinerja adalah membagi tabel tepi menjadi beberapa tabel level zoom. Maksud saya level yang identik dengan ubin google. Pada tingkat zoom 8, misalnya, saya memiliki 88 tabel. Setiap tabel berisi subset jalan dan area mereka saling tumpang tindih sehingga untuk menghitung rute antara dua titik yang terletak tidak jauh dari 290 km satu sama lain membutuhkan waktu 2 detik. Pada level 9 waktu perhitungan turun menjadi 0,25 detik dan kami memiliki 352 tabel. Rekreasi semua grafik jika kami mengedit jalan tidak lebih dari satu jam. Cara radikal untuk meningkatkan kecepatan perutean adalah dengan menggunakan algoritma Floyd-Warshall. Tapi tidak ada yang tahu berapa yang dibutuhkan untuk menghitung matriks pendahulu di banyak sisi.
sumber