Artikel ini merupakan kelanjutan dari seri Case Locomizer, lihat juga
Halo

Apakah Anda tahu apa itu post-mortem? Ini adalah kisah tentang bagaimana kita sampai pada kehidupan seperti itu.
Saya tidak yakin tentang Anda, tetapi saya sangat suka membaca cerita tentang proses pengembangan beberapa perangkat lunak tingkat tinggi yang sangat khusus. Kolega mungkin memiliki ide yang menarik untuk dikerjakan, dan selalu ingin tahu untuk mengikuti apa yang terjadi dengan program dari prototipe ke produk dewasa, yang melakukan beberapa keajaiban di bidang subjek yang tidak dikenal.
Selain itu, jika saya hanya membuang tautan ke repositori dengan perangkat lunak semacam itu, tidak mungkin ada orang yang bisa mendapatkan petunjuk tentang apa itu dan mengapa, dan untuk tugas apa itu bisa bermanfaat. Bahkan jika saya menerjemahkan dari bahasa Inggris tiga lusin halaman instruksi untuk memulai. Namun demikian, kerangka kerja
Spark bukan hanya kerajinan lain pada sudut, harus dipahami
bahwa penulis
merokok mengapa itu ditulis dengan cara ini dan bukan sebaliknya.
Artikel ini adalah pengantar historis untuk One Ring. Tidak ada kode di dalamnya, dan ceritanya lebih populer daripada ilmiah. Tetapi hanya tentang pengembangan, dan tentang tidak ada yang lain, kecuali untuk dua setengah tahun pembangunan.
Terakhir kali, saya berbicara dengan cukup detail (saya harap cukup) tentang kesulitan mengekstraksi data dari set data anonim di jalur tengah, dan pada akhirnya saya menyusul dengan intrik yang tidak lemah. Mari kita tinggalkan resolusinya untuk yang terakhir kalinya, dan hari ini kita akan berbicara tentang jalan panjang dan sulit menuju kesempurnaan alat utama kami:
- Data besar itu besar
- Kasus kami tidak standar
- Prototipe dalam C # dan PostGIS
- Pendekatan pertama ke Hadoop MapReduce
- Munculnya CI dan Spark
- Perkiraan ketiga di GeoSpark
- Analis Jepang dan migrasi dari Azure ke AWS
- Ash Nazg Durbatuluk, Ash Nazg Gimbatul, Ash Nazg Trakatuluk, Ag Burzum Ishi Krimpatul !!
- Optimalisasi dan geocatarsis dengan Uber H3
- Putih seluruhnya
Data besar itu besar
Data besar bukan tentang ukuran.
Mungkin ada puluhan, atau bahkan ratusan juta catatan dalam dataset bulanan di wilayah London Raya, tapi itu tidak banyak. Satu iterasi tunggal pada mereka dari awal hingga akhir bertumpu pada kecepatan membaca linear dari disk. Jika drive adalah SSD, itu akan memakan waktu beberapa detik.
(Saya ingatkan Anda bahwa dataset yang dimaksud adalah sekumpulan file CSV dengan sekumpulan bidang khusus untuk penyedia. Pengelompokan catatan dengan koordinat pengguna anonim ke dalam suatu file terjadi di sepanjang perbatasan wilayah administratif negara, prefektur, atau kota. File itu sendiri dihasilkan pada tanggal yang dipilih, harian atau
bulanan. Detail lebih lanjut semua
dijelaskan di bagian sebelumnya,
jalankan secara diagonal jika tidak ada konteks yang cukup.)
Proses kami multi-langkah. Heuristik pengayaan data mentah awal yang bekerja hanya dalam mode iterasi tunggal cepat, dan Anda dapat menulis setidaknya dalam Python, setidaknya dalam C ++, bahkan dalam PHP. Bahkan pada mesin yang lemah, pemrosesan akan cepat.
Jika dataset berada di suatu tempat di cloud, maka, asalkan pawang ditempatkan di cloud yang sama, tidak ada masalah khusus untuk mendapatkannya, pergi, dan simpan hasilnya di sebelahnya. Selain itu, biasanya file sudah ada di sana, karena penyedia data dengan senang hati akan mengunggah arsip ke penyimpanan cloud Anda sendiri, yang akan memberi Anda tautan unduhan. Tetap hanya untuk menggunakan mesin virtual, dan semua perpustakaan untuk mengakses repositori akan dengan hati-hati diletakkan oleh vendor di dalamnya, semua kunci akses terdaftar, cukup ambil API di tangan Anda dan gunakan. Ini akan cepat juga.
Nah, dengan langkah pertama, semuanya jelas. Mereka mengambil file, menjalankannya beberapa kali, mengembalikan versi yang sudah diproses. Tetapi apa yang terjadi jika langkah-langkah selanjutnya dari algoritma kami memerlukan beberapa set perhitungan yang sedikit lebih rumit untuk setiap record?
Ambil sesuatu seperti menentukan jarak antara sepasang koordinat. Ada metode
Haversine yang sangat cepat ("haversinuses" menurut versi aula), yang memberikan akurasi yang dapat diterima pada jarak pendek, dan memungkinkan untuk tidak mengambil
geo WGS84 , perhitungan yang bekerja jauh lebih lambat.
Dalam perhitungan itu sendiri, ternyata, tidak perlu biaya banyak jika itu tunggal. Dan bahkan jika ada puluhan juta dari mereka, ini, pada prinsipnya, tidak masuk akal.
Dan sekarang kami mengambil kasing dari algoritme yang kami patenkan, ketika kami perlu menghitung jarak dari setiap sinyal ke setiap POI dari kategori yang dipilih, dan membuang yang lebih dari setengah kilometer (jarak yang sedemikian mudah untuk dilalui).
Untuk wilayah London Raya, sekitar satu juta perusahaan termasuk ke dalam
POI yang ditargetkan dalam kategori toko dan outlet. Dan seperti yang saya katakan, dalam puluhan dataset bulanan, ratusan juta catatan datang untuknya. Dan jadi kita dapatkan ...
1.000.000 POI Γ N, 000.000 sinyal = N, 000.000.000.000 jarak.
Oh, ayolah. Gila triliunan perhitungan jarak dan perbandingan ambang batas konstan.
Situasi klasik dengan
produk Cartesian . Dua set yang tidak terlalu kuat secara individual dengan mudah memberikan hasil menengah N Γ 1012, dan ini hanya satu bulan di satu wilayah! Jumlah seperti itu sudah berubah menjadi kualitas. Tidak hanya ukuran hasil antara sudah merupakan masalah serius, karena tidak sepenuhnya masuk ke memori, dan perlu untuk segera memprosesnya di tempat penerimaan, tetapi jumlah perhitungan yang diperlukan untuk memperolehnya membutuhkan waktu komputer terlalu banyak. Dan jika untuk satu catatan, dengan mempertimbangkan semua keterlambatan dalam transmisi melalui jaringan, dan biaya overhead lainnya, hanya 100 nanodetik yang dihabiskan, maka jutaan detik adalah hitungan hari dan minggu dalam satu aliran.
Atau, jika kita perlu membuang segmen dari populasi umum, misalnya, kondisi "tidak memperhitungkan kepentingan pengguna yang tinggal di area tertentu", maka kita harus membandingkan device_id dari setiap catatan dari dataset yang diperkaya dari seluruh wilayah dengan satu set di mana ratusan ribu catatan dengan mengecualikan device_id penghuni area ini. Dan ini adalah perbandingan string dalam banyak hal, tidak secepat untuk dua int. Sekali lagi, ada semacam nol angka gila dalam mengevaluasi satu operasi sederhana, dan kami memilikinya untuk set heuristik lengkap untuk proyek rata-rata dengan selusin, atau bahkan lebih.
Big Data adalah data yang, karena ukurannya, membuatnya perlu menggunakan teknik algoritme khusus karena ketidaktepatan atau ketidakpraktisan pemrosesan secara langsung.
... bahkan jika hasil akhir perhitungan runtuh menjadi satu layar tabel Excel.
Anda dapat mencoba memparalelkan penangan βnaifβ dengan jumlah prosesor virtual yang tersedia pada mesin tempat kami menjalankan perhitungan. Anda dapat membagi dataset menjadi beberapa bagian dan menjalankan perhitungan rhinestones pada selusin mesin virtual di cloud. Tetapi semua ini tidak akan memberikan hasil yang sangat baik secara kualitatif. Penskalaan "lebar" memberikan
hasil yang menurun mulai dari lebar tertentu. Dan masalah sinkronisasi dan partisi pasti akan keluar, dan mengelola seluruh armada mesin virtual akan menghabiskan waktu dan uang. Menjaga mereka tetap menyala sepanjang waktu itu mahal, dan memulai dan menghentikan permintaan itu padat karya.
Oleh karena itu, untuk data besar, sistem perangkat lunak khusus dari ekosistem Hadoop, yang sudah memiliki kontrol skala, digunakan, serta seperangkat algoritma khusus yang memungkinkan mammoth untuk makan dalam porsi kecil tanpa risiko tersedak jumlah data menengah yang sangat besar, dan sangat menyederhanakan kehidupan pengembang data besar. Tetapi Anda tidak bisa mengambil dan mulai menggunakan Hadoop. Pertama, Anda perlu membuat rencana.
Apalagi jika ...
Kasus kami tidak standar
Jika Anda bertanya bagaimana kantor yang terlibat dalam analisis pada kumpulan data besar membangun proses mereka, ternyata dua pendekatan utama digunakan dalam praktik dunia.
Pendekatan nomor 1. Danau data
Untuk data yang terakumulasi dari waktu ke waktu dan tetap relevan selamanya, jenis penyimpanan khusus dirancang, yang disebut "
danau data ".
Arsitektur repositori tersebut dioptimalkan untuk akses acak cepat. Banyak kumpulan data yang dikumpulkan diterjemahkan ke dalam format khusus yang memungkinkan Anda untuk dengan cepat melakukan pemilihan multi-kriteria dan irisan dengan set kolom. Tidak seperti database relasional dan berorientasi dokumen tradisional, penyimpanan kolom digunakan dalam danau data. Biasanya mereka final, yaitu, format wadah dengan data sedemikian rupa sehingga setelah mengisi dan mengindeks, data dalam dataset yang sama tidak pernah berubah lagi. Misalnya, file parket yang tidak memerlukan modifikasi.
Setelah itu, kerumunan data -
Satanis atau
analis data bergegas masuk, dan dalam perangkat lunak khusus ("laptop" seperti Jupyter) mengumpulkan statistik, indikator, dll. online. Statistik ini diturunkan dari danau di suatu tempat di luar, atau hanya ditambahkan bersama dalam bentuk file akhir yang sama untuk agregasi berikutnya.
Pendekatan nomor 2. Streaming data
Untuk data yang tiba secara real time dan perlu diproses dengan cepat (mis., Streaming data), bus data, atau antrian pesan, dirancang.
Dalam infrastruktur dengan bus data ada generator di satu ujung, dan konsumen di ujung lainnya, dan aliran data sendiri terdiri dari peristiwa.
Generator dihasilkan, dan konsumen, dalam waktu nyata atau dekat waktu nyata, menganalisis peristiwa, mengumpulkan beberapa hasil akhir, yang lagi-lagi dapat menghasilkan peristiwa yang akan dikonsumsi oleh rangkaian agregator berikutnya melalui bus yang sama, dan seterusnya hingga hasil akhir diperoleh, dilipat dalam repositori hasil akhir.
Ini didorong oleh Apache Kafka dan penyimpanan cepat seperti Aerospike.
Kasus kami
Tetapi kasus kami tidak cocok dengan dua pendekatan ini.
Pertama, tidak masuk akal bagi kami untuk menyimpan data lake, karena dataset jarang bertahan lebih dari setahun (trek pengguna untuk 2016 pada tahun 2019 tidak lagi diperlukan oleh siapa pun), dan setiap kali pelanggan membutuhkan bagian yang benar-benar tidak dapat diprediksi dari semua data akumulasi. Juga, karena fakta bahwa untuk setiap segmen populasi dan kategori templat sendiri dibuat, kita masih dipaksa untuk mengambil hanya bagian yang diperlukan, dan menggabungkannya ke danau bersama tidak masuk akal. Lebih mudah menyimpan setiap dataset bulanan dalam bentuk aslinya - file CSV di direktori terpisahnya sendiri. Path ke file diperoleh ... / penyedia / negara / wilayah / subregion / tahun / bulan / file dataset, dan subset dipilih hanya dengan topeng nama file, misalnya, ... / Tamoco / UK / Greater_London / * / 2019 / {6, 7.8} / *. Csv.
Kedua, sifat dataset adalah diskrit, bukan streaming. Tentu saja, seseorang dapat, tentu saja, secara langsung menghitung beberapa indikator secara langsung dalam proses pengunggahan ke penyimpanan jaringan, tetapi peta panas yang sudah jadi untuk wilayah Moskow dan wilayah Moskow yang berdekatan tidak akan berkorelasi dengan peta panas yang sudah jadi dari gabungan wilayah Moskow dan Wilayah ( karena kenyataan bahwa terlalu banyak tinggal di wilayah tersebut dan bekerja di Moskow), dan kami masih belum tahu sebelumnya wilayah mana yang akan kami butuhkan. Mungkin bukan Moskow, atau Wilayah Moskow, tetapi hanya beberapa Kota 17. Sangat mahal untuk menggerakkan heuristik dan menghitung indikator untuk semua dataset.
Akibatnya, kita harus dengan cepat memilih subset dari kumpulan data yang terakumulasi, dengan cepat menyebarkan farm komputasi yang cocok untuk daya, dengan cepat melakukan proses perhitungan yang unik namun terstandarisasi, mengeluarkan hasilnya, dan ... mungkin tidak pernah lagi kembali ke subset atau ke farm dengan ukuran ini , bukan ke template. Dan kami benar-benar tidak dapat menyimpan cluster kinerja yang telah disesuaikan dengan perangkat keras kami sendiri, yang akan mencakup kebutuhan semua proyek kami dari yang terkecil hingga yang paling sulit, karena mereka terlalu berbeda.
Saya tidak berpikir kami sangat unik. Dalam percakapan dengan kolega, kebutuhan untuk instrumentasi kasus
meledak serupa muncul secara teratur, tetapi di sini semua orang membangun proses dengan caranya sendiri. Biasanya, solusi untuk kasus-kasus non-standar melekat pada konveyor yang ada dari pendekatan No. 1 atau No. 2 di samping; proses kami seluruhnya terdiri dari proyek-proyek swasta, kami memiliki semua tugas seperti "meledak".
Baik sekarang. Selama dua tahun dan satu sen, kami dapat menghasilkan kit alat untuk mengotomatisasi pekerjaan saya sebanyak mungkin, dan justru inilah yang akan saya sajikan untuk penggunaan umum di bagian ketiga dari cerita saya. Sementara itu, mari kita bicara tentang evolusi, dan semua kesalahan dan masalah itu, memperbaiki dan menyelesaikan yang telah kita alami pada proses yang berkelanjutan melalui pengalaman.
Prototipe dalam C # dan PostGIS
Semuanya dimulai beberapa tahun yang lalu. Dua pria yang sangat cerdas bernama
Alexei Polyakov dan Alexei Polyakov - jangan tertawa, mereka sebenarnya sama, tetapi dari berbagai belahan dunia - ahli biologi dan pemasar, mereka memutuskan untuk menerapkan metode dari disertasi tentang perilaku kolektif populasi sel dalam kultur sel, yang diuji secara eksperimental hingga tikus , untuk iklan dan pemasaran.
Ini berhasil pada orang.
Dan kemudian proyek Locomizer muncul. Saya mengatakan "proyek" karena ini seperti startup dengan
LLC untuk menyelesaikan kontrak, tetapi tidak cukup. Anggota tim kami tersebar di seluruh dunia, bekerja di berbagai tempat dan kantor sebagai freelancer atau agen outsourcing (dan tidak semua karyawan penuh waktu), dan kami menggunakan algoritme kami untuk pelanggan yang sangat berbeda dengan model interaksi yang berbeda saat kami menerima atau menemukan pesanan. Ada langganan, tetapi lebih banyak tugas pribadi satu kali.
Tapi itu sekarang. Dan beberapa tahun yang lalu segalanya menjadi lebih kacau. Siapa yang menulis implementasi perangkat lunak pertama untuk menghitung kecepatan, saya biasanya tidak tahu. (Jika Anda tiba-tiba mengenal para pahlawan yang tidak dikenal ini, menyapa mereka.) Di akhir
artikel terakhir saya tentang karier seorang programmer di kota tertentu, saya benar-benar menulis yang berikut ini: βSaya datang untuk berbicara ke tempat di mana saya bekerja sekarang, dan PM menyatakan langsung dari ambang pintu bahwa proyek ini adalah neraka. Tidak ada Sekali lagi, GIS, hanya perhitungan yang semuanya didasarkan pada MapReduce (dan saya menginginkannya pada Spark), peta di ArcGIS, dan semua ini berputar di awan yang tidak dapat dirancang oleh siapa pun. Menurut pendapat saya, pilihan yang bagus! β- pada saat itu sudah seperti itu, dan saya hanya dapat mengembalikan tahap pertama pengembangan proyek dalam kode dari ingatan
mitra_kun , yang muncul pada proyek hanya setahun sebelumnya.
Heuristik dasar untuk memproses dataset mentah ditulis dalam PHP, Python dan C ++, dan perhitungan utama kecepatan untuk peta panas dilakukan oleh sebuah program di C #.

