Hello semua, saya hebat.
Baru-baru ini, dalam projek kami, kami menggunakan format protobuf sebagai pembawa untuk menyimpan data. Saya secara tidak sengaja menimbus lubang besar untuk diri saya sendiri, tetapi saya mengambil masa yang lama untuk menemuinya.
Nama penuh protobuf ialah Protocol buffers Ia dibangunkan oleh Google dan merupakan mekanisme data bersiri merentas bahasa, merentas platform dan berskala. Serupa dengan XML, tetapi lebih kecil, lebih pantas dan lebih ringkas. Anda hanya perlu mentakrifkan sekali cara anda mahu data anda distrukturkan, dan kemudian anda boleh menggunakan alatan penjanaannya untuk menjana kod sumber yang merangkumi beberapa operasi bersiri dan penyahsirilan. Data berstruktur boleh ditulis dan dibaca dengan mudah daripada pelbagai aliran data dan menggunakan pelbagai bahasa pengaturcaraan.
Versi proto2 menyokong penjanaan kod dalam Java, Python, Objective-C dan C++. Dengan versi bahasa proto3 baharu, anda juga boleh menggunakan Kotlin, Dart, Go, Ruby, PHP dan C#, dan banyak lagi bahasa.
Dalam projek baharu kami, kami menyimpan data projek yang dijalankan menggunakan format protobuf. Dengan cara ini, semasa proses penyahpepijatan, kami mungkin melakukan penyahpepijatan setempat berdasarkan data yang direkodkan di tapak.
message ImageData { // ms int64 timestamp = 1; int32 id = 2; Data mat = 3; } message PointCloud { // ms int64 timestamp = 1; int32 id = 2; PointData pointcloud = 3; } message State { // ms int64 timestamp = 1; string direction = 2; } message Sensor { repeated PointCloud point_data = 1; repeated ImageData image_data = 2; repeated State vehicle_data = 3; }
Kami mentakrifkan set data sedemikian, dan kemudian apabila menyimpan, kerana kadar bingkai bagi tiga sumber data Sensor adalah berbeza, apabila menyimpan, satu Sensor sebenarnya hanya mengandungi satu set data Sebagai tambahan Dua jenis data tidak disertakan.
Apabila kami hanya merakam satu pek, kami tidak menghadapi masalah. Sehingga kita merasakan bahawa satu paket tidak dapat direkodkan untuk masa yang lama, kita perlu mencari penyelesaian untuk membelah paket tersebut.
Pada masa itu, saya fikir ini mesti sangat mudah, jadi kami menyediakannya apabila satu paket mencapai 500M, kami akan menyimpan data seterusnya dalam paket baru. Saya selesai menulisnya dengan lancar dan kemudian meletakkannya di tapak untuk rakaman data. Selepas merakam seketika, kami mengambil semula pakej itu dan membuat simulasi menguji program baharu kami. Didapati terdapat masalah dalam menghuraikan data beberapa pakej. Program ini akan tersangkut di tengah-tengah berjalan. Selepas banyak ujian, didapati beberapa pakej mempunyai masalah ini.
Apa yang kami syak pada mulanya ialah cara untuk menentukan saiz fail adalah salah, yang menjejaskan subkontrak. Kerana apabila menilai saiz fail, fail akan dibuka. Tetapi selepas menilai beberapa cara lain untuk tidak membuka fail, pemisahan itu dilakukan. Saya masih menghadapi masalah dengan beberapa pakej yang direkodkan.
Barulah saya mengesyaki bahawa protobuf mempunyai beberapa keperluan khas untuk menyimpan data. Kemudian, saya membaca beberapa artikel dan mengetahui bahawa protobuf memerlukan pengecam untuk menyimpan berbilang set data ke dalam satu fail. Jika tidak, apabila menghuraikan kembali daripada fail, protobuf tidak tahu di mana watak henti bagi satu data, menyebabkan ralat penghuraian data.
Di sini, lubang itu muncul. Kami menyimpan satu siri data ke dalam satu paket tanpa sebarang manipulasi pemisah. Apabila protobuf menghuraikan, semua kandungan dalam fail dihuraikan ke dalam satu Sensor. Sensor mengandungi semua data, dan protobuf secara aktif menggabungkan semua data yang disimpan.
Pada masa ini, saya dapati bahawa apabila saya merekodkan paket tunggal pada masa lalu, semua data adalah betul. protobuf berjaya dihuraikan.
Sekarang kita tahu bahawa protobuf akan beroperasi dengan cara ini, kita hanya perlu tahu cara membahagikan protobuf. Cara ini memang sukar didapati kerana terlalu sedikit orang seperti kita yang menggunakannya. Carian Cina tidak dapat mencari kandungan ini sama sekali Mungkin semua orang tidak menggunakan protobuf untuk menyimpan data Kaedah yang digunakan oleh semua orang harus menjadi senario interaksi antara pelbagai perkhidmatan.
Akhirnya saya menemui jawapan melalui beberapa jawapan pada stackoverflow Daripada jawapan, saya mengetahui bahawa penyelesaian ini hanya digabungkan secara rasmi dalam protobuf 3.3. Nampak sangat fungsi ni jarang digunakan.
bool SerializeDelimitedToOstream(const MessageLite& message, std::ostream* output); bool ParseDelimitedFromZeroCopyStream( MessageLite* message, io::ZeroCopyInputStream* input, bool* clean_eof);
Melalui pasangan kaedah ini, fail boleh disimpan dan dibaca satu demi satu mengikut aliran data. Tidak perlu risau lagi tentang data digabungkan dan dibaca.
Sudah tentu, data yang disimpan dengan cara ini tidak boleh dihuraikan dengan kaedah penghuraian asal, dan format storan telah berubah sepenuhnya. Kaedah ini mula-mula akan menyimpan saiz data binari dan kemudian menyimpan data binari.
Setelah bertungkus lumus, akhirnya saya dapat menyingkirkan lubang pemisah ini. Senario penggunaan mungkin agak khusus, menyebabkan banyak maklumat yang tidak dapat ditemui sama sekali. Saya menemui masalah ini dengan melihat sendiri kod sumber. Kod sumber C++ sangat sukar dibaca Terdapat banyak kaedah templat dan kelas templat dan mudah terlepas beberapa butiran. Akhirnya, saya melihat kod C# dan akhirnya mengesahkannya.
Atas ialah kandungan terperinci Perkataan asal ditulis semula: Penemuan yang tidak dijangka ialah apa yang pada asalnya dianggap sebagai pepijat sebenarnya adalah ciri dalam reka bentuk Protobuf. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!