Dia bekerja seperti ini:
- Pertama, kita langsung membaca string ke dalam array dari file dataset.
- Jalankan foreach'em, buat tabel hash di polzakz.
- Basis POI adalah tabel literal dalam database PostgreSQL dengan bidang PostGIS tipe GEOMETRI, dan untuk menghitung jarak antara setiap sinyal pengguna dan setiap POI, fungsi ST_DISTANCE ditarik melalui penyimpanan kecil, hasilnya ditambahkan ke tabel hash dengan kunci untuk setiap pengguna.
- Kemudian kami melakukan foreach di atas meja dengan akumulasi hasil skor bunga untuk setiap kunci dalam array.
- Sekali lagi, kelompokkan, untuk setiap kategori.
- Setelah akhir perhitungan, yang seluruhnya memakan waktu dari beberapa jam hingga satu minggu, hasilnya ditambahkan ke file CSV ...
- ... dan kemudian masih diproses secara manual, ditumpangkan pada peta, dan divisualisasikan di ArcGIS .
Jelas bahwa volume maksimum yang diproses dibatasi oleh memori yang tersedia pada mesin, dan kecepatan permintaan tunggal ke database menyebabkan beberapa alarm.
Pendekatan pertama ke Hadoop MapReduce
Sesuatu dihitung pada prototipe lokal, kesesuaian perawatan yang diterapkan untuk menyiapkan dataset dan membangun peta panas diuji, dan pertanyaan muncul tentang bagaimana membuat pekerjaan pada aliran. Nah, penting untuk tidak berurusan dengan matahari terbenam secara manual, tetapi untuk menggunakan kemampuan beberapa platform, lebih disukai ditulis oleh paus industri, dan untuk skala setidaknya ke minimum.
Seperti yang saya katakan, platform pemrosesan data besar standar adalah ekosistem Hadoop. Satu set besar pustaka heterogen, termasuk sistem file terdistribusi, penjadwalan untuk memparalelkan tugas, abstraksi yang relatif nyaman atas pengurangan peta, mesin untuk mengeksekusi query, dan bahkan sejumlah besar barang untuk analisis data. Dan semua infrastruktur perangkat lunak ini tersedia di cloud dari vendor yang berbeda dalam bentuk paket terintegrasi, dan itu akan otomatis, tetapi lebih lanjut tentang itu nanti.
Oke Google, cari Hadoop. Pendahulu saya mengambil prototipe, dan menulis ulang perhitungan utama dari C # ke Jawa, secara harfiah mengganti semua pendahuluan dengan Hadup Mapper dan Reducer yang sesuai, dan mengambil semua langkah untuk menyiapkan dan memperkaya kumpulan data ke dalam utilitas terpisah dalam bahasa scripting untuk berkembang lebih cepat, karena dengan munculnya berbagai algoritma pelanggan mulai berkembang secara aktif. Secara terpisah, kami mulai menulis backend untuk Web UI di Spring (bukan solusi terbaik, jika tidak ada pengalaman sebelumnya dalam pengembangan Java, akan lebih baik untuk menulis dalam PHP), dengan sebuah front di Node.js dengan integrasi peta dari ArcGIS.

Mereka mengangkat "kelompok besar" Hadoop pada lima mesin virtual di Microsoft Azure untuk kasus ini. Mengapa Azure Pertama, untuk startup ada diskon besar untuk beberapa tahun pertama. Kedua, ArcGIS Desktop untuk Windows untuk visualisasi peta sudah digunakan di cloud ini.
Cluster Hadoop dikerahkan secara manual, dan bukan dari layanan Azure HDInsight yang sesuai, yang sulit dikonfigurasi.
Pada masing-masing mesin cluster, mereka mengangkat Postgre + PostGIS (keputusan yang agak meragukan, karena MR dan pangkalan mulai bersaing untuk prosesor), sehingga tidak pergi untuk jarak ke server yang terpisah. Kami membuat skrip kecil yang menyebarkan replika database POI di seluruh node cluster.Proyek itu masih berupa prototipe, hanya sedikit lebih maju. PostGIS masih digunakan karena geofencing muncul, dan mereka belum tahu bagaimana cara menerapkannya dengan tenaga kerja minimal. Rasanya semuanya sangat lambat, dan jumlah langkah yang harus dilakukan secara manual melebihi selusin setengah.Pada saat itulah saya tertarik pada proposal dari sedikit-dikenal di kota IT kami yang kecil tapi sangat (di Izhevsk ada lebih dari tujuh lusin kantor dengan staf pengembangan, di mana sekitar tiga ribu programmer bekerja), sebuah kantor dengan nama yang benar-benar generik "Teknologi Informasi Rusia", yang Tiba-tiba, tanpa alasan, butuh Pengembang Java Senior dengan pengalaman luas dalam penerapan dan otomatisasi, dan setidaknya saya mendengar tentang Big Data dan awan dari bagian bawah telinga saya. Nah, pada saat saya mendengar sedikit tentang awan dan data besar.Mengenai hal-hal lain, saya memiliki pengalaman lebih dari cukup :( Oleh karena itu, hal pertama yang saya katakan ketika saya melihat kode dan keadaan prosesnya adalah dalam tradisi terbaik Artemy Lebedev, keras dan banyak. Saya tidak akan mengulanginya.Nah, jika kode dan proses memiliki kualitas yang dapat dimengerti, maka mereka pasti memiliki tempat untuk melakukan optimasi. Sebagai permulaan, Anda setidaknya dapat mengirim permintaan ke PostGIS satu per satu, tetapi dalam batch, sekitar 5.000 poin sekaligus. Database, sebagai aturan, dioptimalkan dengan baik untuk resolusi produk Cartesian. Dikatakan - selesai, penyimpanan dengan panggilan ST_DISTANCE ditulis ulang sedemikian rupa untuk segera mengembalikan array besar untuk paket poin, dan dari awal perhitungan dipercepat dengan segera sebanyak 40 kali, karena sekarang tidak perlu membuat koneksi ke database begitu sering, dan begitu banyak indeks pada geometri di meja dengan POI mulai bekerja dengan sangat masuk akal.Benar, kesalahan esoteris yang buruk merayap masuk ke dalam perhitungan, karena fakta bahwa prototipe tidak sepenuhnya benar porting dari C # ke Jawa. Orang-orang kehilangan titik satu variabel penting, dan TK formal pada prototipe tidak mencapai mereka sama sekali, hilang di suatu tempat di sepanjang jalan. Kemudian kami mengembalikan semua algoritma dari deskripsi yang terpisah-pisah, tetapi ini sudah sangat lama. Namun, kesalahan ini secara keseluruhan tidak merusak hasil perhitungan, itu hanya mengurangi kontras peta panas.Tetapi Anda tidak akan mendapatkan banyak kinerja dari MapReduce, karena mapper membaca data dari HDFS dan menulis kembali, dan peredam berikutnya dalam rantai melakukan hal yang sama, dan seterusnya hingga semua langkah selesai. Ini juga sangat tidak nyaman untuk mengelola proses multi-langkah, terutama jika algoritma memiliki cabang karena pengaturan. Seluruh algoritma adalah hardcode, dan jika Anda ingin mengatur ulang langkah-langkahnya, Anda harus memindahkannya ke modul terpisah dengan peluncur Anda sendiri, dan membungkus semacam logika di luar.Yah, menarik PostGIS dari dalam perhitungan, bahkan jika Anda menduplikasi database pada setiap node cluster, masih merupakan ide yang sangat menyakitkan.Munculnya CI dan Spark
- Otomatiskan itu! - saya besar kedua item yang menarik rofessionalny setelah enterprayznogo n rogrammirovaniya pada katak ... Dan tidak ada. Kedua - itu adalah n itstsa, n asta dan n udingi, maka biarlah ada ketiga - adalah n berhenti n Proses dan otomatisasi mereka. (Aku seperti shef- n Ovar seperti memiliki segalanya di p . Hashtag # n echenki.)Pekerjaan tangan membawa terlalu banyak bahaya. Orang tidak dapat diandalkan dan sering melakukan kesalahan, bahkan jika mereka melakukan hal yang sama, sehingga jauh lebih efisien untuk meluangkan waktu memformalkan keseluruhan alur proyek dan menulis skrip yang tidak akan gagal saat memanggil utilitas untuk menyalin dataset dari penyimpanan jangka panjang ke yang online, dan tidak akan mencampur urutan langkah-langkah, daripada terus berjalan menyapu.Rake walking adalah masalah paling serius yang harus diselesaikan terlebih dahulu. Pertama, saya ditempatkan di teamCity virtual kecil yang terpisah, dan mengonfigurasi perakitan dengan menjalankan semua tes sehingga artefak yang diperiksa selalu ada, dan tidak perlu dilemparkan ke kluster secara manual. Langkah kedua adalah menulis pembungkus untuk menjalankan satu tugas MR dengan dataset yang ditentukan dan set parameter pada cluster langsung dari TC yang sama, dengan menyalin otomatis yang sama dari dataset asli ke cluster dan hasil perhitungan di toko hasil.Dan langkah ketiga, yang menghabiskan banyak waktu karena kebiasaan, adalah mengotomatiskan penyebaran cluster itu sendiri, menyetel parameternya, dan memulai perhitungan pada dataset yang dibangun di Azure Blob Storage. Tiba-tiba saja ada proyek di mana sekelompok statis dari lima mesin virtual mulai dilewatkan dan / atau yang dataset tidak boleh dicampur dengan dump file lama pada HDFS.Azure HDInsight sebenarnyaHDP Hortonworks (tenang untuknya), dan beberapa pengaturannya dibuat dalam API, dan beberapa hanya dapat didaftarkan melalui Ambari. Menyebarkan sebuah cluster tergantung pada beban cloud dapat memakan waktu hingga satu jam, dan siklus tuning, yaitu, memeriksa efek dari set pengaturan pada kinerja kode kami, dapat memakan waktu satu hari penuh. Versi lokal HDP Sandbox di mesin virtual memakan 11 gigs RAM, dan sangat menuntut subsistem disk, sehingga bahkan debugging lokal sangat tidak menyenangkan, dan pengaturannya sedikit berbeda dari versi cloud. Saya membuat banyak waktu untuk percobaan, tetapi setidaknya saya menemukan cara kerjanya, dan apa yang harus dilakukan jika perhitungan tiba-tiba hang di tengah dengan OOM berikutnya, karena juga tidak menyenangkan untuk mengurai log secara manual.Ketika saya berurusan dengan HDP, programmer lain mulai menyatukan tahapan yang berbeda dalam menyiapkan dataset di Apache Spark. Spark memecahkan masalah terus-menerus menulis / membaca data antara yang terjadi antara langkah-langkah satu perhitungan, dan secara umum, ini dirancang dengan mempertimbangkan semua tempat buruk MR, dan dapat melakukannya berkali-kali di luar kotak. Dan RDD yang malas di Spark adalah hal yang sangat berguna.Pada saat yang sama, saya menulis Azure Templates di PowerShell untuk mengkonfigurasi node edge untuk PostGIS - contoh terpisah berhidung tebal di cluster, dengan sekelompok core dan memori untuk mempercepat permintaan, serta menjalankan langkah-langkah awal untuk menyiapkan dataset, yang pertama kali diletakkan pada disk lokalnya, dan kemudian dimuat ke HDFS di cluster.Jadi penjilidan skrip, yang semula dianggap bekerja secara interaktif dan dalam mode batch pada TC sebagai build terpisah, secara bertahap belajar menjalankan kombinasi langkah-langkah sewenang-wenang pada MR, Spark, dan paket perangkat lunak lain yang tidak kami gunakan dari HDInsight suite, tetapi masih dengan parameterisasi belum sempurna. Namun, mentransfer parameter build ke repositori tetangga dengan satu set file .ini (untuk setiap komponen platform dan untuk setiap langkah proses), dan mempertahankan templat proses di cabang repositori ini ternyata merupakan praktik yang nyaman sehingga kami masih menggunakannya.Sudah maju. Dengan otomatisasi rutin manual, waktu persiapan untuk perhitungan berkurang empat kali, belum lagi kesalahan manusia, yang menjadi jauh lebih sedikit. Tapi itu belum waktu perhitungan itu sendiri.Perkiraan ketiga di GeoSpark
Butuh sekitar enam bulan. Pada saat ini, serangkaian heuristik yang telah di-debug dan teruji telah berakumulasi secara bertahap, sudah dengan aplikasi terpisah pada Spark, dan tidak dengan skrip apa pun, dan beberapa templat proses khas dikembangkan. Sekarang perlu mengoptimalkannya.
Programmer kedua, yang tidak memiliki pengalaman sebelumnya dalam tim atau perusahaan, bertindak dengan modulnya cukup mudah - setelah menyelesaikan transfer satu heuristik ke Spark, ia hanya menyalin seluruh proyek, dan mulai mengganti algoritma lama dengan yang baru di dalamnya. Akibatnya, ketika ada delapan modul paralel tersebut, masing-masing dengan parameter yang serupa tetapi sedikit berbeda, sedikit semantik panggilan yang sangat baik - dan juga banyak kode layanan duplikat - mereka mulai menimbulkan masalah lain. Semakin banyak kode, semakin banyak waktu yang dihabiskan untuk dukungannya, terutama jika tidak berhenti berkembang selama ini. Dan karena copy-paste yang konstan, parameter yang tidak digunakan dan sampah lainnya mulai menumpuk di dalamnya.
Setelah selesai dengan masalah pembakaran otomatisasi dan telah berurusan dengan konfigurasi cluster, sekarang saya sudah bisa mengambil modul persiapan data dan heuristik. Untuk memulainya, saya mengambil semua kode berulang ke dalam proyek Commons terpisah, dicolokkan sebagai
submodule git , dan dalam modul perhitungan menjadi beberapa kali lebih sedikit berantakan. Saya menyusun templat untuk heuristik tipikal, dan sebuah proyek baru sudah datang darinya, tanpa perlu mengganti potongan kode dan tanpa kotoran yang tidak perlu dalam sejarah komit. Pembangunan mulai lebih cepat.
Masalah besar berikutnya yang harus dikalahkan datang dari logika menghitung produk Γ sinyal POI Cartesian.
Hanya pemrosesan batch yang mentransfernya ke database, tetapi tidak mengurangi jumlah operasi, bahkan jika database secara efektif menggunakan indeks dan optimasi kueri. Adalah logis untuk tidak mempertimbangkan jarak untuk pasangan-pasangan di mana itu jelas melebihi ambang yang kita butuhkan. Tetapi bagaimana cara membuang pasangan dengan jarak lebih besar dari ambang tanpa menghitung jarak ini?
Jawaban:
mempartisi sinyal dan POI pada kisi geometris.
Apalagi peta panasnya sudah terdiri dari kisi-kisi poligon. Dan jika Anda memilih ukuran sel dari kisi ini dengan cara yang benar, maka untuk setiap POI dari poligon yang dipilih, sangat mungkin untuk membatasi diri untuk menghitung jarak ke sinyal yang masuk ke dalam poligon yang sama, sel-sel tetangganya, dan itu saja. Sisanya dapat dibuang, mereka pasti akan jatuh di luar batas relevansi.
Spark sudah memiliki alat yang siap pakai untuk bekerja dengan kisi -
GeoSpark . Programmer kedua mulai menggunakannya, dan operasi awal "menarik dataset ke grid" muncul. Tapi itu tidak menjadi jauh lebih baik, satu masalah serius diganti dengan masalah serius lainnya.
Sekarang ini adalah masalah "ekor panjang" - pengguna, di mana jumlah sinyal dalam jutaan. Tidak banyak dari mereka, tetapi jika mereka terakumulasi di pusat kota, di mana POI tinggi, dan mereka terakumulasi di sana, sebagaimana keberuntungan akan memilikinya, maka tidak masalah bagaimana Anda mempartisi dalam geometri (setidaknya
Voronoi , setidaknya
quadtree ), masih akan ada poligon di mana jumlah perbandingan melebihi jumlah yang wajar. Tapi Anda juga perlu memeriksa poligon tetangga di mana kepadatannya setinggi.
Dan jika 99% partisi dengan poligon saturasi rendah bekerja dengan cepat, maka 1% stasiun kerja Spark dengan sel kepadatan tinggi terus menggantung ke kemenangan, memakan memori seolah-olah tidak sadar, dan merusak semua raspberry. Spark sedang mencoba untuk mengingat semuanya, dan jika ada variasi yang kuat dalam ukuran partisi di RDD, maka seluruh penyetelan untuk konsumsi memori terbang sia-sia, karena itu harus dilakukan untuk yang terbesar.
Ternyata 99% perhitungan dipercepat dengan partisi geometris ratusan kali, dan 1% dari buntut panjang mengurangi seluruh pengoptimalan menjadi hampir tidak ada.
Secara umum, transisi ke GeoSpark menghasilkan keuntungan lima kali lipat, tetapi hanya pada ukuran eksekutor yang sangat tidak efisien memori, dan, karenanya, cluster dengan mesin virtual yang mahal. Singkatnya, partisi geometris untuk geodata kepadatan tinggi ternyata buntu.
Dan kemudian ada kebahagiaan dalam diri orang dari meja analitis dari salah satu telekomunikasi Jepang terbesar. Bisnis anak perusahaan kecil berdasarkan data geolokasi yang dikumpulkan oleh perusahaan utama.
Analis Jepang dan migrasi dari Azure ke AWS
Orang Jepang memiliki mental yang menarik. Mereka sendiri tidak terburu-buru, tetapi jika hanya gaijin diberikan untuk menggigit jari mereka, kedua tangan dipotong. Jangan pernah berikan tanggal spesifik Jepang! Dan jika Anda menelepon, maka ambil setidaknya tiga kali penawaran. Akan sangat panjang dan sulit untuk mengoordinasikan kerangka acuan, dan tidak hanya ketelitian Jepang yang terkenal akan ikut campur, tetapi juga perbedaan dalam berpikir. Mungkin tidak ada waktu tersisa untuk mengimplementasikan versi final TOR.
Proyek untuk berintegrasi dengan "putri" telekomunikasi Jepang hampir membunuh proyek kami. Prospek bersinar untuk menjadi penyedia data eksklusif untuk pasar iklan Jepang yang gila, dan bisnisnya sedikit ... eh, saya bisa melakukannya tanpa komentar.
Pertama, bukan Azure. Hanya AWS, hanya hardcore.
Kedua, bagian depan harus dimodifikasi untuk memenuhi kebutuhan mereka, yang terus berubah sepanjang proyek. Pemasar dari kantor ini terus-menerus menginginkan sesuatu yang mereka sendiri tidak tahu persis, dan tidak dapat benar-benar mengartikulasikan, dan itu harus diulang sepuluh kali per tahap, mengubah logika perhitungan untuk indikator baru berikutnya dengan cepat.

Pada titik tertentu, saya sedikit panik, dan membuat satu set "operasi dasar" - sekitar 15 tindakan primitif pada RDD dengan memanggil metode dasar seperti bergabung, memetakan, meletakkan nilai default, menjumlahkan nilai kolom - dan operasi kecil lainnya - dengan cepat mengubah logika rantai perhitungan, seolah-olah itu adalah seperangkat pernyataan SQL.
(Regular Spark SQL tidak dapat diterapkan dalam kasus kami karena fakta bahwa tidak ada pengetikan yang ketat atau sekumpulan bidang yang ketat. Dalam dataset, setiap saat Anda dapat menambahkan sebanyak mungkin bidang tambahan yang Anda inginkan, dan itu berubah selama aliran proses Terlalu sulit untuk meresepkan metadata dalam kondisi yang terus berubah.)
Tugas tingkat tinggi adalah ini: untuk memilih wilayah sewenang-wenang Jepang, dan membangun peta panas untuk jangka waktu sewenang-wenang menggunakan seperangkat kategori sewenang-wenang dengan tumpukan indikator untuk tempat pembuangan sampah. Indikator seperti apa, bagaimana cara menghitungnya - pelanggan sendiri tidak benar-benar memahami hal ini.
Dataset uji (yaitu, kecil) dengan sinyal pengguna untuk 2016-2017, di mana kami harus mengerjakan teknologinya, adalah data 5 terabyte, 14.000.000.000 catatan. Di Tokyo saja, ada beberapa juta POI, dan di grid di wilayah Hokkaido, 1.600.000 sel.
Dan kartu untuk semua dua ribu kategori untuk masing-masing dari 47 kesempurnaan Jepang harus dianggap "on the fly", karena itu harus dijual sebagai layanan cloud.
Tugas hebat untuk mematahkan otak. Di suatu tempat tiga atau empat urutan besarnya lebih tinggi dari kemampuan kami saat itu dalam hal "kecepatan perhitungan" dan "volume data".
Setelah menjadi sedih, kami memutuskan untuk tetap melakukan pra-perhitungan untuk setiap wilayah (terima kasih kepada para dewa Shinto, Jepang tidak perlu menyatukan daerah) dan sebulan sehingga peta panas itu dibangun sesuai dengan skor yang disiapkan sebelumnya. Biarkan tidak dalam waktu nyata, tetapi beberapa menit atau puluhan menit (untuk pusat Tokyo). Pra-perhitungan memakan waktu beberapa bulan dengan kelompok 25 mesin virtual paling kuat yang tersedia di wilayah Tokyo AWS.
Tetapi untuk menjalankan di AWS, Anda harus menulis ulang otomasi di bawah AWS API. Dan cloud yang berbeda, meskipun mereka menawarkan layanan yang serupa secara lahiriah, secara internal sama sekali berbeda. Sangat bagus bahwa pada saat ini PowerShell telah mencapai kandidat rilis versi 6, dan skrip pengikat Azur untuk menggunakan cluster dan menjalankan kalkulasi dapat diangkut dan dijalankan dengan berani di Linux TeamCity (karena menggunakan server pada Windows di AWS adalah sebuah ide. ) Lebih tepatnya, jangan porting, tetapi buka skrip yang ada pada satu monitor, dan tulis implementasi paralel untuk cloud lain di kedua.
Juga, AWS jauh lebih tua, dan karena itu lebih kuno daripada Azure, adalah arsitektur, dan ada lebih banyak pekerjaan manual untuk mengkonfigurasi tingkat infrastruktur yang lebih rendah. Dan lelang lokal untuk penjualan sumber daya komputasi menambah sakit kepala ketika Anda mungkin tidak memiliki mobil ukuran yang tepat dengan harga yang diinginkan, dan pelanggan tidak mengalokasikan anggaran untuk perhitungan harga penuh.
Tetapi ekosistem Hadoop itu sendiri dalam inkarnasi Amazon - EMR - adalah sesuatu yang lebih dekat dengan vanila, dan bekerja dengannya lebih mudah daripada dengan HDInsight. Ya, setidaknya dengan sesuatu ternyata lebih mudah.
Tapi tidak dengan S3. Di sini masalah keluar dari tempat mereka tidak menunggu. S3 memiliki batas tidak berdokumen. Misalnya, dalam satu ember tidak boleh ada lebih dari ~ 11.000.000 objek, karena di suatu tempat di dalam perut API mereka melakukan penyortiran kunci dalam urutan leksikografis untuk setiap (setiap!) Permintaan, dan buffer yang dialokasikan untuk itu tidak memungkinkan penyortiran lebih banyak garis, terutama jika panjang. Untuk mempercepat perhitungan, kami tidak menggabungkan partisi di akhir, dan di beberapa titik kami berlari ke batas ini, setelah itu proses berhenti begitu saja.
Menurut pikiran, penggabungan harus dilakukan, dan bahkan ada alat - utilitas s3-dist-cp, tetapi penggunaannya adalah sakit kepala yang terpisah. Predator untuk alien menulis utilitas itu pasti, berperilaku sangat berlawanan dengan intuisi. Dan itu memiliki kesalahan fatal - di bawah file gabungan Anda membutuhkan ruang lebih banyak pada HDFS karena semua yang asli ambil. Dan untuk menggabungkan puluhan ribu file partisi dari ratusan byte hingga puluhan megabyte dalam ukuran, tersebar di sekelompok 25 mesin, itu akan bertahan lama.
Namun, sudah dengan sejuta objek di ember, S3 mulai diam-diam berlari permintaan untuk itu. Dan dalam kondisi konsistensi akhirnya ini umumnya merupakan bencana - Spark, tanpa menunggu meja depan berapa kali yang disepakati, dapat jatuh. Ada solusi - gunakan EMRFS milik Amazon add-on, tetapi berfungsi di atas DynamoDB, dan ini adalah hal yang sangat mahal. Dan dengan batasannya sendiri pada jumlah permintaan per detik.
Singkatnya, dalam kondisi total waktu yang kurang, kami memutuskan untuk kembali ke skema statis - menggunakan cluster permanen pada contoh ukuran yang agak kecil (meskipun mahal, tetapi lebih murah daripada DynamoDB), menggabungkan semua terabyte dari dataset asli dan yang dihitung ke dalam HDFS di dalamnya, dan membaca kartu secara lokal.
Tapi twist plot berikutnya adalah permintaan Jepang untuk beralih dari grid heksagonal yang dihasilkan ke
Jepang Mesh - metode standar untuk partisi geografis dengan sel persegi yang hanya bergantung pada koordinat titik. Suatu hal yang sangat baik, karena memungkinkan Anda untuk meninggalkan langkah berat "menarik sinyal ke grid".
Kerugiannya adalah bahwa jaring Mesh Jepang hanya berlaku untuk Jepang dan wilayah kepulauan yang secara historis diklaim, tetapi tidak untuk seluruh dunia. Tapi setidaknya bagi orang Jepang menjadi mungkin untuk meninggalkan GeoSpark lambat, dan mempartisi sinyal secara merata tanpa mengacu pada geometri eksternal. Dan dengan kepergian "long tail", perhitungan segera dipercepat sekali lagi pada 10.
Sangat disayangkan bahwa ini terjadi setelah kita semua menemukan segi enam, menghabiskan banyak uang dan waktu dengan sia-sia. Cluster dengan terabyte kumpulan data yang telah disiapkan harus dibuang begitu saja.
Dan bagaimanapun, di suatu tempat di tengah pekerjaan, Jepang masih meminta untuk mentransfer seluruh infrastruktur dari satu akun AWS ke yang lain. Dan seolah-olah tidak peduli dengan semua pekerjaan yang dilakukan pada pengaturan. Yah, saya berhasil skrip ke template CloudFormation pada saat transisi, sehingga migrasi berjalan lebih atau kurang lancar.
Sebagai ceri terakhir pada kue, Jepang akhirnya memutuskan bahwa bagian depan tidak menyerah kepada mereka, dan mereka akan menarik perhitungan secara manual atas permintaan pelanggan mereka, jadi terima kasih kepada kami untuk algoritme (untuk pertama kalinya kami mendokumentasikan semuanya secara rinci - dan menemukan beberapa kesalahan), dan untuk saat ini. Baiklah ... semoga sukses dan sampai jumpa lagi.
Brrr Saya ingat proyek ini dengan ngeri dan gemetar.
Ash Nazg Durbatuluk, Ash Nazg Gimbatul, Ash Nazg Trakatuluk, Ag Burzum Ishi Krimpatul !!
Namun dari sisi positifnya, selain mendokumentasikan semua algoritma, ada juga perbaikan umum.
Kami belajar seorang siswa di Java Junior, dan ia melakukan studi terhadap sekelompok perpustakaan geografis, dan akhirnya ia berhasil memilih yang tepat dan membuangnya dari lingkungan PostGIS.
Upaya sebelumnya tidak berhasil karena akurasi yang buruk. Pada radius tiga kilometer, Haversin memberikan kesalahan yang sudah terlihat bagi kami, dan sebagian besar perpustakaan yang kami coba ambil dari awal sangat buruk di garis lintang utara St. Petersburg, akibatnya lubang atau tumpang tindih ganda muncul di grid. Dan kami orang Finlandia adalah pelanggan yang sering, jadi sangat penting bahwa semuanya bekerja dengan benar di garis lintang mereka.
Sampai kami menemukan bahwa kami membutuhkan lib dengan geoid normal (lebih disukai sama dengan di PostGIS, WGS84), hasilnya tidak sesuai dengan hasil yang diharapkan. Tetapi setelah beralih ke GeographicLib, hambatan dalam bentuk koneksi Postgre dihilangkan, dan tahap akhir dari menghitung kecepatan dipercepat 40 kali. Golovnyak pergi dengan konfigurasi tambahan instance RDS terpisah di bawah pangkalan dan mengunggah dump dengan POI ke dalamnya, yang pindah ke kumpulan data biasa dalam S3. Penyatuan!
Pada saat yang sama, siswa yang sama menggali dan memperbaiki kesalahan yang menyebabkan kartu tampak lebih pucat daripada yang sebenarnya. Nah, ketika ada tugas tanpa batas waktu, saya iri pada siswa.
Poin penting lainnya. Suatu kali, untuk yang kesekian kalinya, melihat skrip yang mengikat yang memanggil modul Spark satu demi satu, pikirku, tapi iblis macam apa yang kita hubungkan dengannya?
Mengapa menyimpan hasil antara setiap kali dalam S3 atau HDFS, jika RDD akhir dari modul sebelumnya hanya dapat diarahkan ke input berikutnya dalam rantai. Tidak lama setelah selesai, MetaRunner ditulis dalam beberapa jam. Kehadiran commons banyak membantu dalam hal ini, modul cukup standar pada saat itu, terutama karena parameter masing-masing modul sudah dalam tugas yang sama. Ini, dengan awalan kunci yang sesuai dengan nama mereka.
Perhatian Anda disajikan dengan diagram blok peta (langkah terakhir sebelum mengeluarkan ke depan, tetapi bukan versi final), yang ditulis pada operasi dasar:

Jika Anda menyingkirkan 24 panggilan perantara ke HDFS, khususnya perhitungan ini dipercepat sekitar 50 kali.
Tetapi bagaimana jika Anda menambahkan dukungan variabel ke templat proses sehingga Anda tidak perlu membuat ulang tugas. Apakah ini setiap kali Anda mengubah parameter di Toko Properti?
- Ash Nazg! Aku berteriak. Kolega saling memandang dengan bingung. Seorang pria memiliki atap karena orang-orang Jepang ini, tetapi oh well, itu terjadi.
"Ash nazg ... burzum-ishi krimpatul," aku menggeram menggeram (tidak berhasil dengan baik), dan pergi ke PM untuk membahas penggabungan semua 15 (jumlah heuristik dan utilitas tambahan secara bertahap bertambah) dari modul perhitungan menjadi satu repositori.
Jika kita melakukan hubungan pendek modul dengan satu sama lain, maka jangan bekerja keras lagi dengan lapisan semua JAR individu di jalan kelas percikan, dan biarkan seluruh paket logika Locomizer yang dipatenkan (dan operasi bantu kami) dirakit menjadi satu JAR gemuk. Pada saat yang sama dan secara lokal sekarang mungkin untuk dijalankan, tanpa sebuah cluster. Dan yang penting, logika untuk parsing task.ini dapat ditransfer dari binding PowerShell ke kode Java, di mana substitusi variabel jauh lebih sederhana.
Rekan kerja meringkuk di proposal untuk menyebut proyek itu "Cincin Mahakuasa", - Satu Cincin - tetapi sedikit kesengsaraan yang sehat tidak akan pernah sakit.
Setelah memanfaatkan momen putaran berikutnya koordinasi TK tanpa akhir di bagian depan, saya mengumpulkan semua modul dalam tumpukan. Maven adalah alat canggih untuk menyelesaikan dependensi dalam proyek multi-modul, sehingga dimungkinkan untuk membersihkan potongan terakhir dari kode duplikat, menyatukan versi semua perpustakaan, dan membuat opsi build untuk lingkungan lokal dan cloud. Selain itu, setiap modul tetap berada di dalam sub proyeknya masing-masing, dan penulisnya dapat mengerjakannya dengan cukup independen, tanpa mengganggu sisanya.
Ngomong-ngomong, saya menganggap pendekatan semacam itu dengan kristalisasi abstraksi dan konstruksi beberapa arsitektur dari set entitas homogen yang ada lebih tepat daripada upaya merancang level abstrak terlebih dahulu dan mengimplementasikannya dalam tugas-tugas tertentu. Tanpa praktik dan pola penggunaan yang mapan, tidak ada gunanya merancang arsitektur - semua kasing tidak dapat diramalkan sebelumnya, dan opsi untuk perilaku pengguna sistem dapat berbeda secara radikal dari gagasan perancang.
Dengan logika terpadu pemrosesan parameter, dimungkinkan untuk membuat model objek terpadu yang berbeda untuk konfigurasi modul, dan untuk melakukan pemeriksaan normal pada validitas dan konsistensi konfigurasi modul dengan satu sama lain dalam proses yang sama.
Ini sangat penting dengan dataset dalam format CSV - kontrol jumlah dan urutan bidang dalam setiap catatan RDD, serta kebenaran transfer data itu sendiri dari output satu modul ke input beberapa modul berikutnya, sepenuhnya berada di sisi panggilan. Dan jika ada satu titik kontrol, maka itu sudah bisa dilakukan dengan baik.Mengapa kita tidak naik dan bekerja dengan RDD dan bukan frame data? Untuk alasan yang sama kami tidak menggunakan Spark SQL. Tetapi selain itu, implementasi pada Spark adalah tahap akhir, akhir dari kode, yang dimulai dengan kertas putih, sepenuhnya debugged dengan Python, dan baru kemudian dioptimalkan dalam beberapa langkah ke versi yang paling produktif. Dan semakin dekat ke primitif perpustakaan dasar, semakin cepat kode berjalan.
... jika tangan pengembang keluar dari pundaknya dan kepalanya cerah. Secara teoritis.Ternyata dalam kondisi kami, jauh lebih mudah untuk mengarahkan garis CSV asli dalam bentuk Teks asli Hadoup kompak (di bawah tenda itu hanya sebuah array byte), dan hanya menggambarkan kolom-kolom yang diketahui operasi saat ini, dan hanya untuk itu. Juga, menurut hasil percobaan, frame data memberikan overhead yang lebih besar untuk konsumsi memori daripada kebutuhan untuk mengurai CSV pada input dari setiap operasi, dan kompres kembali ke Teks pada output. Baik dan baik - penting bagi kami untuk menjaga kemampuan untuk mempartisi RDD perantara setelah setiap langkah, karena kumpulan data baru dari toko dapat bercampur dengannya (ini terlihat jelas dalam diagram), jadi Anda harus turun satu tingkat, tidak peduli bagaimana Anda ingin tetap berada di level tersebut kertas putih logika.Tetapi dalam kode "tingkat rendah" di Jawa, ada plus juga. Misalnya, jika Anda menggambarkan parameter operasi (serta RDD yang diharapkan dan dihasilkan) dalam metadata, Anda dapat secara otomatis menghasilkan dokumentasi dan contoh konfigurasi untuknya, dan jangan menulisnya lagi secara manual. Dan dermaga akan selalu relevan, setelah setiap pembangunan.File konfigurasi task.ini sendiri, dari sekumpulan parameter heterogen untuk setiap modul, segera berubah menjadi program dalam semacam bahasa pemrograman deklaratif. Tidak terlalu cantik, tetapi secara internal logis dan relatif dapat dibaca manusia. Menyelesaikannya hingga DSL nyata dengan sintaksnya sendiri bukan masalah, tapi saya tidak melakukannya sebagai tidak perlu. Namun sedikit kemudian ia menambahkan pandangan ke JSON untuk front depan dengan editor visual.Proses hubung singkat, rata-rata, menerima tiga hingga lima kali lebih cepat daripada rantai panggilan individu ke pekerjaan Spark.Tidak seratus kali, karena sekarang, dalam kerangka kerja Spark yang sama, langkah-langkah tugas dengan kompleksitas komputasi yang berbeda dan saturasi data dapat dicampur. Akibatnya, penyetelan tipis parameter cluster untuk setiap bagian dari proses multi-langkah telah kehilangan makna praktis. Tetapi secara bertahap, dan untuk opsi ini, beberapa pola umum ditemukan yang memungkinkan untuk memilih preset ukuran cluster, hanya berdasarkan pada ukuran dataset awal dan jumlah langkah dalam templat proses pemrosesan.Untuk meringkas tahap ini, pada akhir pekerjaan kami dengan Jepang, kami telah memiliki alat yang cukup berkembang:- , ,
- , , DSL ,
- , β ,
- AWS, .
Tapi yang tidak berhasil adalah bagian depannya. Locomizer Web UI yang lama sudah usang, kami tidak pernah berhasil menyelesaikan bahasa Jepang yang baru sebelum mereka benar-benar meninggalkannya. Ya, dan kode backend UI ini sendiri, ditulis dengan kaki kiri saya pada malam Oktober yang gelap, saya tidak bisa menyisir sampai akhir hanya karena volume yang besar.Optimalisasi dan geocatarsis dengan Uber H3
Setelah menghembuskan napas, kami kembali ke proyek-proyek swasta. Suasana setelah orang Jepang itu, terus terang, seluruh tim sangat-begitu-begitu.Tapi saya akhirnya menyingkirkan kebutuhan untuk mempertahankan cadangan di bagian depan dengan Bogomersssky, holm, holm, spring. (Ini adalah pendapat pribadi saya. EE, saya tidak suka sedikit saja, karena memiliki autogi yang lebih sedikit dan default yang tersirat; jadi tidak masalah apa pun yang harus dilakukan oleh perusahaan yang mengerikan untuk menulis REST).Ada waktu untuk melihat ke dalam setiap modul dengan kecanduan.β , . , , , . - . β . , β .
Bukan berarti saya akan melihat kode rekan-rekan saya tanpa perhatian. Hanya setiap orang terlibat dalam tugas yang diberikan kepadanya, dan sementara itu dilakukan olehnya dengan hasil yang diinginkan, jangan mengganggu pengembang melakukan pekerjaannya. Jika algoritme berfungsi dengan benar, dan ini dikonfirmasi oleh tes, maka semuanya baik-baik saja. Menurut kecepatan kerja, - itu dapat diterima, atau sebaliknya, - keputusan dibuat oleh PM.Saya tidak melakukan intervensi sampai saya mengenali risiko tinggi untuk dukungan lebih lanjut dalam keputusan yang dibuat oleh pengembang saat mengimplementasikan tugas baru. Dan modul-modul lama dan jelek, yang ditulis di bawah Tsar Gorokh oleh seseorang yang telah lama meninggalkan proyek, tetapi perlu untuk bisnis, akan dipertahankan pada tingkat yang bisa diterapkan sebagaimana adanya, dan tidak peduli seberapa baunya dari mereka. Kedengarannya sinis, tapi saya seorang pragmatis, bukan idealis, hasil pekerjaan lebih penting bagi saya daripada keindahan kode.Tetapi kadang-kadang perlu untuk menghapus utang teknis sehingga ia tidak mengubur proyek di bawah beratnya sendiri.Spark adalah perpustakaan tingkat yang sangat tinggi. Ini memungkinkan Anda untuk melakukan operasi pada RDD dalam berbagai cara sinonim, yang memberikan hasil yang sama, dan setiap metode dapat memiliki beberapa bagian dari beberapa opsi yang sangat baik. Anda harus hati-hati membaca deskripsi masing-masing, dan jika ragu naik ke sumber untuk memahami mana yang optimal dalam hal ini. Hasilnya akan sama, tetapi perbedaan dalam kecepatan perhitungannya bisa beberapa kali, dan jika logika beberapa heuristik membuka seratus baris kode pada Spark, maka Anda harus sangat berhati-hati menggunakan cara yang paling tepat untuk mengubah data.Bahasa tingkat tinggi - bahasa-bahasa itu sedemikian rupa sehingga membuat Anda berpikir secara abstrak.Tetapi pada saat yang sama, pengembang harus menyadari level rendah, tidak peduli berapa banyak ia melambung ke abstraksi tinggi. Sebagai contoh, bahwa setiap lambda yang dilewatkan ke metode .map (), di mana memori dialokasikan untuk beberapa objek tebal, dipanggil lagi untuk setiap record dan realokasi objek yang sama, dan tidak ada JVM yang ada suka alokasi ulang yang tebal.Dan jika Anda berpikir tentang dukungan kode, alangkah baiknya untuk memiliki potongan-potongan algoritma yang dihubungkan oleh logika internal, tetapi pada saat yang sama sepenuhnya terisolasi dengan beberapa nilai parameter, mengisolasi dari sisa kode, terutama jika potongan-potongan ini berada di awal atau akhir algoritma. Mereka umumnya dapat dikeluarkan dalam operasi terpisah, pada saat yang sama tes dengan cakupan penuh dari semua kasus akan menjadi lebih pendek.Dulu terlalu dini untuk berurusan dengan optimasi, tetapi sekarang saatnya telah tiba ketika saatnya, dan selama beberapa bulan saya pergi dengan pikiran tenggelam dalam isi modul komputasi dengan kode profil yang ditulis lebih dari dua tahun oleh rekan-rekan saya.Ketika saya menyelam di sana, One Ring memiliki 29 operasi (beberapa modul berisi lebih dari satu). Ketika muncul - 43, dan masing-masing lebih cepat dari aslinya, dari beberapa persen menjadi puluhan kali. Tapi yang lebih berharga, operasi-operasi yang sebelumnya tersedak dengan data pada partisi 10.000 elemen, sekarang dengan mudah dikunyah dalam jutaan catatan. Di beberapa tempat, saya harus mengorbankan fleksibilitas dan keterbacaan kode, di beberapa tempat harganya penggantian sederhana .map () dengan .mapPartition (), tetapi kode berhenti mogok.Hanya ada satu hambatan - geofencing di wilayah yang sewenang-wenang. Itu masih merupakan solusi hybrid yang aneh dengan mesh eksternal. Dimungkinkan untuk menggunakan Mesh Jepang untuk Jepang, tetapi untuk seluruh dunia perlu untuk mencari varian yang cocok dari grid dinamis, yang hanya bergantung pada koordinat titik, dan mudah digunakan.Pilihan seperti itu ditemukan - Uber H3 .Seperti yang saya mengerti, pohon heksagonal dienkripsi dalam nama H3 - dan ini adalah kotak geografis dengan fitur hebat. Stabil pada seluruh rentang koordinat, sangat cepat (kode asli disebut), ini memberikan sel-sel ukuran seragam tanpa celah di semua tanah, dan memungkinkan Anda untuk membuat banyak pilihan yang berbeda untuk mencakup poligon, titik dan jalur. Juga, sel kotak heksagonal memiliki jumlah tetangga minimal, dan tingkat berikutnya mencakup tujuh sel yang sebelumnya ketat di atas pusat sel yang mendasarinya, yang nyaman ketika membangun peta agregat.Dengan transisi ke H3, tampaknya puzzle telah berkembang sepenuhnya.Jika kita bandingkan dengan apa yang ada di awal, 2,5 tahun yang lalu, maka dari minggu-minggu yang dihabiskan pada satu peta panas yang tidak menguntungkan pada set data ke beberapa juta sinyal, kami sampai pada menit-menit yang dihabiskan pada lusinan kartu dengan set data, yang ukurannya analis data tidak terlalu memperhatikan (Anda harus menggerutu ketika dia menetapkan preset terlalu tinggi untuk ukuran cluster jika menulis hasilnya ke S3 membutuhkan waktu lebih lama daripada perhitungan itu sendiri). Dan dia tidak melihat TC sendiri lagi, dia hanya menyumbat matriks parameter di suatu tempat di rumah, dan menarik jumlah bangunan yang diperlukan dengan python.Tambahkan operasi baru - Anda hanya perlu mengimplementasikan kelas Operasi dengan benar (Anda juga dapat menggunakan Scala jika Anda mau), membungkusnya dengan metadata, memasukkannya ke dalam konfigurasi Anda, dan kemudian Satu Cincin akan mencari tahu apakah Anda memanggil heuristik baru atau memproses dalam rantai dengan benar.Yah, semuanya bekerja baik secara lokal maupun dalam AWS. Itu juga akan berada di beberapa cloud lain jika mendukung S3, dan Spark dapat ditarik melalui Livy di sana - dan kami menyingkirkan semua dependensi eksternal lainnya.Putih seluruhnya
- Gandalf ?!Tetapi kami masih belum memiliki front untuk meluncurkan proses yang fleksibel. Dan templat dari proses semacam itu sendiri harus ditulis dengan cara kuno - dengan tangan di VSCode, tetapi saya ingin menjadi mouse di editor yang mirip dengan Visio. Sesuatu seperti ini: Saya bahkan membuat layanan REST kecil sebagai bagian dari One Ring, yang memiliki semua yang Anda butuhkan untuk menulis editor seperti itu, tetapi terakhir kali saya bekerja di depan adalah sekitar 10 tahun yang lalu, dan tidak dalam kursus tren saat ini. Bukan JSF yang kupercaya, bahkan tidak akan retro, tapi sudah semacam necro. Akan menyenangkan untuk menjadikannya SPA statis pada sesuatu yang modern. Hanya saja saya tidak tahu apa. Minat pribadi saya yang egois dalam mengungkapkan kode Satu Dering
(Saya akan menyelesaikan repositori dengan konten, tetapi Anda dapat menontonnya sekarang), saya harap, ini jelas. Dan jika ada seseorang yang cukup berani untuk menangani tugas ini , saya akan menulis tugas teknis yang waras dengan spesifikasi.Namun secara umum, kami, tim insinyur data, tidak ingin menyimpan alat yang sudah jadi di lemari kami. Kami yakin: ini akan bermanfaat tidak hanya bagi kami. Dan tidak hanya untuk kebutuhan SIG, tetapi secara umum setiap burst-processing dataset dengan langkah-langkah pemrosesan yang dapat diukur.
Dalam artikel terakhir (atau beberapa artikel, sekali lagi, ada sesuatu yang terlalu lama) saya akan memberitahu Anda bagaimana membangun, menjalankan, memperluas dan menggunakan Satu Cincin untuk tugas-tugas penelitian Anda.* Kode sumber One Ring OSS tidak termasuk algoritma heuristik Locomizer yang dipatenkan. Tetapi repositori-nya akan berisi antarmuka dan deskripsi, yang dengannya implementasi bebas heuristik ini dapat dibuat kembali menggunakan metode ruang bersih, yaitu, tanpa diminta dari pihak saya mengenai kode.Ucapan Terima Kasih
... kepada kolega Gregory pomadchin untuk komentar substantif tentang pokok permasalahan, dan sshikov untuk penilaian independen atas keterbacaan teks, dan juga kepada Anton dartov Zadorozhny untuk umpan balik yang tidak terduga pada artikel sebelumnya dalam seri.