Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Dina usum gugur 2019, acara anu ditunggu-tunggu lumangsung dina tim Mail.ru Cloud iOS. Pangkalan data utama pikeun neundeun pengkuh kaayaan aplikasi parantos janten aheng pikeun dunya mobile Kilat Mémori-Dipetakeun Database (LMDB). Dina cut, perhatian anjeun diondang kana review lengkep na dina opat bagian. Kahiji, hayu urang ngobrol ngeunaan alesan pikeun pilihan non-trivial jeung hésé. Teras hayu urang teraskeun kana pertimbangan tilu paus di jantung arsitéktur LMDB: file anu dipetakeun memori, tangkal B +, pendekatan copy-on-write pikeun ngalaksanakeun transactional sareng multiversioning. Tungtungna, pikeun dessert - bagian praktis. Dina éta, urang bakal ningali kumaha mendesain sareng nerapkeun skéma dasar sareng sababaraha tabel, kalebet indéks, di luhur API konci-nilai tingkat rendah.​

eusi

  1. Motivasi Palaksanaan
  2. Positioning LMDB
  3. Tilu paus LMDB
    3.1. Paus #1. Payil-dipetakeun memori
    3.2. Paus #2. B+-tangkal
    3.3. Paus #3. copy-on-write
  4. Ngarancang skéma data dina luhureun API konci-nilai
    4.1. abstraksi dasar
    4.2. Méja Modeling
    4.3. Hubungan modeling antara tabel

1. Motivasi palaksanaan

sataun sakali, dina 2015, urang ngurus nyokot métrik a, sabaraha sering panganteur aplikasi urang lags. Kami henteu ngan ukur ngalakukeun ieu. Kami gaduh seueur keluhan ngeunaan kanyataan yén sakapeung aplikasi lirén ngaréspon kana tindakan pangguna: tombol henteu dipencet, daptar henteu ngagulung, jsb. Ngeunaan mékanika pangukuran ngawartoskeun on AvitoTech, jadi didieu kuring masihan ukur urutan angka.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Hasil pangukuran janten pancuran tiis pikeun urang. Tétéla yén masalah anu disababkeun ku freezes langkung seueur tibatan anu sanés. Lamun, saméméh merealisasikan kanyataan ieu, indikator teknis utama kualitas éta bébas kacilakaan, lajeng sanggeus fokus ngageser dina freeze.

Sanggeus ngawangun dasbor kalawan freezes sarta sanggeus spent kuantitatif и kualitas analisis sabab maranéhanana, musuh utama janten jelas - logika bisnis beurat executing dina thread utama aplikasi. Réaksi alami pikeun aib ieu mangrupikeun kahayang anu ngaduruk pikeun nyorong éta ngaliwatan aliran padamelan. Pikeun solusi sistematis masalah ieu, urang resorted ka arsitéktur multi-threaded dumasar kana aktor lightweight. Kuring dedicated adaptations nya pikeun dunya ios dua benang dina twitter koléktif jeung artikel ngeunaan Habré. Salaku bagian tina carita ayeuna, kuring hoyong ngantebkeun aspék-aspék kaputusan anu mangaruhan pilihan pangkalan data.

Modél aktor organisasi sistem nganggap yén multithreading janten hakekat kadua. Objék modél di jerona resep meuntas wates benang. Jeung maranehna ngalakukeun ieu teu kadang jeung di sababaraha tempat, tapi ampir terus jeung madhab.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Database nyaéta salah sahiji komponén cornerstone dina diagram dibere. Tugas utami nyaéta ngalaksanakeun pola makro Database dibagikeun. Upami di dunya perusahaan dianggo pikeun ngatur sinkronisasi data antara jasa, maka dina kasus arsitéktur aktor, data antara benang. Ku kituna, urang diperlukeun database misalna, gawé bareng nu dina lingkungan multi-threaded teu ngabalukarkeun malah kasusah minimal. Khususna, ieu ngandung harti yén obyék anu diturunkeun tina éta kedah sahenteuna aman-aman, sareng idéalna henteu mutable pisan. Sakumaha anjeun terang, anu terakhir tiasa dianggo sakaligus tina sababaraha benang tanpa nganggo konci naon waé, anu ngagaduhan pangaruh anu mangpaat pikeun pagelaran.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi iosFaktor signifikan kadua anu mangaruhan pilihan pangkalan data nyaéta API awan urang. Éta diideuan ku pendekatan git pikeun sinkronisasi. Kawas anjeunna urang aimed di offline munggaran API, nu Sigana leuwih ti luyu pikeun klien awan. Hal ieu dianggap yén maranéhna ngan sakali bakal ngompa kaluar kaayaan pinuh ku awan, lajeng sinkronisasi dina Lolobana kasus bakal lumangsung ngaliwatan parobahan rolling. Alas, kamungkinan ieu masih ngan dina zona teoritis, sarta dina praktekna, klien teu diajar kumaha carana digawekeun ku patches. Aya sababaraha alesan obyektif pikeun ieu, nu, dina urutan teu reureuh bubuka, urang bakal ninggalkeun kaluar tina kurung. Ayeuna leuwih metot nyaéta hasil instructive palajaran ngeunaan naon anu lumangsung nalika API ceuk "A" jeung konsumen na teu ngomong "B".

Janten, upami anjeun ngabayangkeun git, anu, nalika ngalaksanakeun paréntah tarik, tinimbang nerapkeun patches kana snapshot lokal, ngabandingkeun kaayaan pinuh na sareng server pinuh, maka anjeun bakal gaduh ide anu cukup akurat ngeunaan kumaha sinkronisasi. lumangsung dina klien awan. Ieu gampang nebak yén pikeun palaksanaan na perlu allocate dua tangkal DOM dina mémori jeung meta-informasi ngeunaan sagala server na file lokal. Tétéla yén upami pangguna nyimpen 500 rébu file dina méga, teras pikeun nyingkronkeunana, perlu nyiptakeun deui sareng ngancurkeun dua tangkal kalayan 1 juta titik. Tapi unggal titik mangrupikeun agrégat anu ngandung grafik subobjék. Dina lampu ieu, hasil profiling diperkirakeun. Tétéla sanajan tanpa nyokot kana akun algoritma ngagabung, pisan prosedur nyieun lajeng ngancurkeun sajumlah badag objék leutik waragad Penny geulis. tina skrip pamaké. Hasilna, urang ngalereskeun kriteria penting kadua dina milih database - kamampuhan pikeun nerapkeun operasi CRUD tanpa alokasi dinamis objék.

Sarat anu sanés langkung tradisional, sareng daptar lengkepna nyaéta kieu.

  1. Kaamanan thread.
  2. Multiprocessing. Dictated ku kahayang ngagunakeun conto database sarua pikeun nyinkronkeun kaayaan teu ukur antara threads, tapi ogé antara aplikasi utama jeung ekstensi ios.
  3. Kamampuhan pikeun ngagambarkeun éntitas anu disimpen salaku objék anu teu tiasa dirobih
  4. Kurangna alokasi dinamis dina operasi CRUD.
  5. Rojongan Transaksi pikeun Pasipatan Dasar AsidKecap konci: atomisitas, konsistensi, isolasi sareng reliabilitas.
  6. Laju dina kasus anu pang populerna.

Kalayan sarat sarat ieu, SQLite mangrupikeun pilihan anu saé. Sanajan kitu, salaku bagian tina ulikan ngeunaan alternatif, abdi datang di sakuliah buku "Ngamimitian sareng LevelDB". Dina kapamimpinanna, tolok ukur ditulis anu ngabandingkeun laju damel sareng database anu béda dina skenario awan nyata. Hasilna ngaleuwihan ekspektasi wildest. Dina kasus anu pang populerna - kéngingkeun kursor dina daptar anu diurutkeun sadaya file sareng daptar anu diurutkeun sadaya file pikeun diréktori anu dipasihkeun - LMDB tétéla 10 kali langkung gancang tibatan SQLite. Pilihan janten atra.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

2. LMDB Positioning

LMDB mangrupakeun perpustakaan, leutik pisan (ngan 10K garis), nu implements lapisan dasar panghandapna database - gudang.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Diagram di luhur nunjukkeun yén ngabandingkeun LMDB sareng SQLite, anu ngalaksanakeun tingkat anu langkung luhur, umumna henteu langkung leres tibatan SQLite sareng Data Inti. Eta bakal leuwih adil disebatkeun mesin gudang sarua salaku pesaing sarua - BerkeleyDB, LevelDB, Sophia, RocksDB, jsb Aya malah kamajuan dimana LMDB meta salaku komponén mesin gudang pikeun SQLite. Percobaan sapertos anu munggaran di 2012 dibalanjakeun pangarang LMDB Howard Chu. Hasil tétéla jadi intriguing yén inisiatif na dijemput ku peminat OSS, sarta kapanggih lajengkeun na dina nyanghareupan LumoSQL. Dina Januari 2020 panulis proyék ieu Den Shearer dibere éta dina LinuxConfAu.

Pamakéan utama LMDB nyaéta salaku mesin pikeun database aplikasi. Perpustakaan owes penampilan na ka pamekar OpenLDAP, anu pohara sugema jeung BerkeleyDB salaku dasar proyék maranéhanana. Nyorong jauh ti perpustakaan hina btree, Howard Chu bisa nyieun salah sahiji alternatif nu pang populerna di jaman urang. Anjeunna ngabdikeun laporan anu saé pisan pikeun carita ieu, ogé kana struktur internal LMDB. "Database anu dipetakeun Memori Kilat". Leonid Yuriev (aka yleo) ti Positive Technologies dina ceramahna di Highload 2015 "Mesin LMDB mangrupikeun juara khusus". Di jerona, anjeunna nyarioskeun ngeunaan LMDB dina konteks tugas anu sami pikeun ngalaksanakeun ReOpenLDAP, sareng LevelDB parantos ngalaman kritik komparatif. Salaku hasil tina palaksanaan, Positive Technologies malah ngagaduhan garpu anu aktip berkembang MDBX kalawan fitur ngeunah pisan, optimizations na perbaikan bug.

LMDB sering dianggo salaku panyimpen ogé. Contona, browser Mozilla Firefox milih eta pikeun sababaraha kaperluan, jeung, mimitian ti versi 9, Xcode pikaresep SQLite na pikeun nyimpen indéks.

mesin ogé bray on di dunya ngembangkeun mobile. Ngambah pamakéan na tiasa pikeun mendakan dina klien ios pikeun Telegram. LinkedIn maju saléngkah sareng milih LMDB salaku panyimpen standar pikeun kerangka caching data homegrown na, Data Rocket, ngeunaan éta. ngawartoskeun dina artikel dina 2016.

LMDB suksés berjuang pikeun tempat di panonpoé dina ceruk anu ditinggalkeun ku BerkeleyDB saatos transisi dina kontrol Oracle. perpustakaan ieu dipikacinta keur speed na reliabilitas, sanajan di ngabandingkeun kalayan jenis sorangan. Sakumaha anjeun terang, teu aya tuang siang gratis, sareng kuring hoyong ngantebkeun trade-off anu anjeun kedah nyanghareupan nalika milih antara LMDB sareng SQLite. Diagram di luhur jelas nunjukkeun kumaha kagancangan ningkat. Kahiji, urang teu mayar lapisan tambahan abstraksi dina luhureun gudang disk. Tangtosna, dina arsitéktur anu saé, anjeun masih teu tiasa ngalakukeun tanpa aranjeunna, sareng aranjeunna pasti bakal muncul dina kode aplikasi, tapi aranjeunna langkung ipis. Aranjeunna moal boga fitur nu teu diperlukeun ku aplikasi husus, Contona, rojongan pikeun queries dina basa SQL. Kadua, janten mungkin pikeun ngalaksanakeun pemetaan operasi aplikasi sacara optimal pikeun pamundut ka panyimpenan disk. Lamun SQLite dina karya kuring asalna tina kabutuhan rata-rata aplikasi rata-rata, teras anjeun, salaku pamekar aplikasi, sadar kana skénario beban utama. Pikeun solusi anu langkung produktif, anjeun kedah mayar tag harga anu ningkat pikeun pamekaran solusi awal sareng dukungan anu salajengna.

3. Tilu paus LMDB

Saatos ningali LMDB tina pandangan panon manuk, waktosna pikeun langkung jero. Tilu bagian salajengna bakal dikhususkeun pikeun nganalisa paus utama tempat arsitéktur panyimpen:

  1. Memori-dipetakeun file salaku mékanisme pikeun gawé bareng disk jeung nyingkronkeun struktur data internal.
  2. B + -tangkal salaku organisasi tina struktur data disimpen.
  3. Copy-on-write salaku pendekatan pikeun nyayogikeun sipat transaksional ACID sareng multiversioning.

3.1. Paus #1. Payil-dipetakeun memori

File anu dipetakeun mémori mangrupikeun unsur arsitéktur anu penting bahkan muncul dina nami gudang. Isu cache sarta nyingkronkeun aksés ka inpo nu disimpen sagemblengna dina rahmat sistem operasi. LMDB henteu ngandung caches dina dirina sorangan. Ieu mangrupikeun kaputusan sadar ku panulis, sabab maca data langsung tina file anu dipetakeun ngamungkinkeun anjeun pikeun motong seueur sudut dina palaksanaan mesin. Di handap ieu tebih ti daptar lengkep sababaraha di antarana.

  1. Ngajaga konsistensi data dina panyimpenan nalika damel sareng éta tina sababaraha prosés janten tanggung jawab sistem operasi. Dina bagian salajengna, montir ieu dibahas di jéntré tur kalawan gambar.
  2. Henteuna cache lengkep ngaleungitkeun LMDB tina overhead anu aya hubunganana sareng alokasi dinamis. Maca data dina prakna nyaéta netepkeun pointer ka alamat anu leres dina mémori virtual sareng teu aya deui. Sora kawas lamunan, tapi dina sumber gudang, sadaya panggero calloc ngumpul dina fungsi konfigurasi gudang.
  3. Henteuna caches ogé hartosna henteuna konci anu aya hubunganana sareng sinkronisasi pikeun ngaksésana. Pamiarsa, anu jumlahna sawenang-wenang tiasa aya dina waktos anu sami, henteu mendakan mutex tunggal dina jalan ka data. Kusabab ieu, laju maca ngagaduhan skalabilitas linier idéal dina hal jumlah CPU. Dina LMDB, ngan ukur operasi ngarobih anu disingkronkeun. Ngan aya hiji panulis dina hiji waktu.
  4. Minimum cache sareng logika sinkronisasi ngahemat kodeu tina jinis kasalahan anu kompleks pisan anu aya hubunganana sareng damel di lingkungan multi-threaded. Aya dua studi database metot dina konferensi Usenix OSDI 2014: "Sadaya Sistem File Henteu Didamel Sarua: Dina Pajeulitna Ngadamel Aplikasi Konsisten Kacilakaan" и Nyiksa Database pikeun Kasenangan sareng Kauntungan. Ti aranjeunna anjeun tiasa nampi inpormasi ngeunaan réliabilitas LMDB anu teu pernah kantos aya, sareng palaksanaan ampir sampurna tina sipat ACID tina transaksi, anu ngaleuwihan dina SQLite anu sami.
  5. The minimalism of LMDB ngamungkinkeun ngagambarkeun mesin kode na pikeun sakabéhna ditempatkeun dina cache L1 tina processor kalawan ciri speed hasilna.

Hanjakalna, dina ios, file anu dipetakeun ku mémori henteu langkung rosa sapertos anu urang pikahoyong. Pikeun ngobrol ngeunaan kalemahan pakait sareng aranjeunna langkung sadar, perlu ngelingan prinsip umum pikeun nerapkeun mékanisme ieu dina sistem operasi.

Inpo umum ngeunaan file-dipetakeun memori

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi iosKalayan unggal aplikasi anu tiasa dieksekusi, sistem operasi ngahubungkeun éntitas anu disebut prosés. Unggal prosés dialokasikeun sauntuyan alamat anu padeukeut, dimana éta nempatkeun sadayana anu diperyogikeun pikeun jalan. Alamat panghandapna ngandung bagian kalawan kode jeung hardcoded data jeung sumber. Salajengna asalna blok-tumuwuh luhur spasi alamat dinamis, ogé dipikawanoh ku urang salaku numpuk. Éta ngandung alamat éntitas anu muncul salami operasi program. Di luhur nyaéta daérah mémori anu dianggo ku tumpukan aplikasi. Boh tumuwuh atawa ngaleutikan, dina basa sejen, ukuranana ogé mibanda sipat dinamis. Supados tumpukan sareng tumpukan henteu nyorong sareng ngaganggu, aranjeunna dipisahkeun dina tungtung anu béda dina rohangan alamat.Aya liang antara dua bagian dinamis di luhur sareng handap. Alamat dina bagian tengah ieu dipaké ku sistem operasi pikeun ngahubungkeun jeung prosés rupa éntitas. Khususna, éta tiasa ngapetakeun sababaraha alamat kontinyu kana file dina disk. Berkas sapertos kitu disebut file anu dipetakeun memori.​

Ruang alamat anu dialokasikeun pikeun prosés anu ageung. Sacara téoritis, jumlah alamat ngan ukur ku ukuran pointer, anu ditangtukeun ku bitness sistem. Upami mémori fisik ditugaskeun ka éta 1-in-1, maka prosés anu munggaran bakal nyéépkeun sadayana RAM, sareng moal aya patarosan ngeunaan seueur tugas.

Nanging, urang terang tina pangalaman yén sistem operasi modéren tiasa ngajalankeun saloba prosés anu dipikahoyong dina waktos anu sami. Ieu mungkin alatan kanyataan yén maranéhna allocate loba memori pikeun prosés ukur dina kertas, tapi dina kanyataanana aranjeunna ngamuat kana mémori fisik utama ngan éta bagian anu di paménta di dieu jeung ayeuna. Ku alatan éta, mémori pakait sareng prosés disebut virtual.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Sistem operasi ngatur mémori maya sareng fisik kana halaman ukuran anu tangtu. Pas halaman tangtu mémori maya aya dina paménta, sistem operasi ngamuat kana mémori fisik sarta nempatkeun turun susuratan antara aranjeunna dina tabel husus. Upami teu aya liang gratis, teras salah sahiji halaman anu dimuat sateuacana disalin kana disk, sareng anu dipénta bakal dilaksanakeun. Prosedur ieu, anu urang bakal uih deui sakedap, disebut swapping. Gambar di handap ieu ngagambarkeun prosés anu dijelaskeun. Dina éta, halaman A sareng alamat 0 dimuat sareng disimpen dina halaman mémori utama kalayan alamat 4. Kanyataan ieu ditingali dina tabel korespondensi dina nomer sél 0.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Kalawan file memori-dipetakeun, carita persis sarua. Logis, aranjeunna konon terus jeung sagemblengna disimpen dina spasi alamat maya. Nanging, aranjeunna asup kana halaman mémori fisik ku halaman sareng ngan ukur upami diperyogikeun. Modifikasi kaca sapertos ieu disingkronkeun sareng file dina disk. Janten, anjeun tiasa ngalakukeun file I / O, ngan ukur damel sareng bait dina mémori - sadaya parobihan bakal otomatis ditransfer ku kernel sistem operasi ka file aslina.​

Gambar di handap ieu nunjukkeun kumaha LMDB nyingkronkeun kaayaan nalika damel sareng pangkalan data tina prosés anu béda. Ku pemetaan mémori virtual tina prosés anu béda kana file anu sami, kami sacara de facto ngawajibkeun sistem operasi pikeun transitively nyingkronkeun blok-blok anu tangtu dina rohangan alamatna saling, dimana LMDB katingalina.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Nuansa penting nyaéta LMDB ngarobih file data sacara standar ngaliwatan mékanisme panggero sistem nyerat, sareng filena nyalira dina modeu baca wungkul. Pendekatan ieu ngagaduhan dua implikasi anu penting.

Konsékuansi kahiji nyaéta umum pikeun sakabéh sistem operasi. Intina nyaéta pikeun nambihan panyalindungan ngalawan karusakan anu teu dihaja kana pangkalan data ku kode anu salah. Sakumaha anjeun terang, paréntah anu tiasa dieksekusi tina prosés bébas ngaksés data ti mana waé dina rohangan alamatna. Dina waktos anu sami, sakumaha anu urang émut, nampilkeun file dina modeu baca-tulis hartosna yén instruksi naon waé ogé tiasa ngarobih salian. Mun manehna ngalakukeun ieu ku kasalahan, nyobian, contona, mun sabenerna nimpa unsur Asép Sunandar Sunarya dina indéks non-existent, lajeng ku cara kieu manehna bisa ngahaja ngarobah file dipetakeun ka alamat ieu, nu bakal ngakibatkeun korupsi database. Upami file ditampilkeun dina modeu baca wungkul, usaha pikeun ngarobih rohangan alamat anu cocog sareng éta bakal ngakibatkeun kacilakaan program sareng sinyal. SIGSEGV, sarta file bakal tetep gembleng.

Konsékuansi kadua geus husus pikeun ios. Panulis atanapi sumber anu sanés sacara eksplisit nyebatkeun éta, tapi tanpa éta, LMDB moal cocog pikeun ngajalankeun sistem operasi mobile ieu. Bagian saterusna devoted kana tinimbangan na.

Spésifikasi file anu dipetakeun mémori dina ios

Dina 2018, aya laporan anu saé dina WWDC ios Mémori Jero beuleum. Éta nyarioskeun yén dina ios sadaya halaman anu aya dina mémori fisik kalebet salah sahiji tina 3 jinis: kotor, dikomprés sareng bersih.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Mémori bersih mangrupikeun kumpulan halaman anu tiasa aman dikaluarkeun tina mémori fisik. Data anu dikandungna tiasa dimuat deui tina sumber aslina upami diperyogikeun. Maca wungkul-memori-dipetakeun file digolongkeun kana kategori ieu. Ios henteu sieun ngabongkar halaman anu dipetakeun kana file tina mémori iraha waé, sabab dijamin bakal nyingkronkeun sareng file dina disk.

Sadaya halaman anu dirobih janten mémori anu kotor, henteu paduli dimana aranjeunna asalna. Khususna, file anu dipetakeun memori anu dirobih ku nyerat kana mémori virtual anu aya hubunganana sareng aranjeunna ogé bakal digolongkeun ku cara ieu. Muka LMDB kalayan bandéra MDB_WRITEMAP, sanggeus nyieun parobahan, anjeun bisa nempo sorangan.​

Pas hiji aplikasi mimiti nyokot teuing memori fisik, ios compresses kaca na kotor. Kumpulan mémori anu dijajah ku halaman anu kotor sareng dikomprés nyaéta anu disebut tapak mémori tina aplikasi. Nalika éta ngahontal nilai ambang anu tangtu, daemon sistem pembunuh OOM saatos prosés sareng ngeureunkeunana sacara paksa. Ieu mangrupikeun peculiarity ios dibandingkeun sareng sistem operasi desktop. Sabalikna, nurunkeun tapak mémori ku cara ngagentos halaman tina mémori fisik ka disk henteu disayogikeun dina ios. Hiji ngan ukur tiasa nebak alesanana. Panginten prosedur pikeun mindahkeun halaman sacara intensif kana disk sareng mundur teuing nyéépkeun énérgi pikeun alat sélulér, atanapi ios ngahémat sumber daya nyerat sél dina drive SSD, atanapi panginten desainer henteu wareg ku kinerja sistem sadayana, dimana sadayana aya. terus diganti. Sanajan kitu, kanyataanana tetep.

Warta anu saé, anu parantos disebatkeun sateuacana, nyaéta LMDB henteu nganggo mékanisme mmap pikeun ngapdet file sacara standar. Ieu kieu yén data rendered digolongkeun kana mémori bersih ku ios sarta henteu nyumbang kana tapak suku memori. Ieu tiasa diverifikasi nganggo alat Xcode anu disebut VM Tracker. Potret layar di handap nembongkeun kaayaan mémori maya aplikasi ios Cloud nalika operasi. Dina mimitina, 2 instansi LMDB diinisialisasi di dinya. Kahiji ieu diwenangkeun peta file na ka 1GiB memori virtual, kadua - 512MiB. Najan kanyataan yén duanana gudang ngeusian jumlah nu tangtu memori nyicingan, taya sahijina nyumbang kana ukuran kotor.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Ayeuna waktuna pikeun warta goréng. Hatur nuhun kana mékanisme swap dina sistem operasi desktop 64-bit, unggal prosés tiasa nyandak saloba spasi alamat maya sakumaha rohangan bébas dina hard disk ngamungkinkeun pikeun swap poténsi na. Ngaganti swap sareng komprési dina ios sacara drastis ngirangan maksimal teoritis. Ayeuna sadaya prosés hirup kedah pas kana mémori utama (baca RAM), sareng sadaya anu henteu cocog kedah diputus paksa. Disebutkeun saperti di luhur laporansareng di dokuméntasi resmi. Akibatna, ios parah ngawatesan jumlah memori sadia pikeun alokasi via mmap. Ieuh di dieu anjeun tiasa ningali wates empiris dina jumlah mémori anu tiasa dialokasikeun dina alat anu béda nganggo panggero sistem ieu. Dina model paling modérn smartphone, ios geus jadi berehan ku 2 gigabytes, sarta dina versi luhur iPad - ku 4. Dina prakna, tangtosna, Anjeun kudu difokuskeun model alat dirojong bungsu, dimana sagalana pisan hanjelu. Malah parah, ningali kaayaan mémori aplikasi dina VM Tracker, anjeun bakal mendakan yén LMDB jauh tina hiji-hijina anu ngaku mémori anu dipetakeun ku mémori. Potongan anu saé didahar ku alokasi sistem, file sumberdaya, kerangka gambar, sareng prédator anu langkung alit.

Salaku hasil tina ékspérimén dina Cloud, kami mendakan nilai kompromi di handap ieu tina mémori anu dialokasikeun ku LMDB: 384 megabyte pikeun alat 32-bit sareng 768 pikeun alat 64-bit. Sanggeus volume ieu dipaké nepi, sagala operasi modifying ngawitan ngalengkepan kalayan kode MDB_MAP_FULL. Urang niténan kasalahan sapertos dina ngawaskeun kami, tapi aranjeunna cukup leutik bisa neglected dina tahap ieu.

Alesan anu teu jelas pikeun konsumsi mémori anu kaleuleuwihan ku panyimpenan tiasa janten transaksi umur panjang. Pikeun ngartos kumaha hubungan dua fenomena ieu, éta bakal ngabantosan urang mertimbangkeun dua paus LMDB sésana.

3.2. Paus #2. B+-tangkal

Pikeun niru tabel di luhur toko nilai konci, operasi di handap ieu kedah aya dina API na:

  1. Nyelapkeun unsur anyar.
  2. Pilarian unsur sareng konci anu dipasihkeun.
  3. Mupus hiji unsur.
  4. Iterate leuwih interval konci dina urutan diurutkeun maranéhna.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi iosStruktur data pangbasajanna anu bisa kalayan gampang nerapkeun sakabéh opat operasi nyaéta tangkal pilarian binér. Unggal titik na mangrupakeun konci anu ngabagi sakabéh sawaréh konci anak jadi dua subtrees. Di kénca aya jalma anu leuwih leutik batan indungna, sarta di katuhu - maranéhanana anu leuwih badag. Kéngingkeun set konci anu dipesen dihontal ku salah sahiji traversals tangkal klasik

Tangkal binér gaduh dua kalemahan dasar anu nyegah aranjeunna efektif salaku struktur data disk. Kahiji, darajat kasaimbangan maranéhanana nyaéta unpredictable. Aya resiko considerable pikeun meunangkeun tangkal nu jangkungna cabang béda bisa greatly rupa-rupa, nu nyata worsens pajeulitna algorithmic pilarian dibandingkeun naon anu dipiharep. Bréh, kelimpahan cross-link antara titik deprives tangkal binér lokalitas dina mémori Tutup titik (dina watesan tumbu antara aranjeunna) bisa lokasina dina kaca lengkep beda dina mémori virtual. Salaku konsekuensi, sanajan hiji traversal basajan tina sababaraha titik tatangga dina tangkal bisa merlukeun ngadatangan jumlah comparable kaca. Ieu masalah sanajan urang ngobrol ngeunaan efisiensi tangkal binér salaku struktur data dina mémori, saprak terus-terusan puteran kaca dina cache processor teu mirah. Lamun datang ka remen raising kaca nu patali titik tina disk, hal jadi bener goréng. hanjakal.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi iosTangkal B, janten évolusi tangkal binér, ngarengsekeun masalah anu diidentipikasi dina paragraf sateuacana. Kahiji, aranjeunna timer balancing. Bréh, unggal titik maranéhanana splits susunan kenop anak teu jadi 2, tapi kana M maréntahkeun sawaréh, jeung jumlah M bisa jadi rada badag, dina urutan sababaraha ratus atawa malah rébuan.

Ku kituna:

  1. Unggal titik ngagaduhan sajumlah ageung konci anu parantos dipesen sareng tangkalna rendah pisan.
  2. Tangkal éta ngagaduhan harta lokalitas dina mémori, sabab konci anu nilaina caket sacara alami ayana di gigireun masing-masing dina hiji atanapi titik tatangga.
  3. Ngurangan jumlah titik transit nalika turun tangkal salila operasi pilarian.
  4. Ngurangan jumlah titik udagan dibaca pikeun queries rentang, saprak unggal sahijina geus ngandung angka nu gede ngarupakeun konci maréntahkeun.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

LMDB ngagunakeun varian B-tangkal disebut tangkal B + pikeun nyimpen data. Diagram di luhur nunjukkeun tilu jinis titik anu dikandungna:

  1. Di luhur aya akar. Ieu materializes nanaon leuwih ti konsép database dina Repository a. Dina hiji conto LMDB, anjeun tiasa nyiptakeun sababaraha pangkalan data anu ngabagi rohangan alamat maya anu dipetakeun. Tiap di antarana dimimitian ti akar sorangan.
  2. Dina tingkat panghandapna aya daun (daun). Éta ngan ukur aranjeunna anu ngandung pasangan konci-nilai anu disimpen dina pangkalan data. Ku jalan kitu, ieu téh peculiarity B + -tangkal. Lamun B-tangkal normal nyimpen bagian-nilai dina titik sadaya tingkat, mangka B + -variasi ngan dina hiji panghandapna. Saatos ngalereskeun kanyataan ieu, dina anu salajengna urang bakal nyauran subtipe tangkal anu dianggo dina LMDB ngan saukur tangkal B.
  3. Antara akar sareng daun, aya 0 atanapi langkung tingkat téknis sareng titik navigasi (cabang). Tugasna nyaéta ngabagi set konci anu diurutkeun antara daun.

Sacara fisik, titik mangrupikeun blok mémori anu panjangna parantos ditangtukeun. Ukuranana mangrupikeun sababaraha ukuran halaman mémori dina sistem operasi, anu urang bahas di luhur. Struktur node dipidangkeun di handap. Lulugu ngandung meta-inpormasi, anu paling atra, contona, nyaéta checksum. Salajengna aya inpormasi ngeunaan offsets, dimana sél sareng data ayana. Peran data tiasa boh konci, upami urang ngobrol ngeunaan titik navigasi, atanapi sadayana pasangan konci-nilai dina kasus daun. Anjeun tiasa maca langkung seueur ngeunaan struktur halaman dina karya "Evaluasi Toko-Nilai Konci Kinerja Luhur".

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Sanggeus diurus eusi internal tina titik kaca, urang salajengna bakal ngagambarkeun LMDB B-tangkal dina cara saderhana dina formulir di handap ieu.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Kaca sareng titik-titik disusun sacara berurutan dina disk. Kaca anu jumlahna langkung ageung aya di tungtung file. Nu disebut kaca meta (kaca meta) ngandung émbaran ngeunaan offsets, nu bisa dipaké pikeun manggihan akar sakabéh tangkal. Nalika file dibuka, LMDB nyeken halaman file ku halaman ti tungtung dugi ka awal pikeun milarian halaman meta anu valid sareng mendakan pangkalan data anu tos aya.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Ayeuna, gaduh ide ngeunaan struktur logis sareng fisik organisasi data, urang tiasa neraskeun mertimbangkeun paus katilu LMDB. Éta kalayan bantuan na yén sakabéh modifikasi gudang lumangsung transactionally sarta di isolasi ti silih, mere database sakabéhna ogé multiversion milik.

3.3. Paus #3. copy-on-write

Sababaraha operasi B-tangkal ngalibatkeun nyieun sakabeh runtuyan parobahan titik na. Hiji conto nyaéta nambahkeun konci anyar ka titik nu geus ngahontal kapasitas maksimum na. Dina hal ieu, perlu, firstly, mun dibeulah titik jadi dua, sarta Bréh, pikeun nambahkeun tumbu ka titik anyar dipintal kaluar anak di indungna na. Prosedur ieu berpotensi bahaya pisan. Upami kusabab sababaraha alesan (kacilakaan, pareum listrik, jsb) ngan ukur sawaréh parobihan tina séri anu kajantenan, maka tangkal bakal tetep dina kaayaan anu teu konsisten.

Salah sahiji solusi tradisional pikeun nyieun database kasalahan-tolerant nyaéta nambahkeun hiji tambahan struktur data dumasar-disk, log transaksi, ogé katelah write-ahead log (WAL), gigireun B-tangkal. Ieu mangrupakeun file, di ahir nu, mastikeun saméméh modifikasi tina B-tangkal sorangan ditulis operasi dimaksudkeun. Janten, upami korupsi data dideteksi nalika diagnosis diri, pangkalan data konsultasi log pikeun ngabersihan diri.

LMDB geus milih métode béda salaku mékanisme kasabaran lepat na, nu disebut copy-on-write. Intina nyaéta yén tinimbang ngamutahirkeun data dina halaman anu tos aya, éta mimiti nyalin sadayana sareng ngadamel sadaya modifikasi anu parantos aya dina salinan.​

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Salajengna, supados data diropéa janten sadia, perlu ngarobah link ka titik nu geus jadi up-to-date dina titik indungna dina hubungan eta. Kusabab éta ogé kedah dirobih pikeun ieu, éta ogé tos disalin. Prosésna diteruskeun sacara rekursif dugi ka akar. Data dina halaman meta nyaéta anu terakhir anu robih.​

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Upami ujug-ujug prosésna ngadat salami prosedur pembaruan, teras halaman meta énggal moal didamel, atanapi moal diserat kana disk dugi ka tungtungna, sareng checksumna bakal lepat. Dina salah sahiji dua kasus ieu, kaca anyar bakal unreachable jeung nu heubeul moal kapangaruhan. Ieu ngaleungitkeun kabutuhan LMDB pikeun nyerat log payun pikeun ngajaga konsistensi data. De facto, struktur panyimpen data dina disk, dijelaskeun di luhur, sakaligus nyandak fungsina. Henteuna log transaksi anu eksplisit mangrupikeun salah sahiji fitur LMDB, anu nyayogikeun kecepatan maca data anu luhur.​

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Konstruksi anu dihasilkeun, disebutna ngan ukur B-tangkal, sacara alami nyayogikeun isolasi transaksi sareng multiversioning. Dina LMDB, unggal transaksi kabuka gaduh akar tangkal up-to-date anu aya hubunganana sareng éta. Salami transaksi henteu réngsé, halaman tangkal anu aya hubunganana sareng éta moal pernah dirobih atanapi dianggo deui pikeun versi data énggal. waktos urus dibuka, sanajan gudang terus aktip diropéa dina waktos ieu. Ieu hakekat multiversioning, ngajadikeun LMDB sumber data idéal pikeun urang tercinta UICollectionView. Saatos muka transaksi, anjeun henteu kedah ningkatkeun tapak suku mémori aplikasi, buru-buru ngompa data ayeuna kana sababaraha struktur mémori, sieun ditinggalkeun ku nanaon. Fitur ieu ngabédakeun LMDB sareng SQLite anu sami, anu henteu tiasa ngagungkeun total isolasi sapertos kitu. Saatos muka dua transaksi anu terakhir sareng ngahapus catetan anu tangtu dina salah sahijina, catetan anu sami henteu tiasa didapet deui dina sésana kadua.

Sisi flip tina koin nyaéta konsumsi mémori virtual anu berpotensi langkung luhur. Slide nembongkeun naon struktur database bakal kasampak kawas lamun dirobah dina waktos anu sareng 3 buka buka transaksi nempo versi béda tina database. Kusabab LMDB teu tiasa nganggo deui titik-titik anu tiasa dihontal tina akar anu aya hubunganana sareng transaksi anu saleresna, panyimpen henteu gaduh pilihan tapi nyayogikeun akar kaopat anu sanés dina mémori sareng sakali deui kloning halaman anu dirobih di handapeun éta.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Di dieu moal superfluous ngelingan bagian dina file memori-dipetakeun. Sigana yén konsumsi tambahan memori maya teu matak ngaganggu urang loba, sabab teu nyumbang kana tapak suku memori aplikasi urang. Sanajan kitu, dina waktos anu sareng, éta dicatet yén ios pisan pelit dina allocating eta, sarta kami teu bisa nyadiakeun 1 terabyte LMDB wewengkon dina server atawa desktop tina taktak master na teu mikir ngeunaan fitur ieu pisan. Nalika mungkin, anjeun kedah nyobian ngajaga umur transaksi sapendek-gancang.

4. Ngarancang skéma data dina luhureun API konci-nilai

Hayu urang mimitian parsing API ku ningali abstraksi dasar anu disayogikeun ku LMDB: lingkungan sareng pangkalan data, konci sareng nilai, transaksi sareng kursor.

Catetan ngeunaan daptar kode

Sadaya fungsi dina API publik LMDB balik hasil karya maranéhanana dina bentuk kode kasalahan, tapi dina sakabéh listings saterusna dipariksa na disingkahkeun demi conciseness.. Dina prakték, urang ngagunakeun kode urang sorangan pikeun berinteraksi sareng gudang. garpu C ++ wrappers lmdbxx, nu kasalahan materialize salaku C++ iwal.

Salaku cara panggancangna pikeun nyambungkeun LMDB ka proyék ios atanapi macOS, kuring nawiskeun CocoaPod kuring POSLMDB.

4.1. abstraksi dasar

Lingkungan

struktur MDB_env nyaeta Repository tina kaayaan internal tina LMDB. Kulawarga fungsi awalan mdb_env ngidinan Anjeun pikeun ngonpigurasikeun sababaraha sipat na. Dina kasus pangbasajanna, initialization tina mesin Sigana mah ieu.

mdb_env_create(env);​
mdb_env_set_map_size(*env, 1024 * 1024 * 512)​
mdb_env_open(*env, path.UTF8String, MDB_NOTLS, 0664);

Dina aplikasi Mail.ru Cloud, urang ngarobih nilai standar pikeun ukur dua parameter.

Anu kahiji nyaéta ukuran rohangan alamat maya dimana file panyimpen dipetakeun. Hanjakal, sanajan dina alat nu sami, nilai husus bisa rupa-rupa nyata ti ngajalankeun ka ngajalankeun. Pikeun tumut kana akun fitur ieu ios, urang milih jumlah maksimum gudang dinamis. Dimimitian ti nilai nu tangtu, éta successively halves nepi ka fungsi mdb_env_open moal balik hasil lian ti ENOMEM. Dina tiori, aya cara sabalikna - mimiti allocate minimum memori mesin, lajeng, nalika kasalahan narima. MDB_MAP_FULL, nambahan deui. Sanajan kitu, éta leuwih thorny. alesan teh nya eta prosedur pikeun remapping memori ngagunakeun fungsi mdb_env_set_map_size invalidates sakabéh éntitas (kursor, transaksi, konci na nilai) nampi ti mesin saméméhna. Akunting pikeun péngkolan sapertos kajadian dina kode bakal ngakibatkeun komplikasi signifikan na. Upami, kumaha waé, mémori maya anjeun dipikacinta pisan, maka ieu tiasa janten alesan pikeun ningali garpu anu parantos jauh ka payun. MDBX, Dimana diantara fitur nyatakeun aya "otomatis on-the-fly database ukuran adjustment".

Parameter kadua, nilai standar anu henteu cocog sareng kami, ngatur mékanika pikeun mastikeun kasalametan benang. Hanjakalna, sahenteuna dina ios 10, aya masalah sareng pangrojong panyimpenan lokal benang. Ku sabab kitu, dina conto di luhur, gudang dibuka kalayan bandéra MDB_NOTLS. Sajaba ti éta, ogé diperlukeun garpu C ++ pambungkus lmdbxxpikeun motong variabel sareng dina atribut ieu.

Databases

Pangkalan data mangrupikeun conto anu misah tina B-tangkal anu urang bahas di luhur. Bubukana lumangsung di jero transaksi, anu mimitina sigana rada anéh.

MDB_txn *txn;​
MDB_dbi dbi;​
mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);​
mdb_dbi_open(txn, NULL, MDB_CREATE, &dbi);​
mdb_txn_abort(txn);

Mémang, transaksi di LMDB mangrupikeun éntitas panyimpen, sanés database khusus. Konsep ieu ngamungkinkeun anjeun pikeun ngalakukeun operasi atom dina éntitas anu aya dina pangkalan data anu béda. Dina tiori, ieu muka kamungkinan modeling tabel dina bentuk database béda, tapi dina hiji waktu kuring indit cara sejen, dijelaskeun dina jéntré di handap.

Konci jeung nilai

struktur MDB_val model konsép duanana konci jeung nilai a. Repository nu teu boga pamanggih ngeunaan semantik maranéhanana. Pikeun dirina, hal anu béda téh ngan hiji Asép Sunandar Sunarya bait tina ukuran tinangtu. Ukuran konci maksimum nyaéta 512 bait.

typedef struct MDB_val {​
    size_t mv_size;​
    void *mv_data;​
} MDB_val;​​

Toko ngagunakeun comparator pikeun nyortir konci dina urutan naek. Upami anjeun henteu ngagentos éta ku anjeun nyalira, maka anu standar bakal dianggo, anu nyortirkeun bait-demi-bait dina urutan leksikografis.​

Transaksi

Alat transaksi dijelaskeun sacara rinci dina bab saméméhna, jadi didieu kuring bakal ngulang sipat utama maranéhanana dina garis pondok:

  1. Rojongan pikeun sakabéh sipat dasar AsidKecap konci: atomisitas, konsistensi, isolasi sareng reliabilitas. Abdi teu tiasa ngabantosan tapi perhatikeun yén dina hal daya tahan dina macOS sareng ios aya bug anu tetep dina MDBX. Anjeun tiasa maca deui dina maranéhna README.
  2. Pendekatan kana multithreading digambarkeun ku skéma "panulis tunggal / sababaraha pamiarsa". Panulis saling meungpeuk, tapi henteu ngahalangan pamiarsa. Pamiarsa henteu ngahalangan panulis atanapi anu sanés.
  3. Rojongan pikeun transaksi nested.
  4. rojongan multiversion.

Multiversioning di LMDB saé pisan kuring hoyong nunjukkeun éta dina aksi. Kodeu di handap ieu nunjukkeun yén unggal transaksi tiasa dianggo sareng persis versi database anu relevan dina waktos dibukana, teras terasingkeun tina sagala parobihan anu salajengna. Initializing Repository jeung nambahkeun catetan test kana eta teu dipikaresep, jadi ritual ieu ditinggalkeun dina spoiler nu.

Nambahkeun éntri tés

MDB_env *env;
MDB_dbi dbi;
MDB_txn *txn;

mdb_env_create(&env);
mdb_env_open(env, "./testdb", MDB_NOTLS, 0664);

mdb_txn_begin(env, NULL, 0, &txn);
mdb_dbi_open(txn, NULL, 0, &dbi);
mdb_txn_abort(txn);

char k = 'k';
MDB_val key;
key.mv_size = sizeof(k);
key.mv_data = (void *)&k;

int v = 997;
MDB_val value;
value.mv_size = sizeof(v);
value.mv_data = (void *)&v;

mdb_txn_begin(env, NULL, 0, &txn);
mdb_put(txn, dbi, &key, &value, MDB_NOOVERWRITE);
mdb_txn_commit(txn);

MDB_txn *txn1, *txn2, *txn3;
MDB_val val;

// Открываем 2 транзакции, каждая из которых смотрит
// на версию базы данных с одной записью.
mdb_txn_begin(env, NULL, 0, &txn1); // read-write
mdb_txn_begin(env, NULL, MDB_RDONLY, &txn2); // read-only

// В рамках первой транзакции удаляем из базы данных существующую в ней запись.
mdb_del(txn1, dbi, &key, NULL);
// Фиксируем удаление.
mdb_txn_commit(txn1);

// Открываем третью транзакцию, которая смотрит на
// актуальную версию базы данных, где записи уже нет.
mdb_txn_begin(env, NULL, MDB_RDONLY, &txn3);
// Убеждаемся, что запись по искомому ключу уже не существует.
assert(mdb_get(txn3, dbi, &key, &val) == MDB_NOTFOUND);
// Завершаем транзакцию.
mdb_txn_abort(txn3);

// Убеждаемся, что в рамках второй транзакции, открытой на момент
// существования записи в базе данных, её всё ещё можно найти по ключу.
assert(mdb_get(txn2, dbi, &key, &val) == MDB_SUCCESS);
// Проверяем, что по ключу получен не абы какой мусор, а валидные данные.
assert(*(int *)val.mv_data == 997);
// Завершаем транзакцию, работающей хоть и с устаревшей, но консистентной базой данных.
mdb_txn_abort(txn2);

Optionally, abdi nyarankeun nyobian trik sarua jeung SQLite tur tingal kumaha kajadian.

Multiversioning mawa mangpaat pisan nice kana kahirupan hiji pamekar ios. Ngagunakeun sipat ieu, anjeun bisa kalayan gampang tur alami nyaluyukeun laju update sumber data pikeun formulir layar dumasar kana tinimbangan pangalaman pamaké. Salaku conto, hayu urang nyandak fitur sapertos aplikasi Mail.ru Cloud salaku eusi autoloading tina galeri média sistem. Kalayan sambungan anu saé, klien tiasa nambihan sababaraha poto per detik ka server. Lamun ngamutahirkeun sanggeus unggal download UICollectionView kalawan eusi media dina awan pamaké, anjeun bisa poho ngeunaan 60 fps tur mulus ngagulung salila prosés ieu. Pikeun nyegah apdet layar sering, Anjeun kudu kumaha bae ngawatesan laju robah data dina dasar UICollectionViewDataSource.

Upami pangkalan data henteu ngadukung multiversioning sareng ngamungkinkeun anjeun ngan ukur damel sareng kaayaan ayeuna, teras pikeun nyiptakeun snapshot data anu stabil waktos, anjeun kedah nyalin kana sababaraha struktur data dina mémori atanapi kana méja samentawis. Salah sahiji pendekatan ieu mahal pisan. Dina kasus panyimpen dina mémori, urang kéngingkeun biaya mémori anu disababkeun ku nyimpen objék anu diwangun sareng biaya waktos anu aya hubunganana sareng transformasi ORM anu kaleuleuwihan. Sedengkeun pikeun tabel samentara, ieu mangrupa pelesir malah leuwih mahal, nu ngajadikeun rasa ngan dina kasus non-trivial.

Multiversioning LMDB ngajawab masalah ngajaga sumber data stabil dina cara pisan elegan. Cukup pikeun muka transaksi sareng voila - dugi ka réngsé, set data dijamin bakal dibenerkeun. Logika laju update na ayeuna sagemblengna aya dina leungeun lapisan presentasi, kalawan euweuh overhead sumberdaya signifikan.

Kursor

Kursor nyadiakeun mékanisme pikeun Iteration mantri leuwih pasangan konci-nilai ku traversing hiji B-tangkal. Tanpa aranjeunna, mustahil pikeun modél sacara efektif tabel dina pangkalan data, anu ayeuna urang giliran.

4.2. Méja Modeling

Properti urutan konci ngamungkinkeun anjeun pikeun ngawangun abstraksi tingkat luhur sapertos tabel di luhur abstraksi dasar. Hayu urang nganggap prosés ieu dina conto tabel utama klien awan, dimana inpormasi ngeunaan sadaya file sareng polder pangguna disimpen.

Skéma méja

Salah sahiji skénario umum dimana struktur méja kalayan tangkal polder kedah diasah nyaéta milih sadaya elemen anu aya di jero diréktori anu dipasihkeun. Daptar Adjacency. Pikeun nerapkeun éta dina luhureun neundeun konci-nilai, perlu nyortir konci file sareng polder ku cara anu aranjeunna dikelompokkeun dumasar kana diréktori indungna. Salaku tambahan, pikeun nampilkeun eusi diréktori dina bentuk anu wawuh ka pangguna Windows (folder heula, teras file, duanana diurutkeun sacara abjad), perlu ngalebetkeun widang tambahan anu saluyu dina konci.

Gambar di handap ieu nunjukkeun kumaha, dumasar kana tugasna, ngagambarkeun konci salaku sakumpulan bait tiasa katingali. Kahiji, bait kalawan identifier diréktori indungna (beureum) disimpen, lajeng ku tipe (héjo), sarta geus di buntut kalawan ngaran (biru). Keur diurutkeun ku standar LMDB comparator dina urutan lexicographic, aranjeunna maréntahkeun dina cara diperlukeun. Sequentially traversing konci kalayan awalan beureum sarua méré urang nilai pakait sareng aranjeunna dina urutan nu aranjeunna kedah dipintonkeun dina panganteur pamaké (katuhu), tanpa merlukeun pos-processing tambahan.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Serializing konci na nilai

Aya loba métode pikeun serializing objék di sakuliah dunya. Kusabab urang teu boga sarat séjén lian ti speed, urang milih hiji panggancangna mungkin pikeun diri urang sorangan - a dump memori dikawasaan ku hiji conto tina struktur basa C. Ku kituna, konci unsur diréktori bisa dimodelkeun ku struktur handap. NodeKey.

typedef struct NodeKey {​
    EntityId parentId;​
    uint8_t type;​
    uint8_t nameBuffer[256];​
} NodeKey;

Pikeun nyimpen NodeKey di gudang kudu di objék MDB_val posisi pointer ka data dina alamat awal struktur, sarta ngitung ukuran maranéhanana jeung fungsi sizeof.

MDB_val serialize(NodeKey * const key) {
    return MDB_val {
        .mv_size = sizeof(NodeKey),
        .mv_data = (void *)key
    };
}

Dina bab munggaran ngeunaan kriteria pamilihan database, kuring nyarios ngaminimalkeun alokasi dinamis salaku bagian tina operasi CRUD salaku faktor pamilihan anu penting. Kodeu fungsi serialize nunjukkeun kumaha, dina kasus LMDB, aranjeunna tiasa dihindari lengkep nalika rékaman énggal diselapkeun kana pangkalan data. Asép Sunandar Sunarya asup tina bait ti server mimitina robah jadi struktur tumpukan, lajeng aranjeunna trivially dumped kana gudang. Nunjukkeun yen aya ogé euweuh alokasi dinamis jero LMDB, anjeun bisa meunangkeun kaayaan hebat ku standar ios - ngagunakeun ukur tumpukan memori pikeun digawe sareng data sagala cara ti jaringan ka disk!

Mesen konci ku comparator binér

Hubungan urutan konci dirumuskeun ku fungsi husus disebut comparator a. Kusabab mesin teu terang nanaon ngeunaan semantik bait anu dikandungna, komparator standar teu gaduh pilihan tapi ngatur konci dina urutan leksikografis, nganggo perbandingan bait-by-bait. Ngagunakeun éta pikeun ngatur struktur sarua jeung cukur jeung kampak ukiran. Sanajan kitu, dina kasus basajan, kuring manggihan metoda ieu bisa ditarima. Alternatipna dijelaskeun di handap ieu, tapi di dieu kuring bakal nyatet sababaraha rake anu sumebar sapanjang jalan.

Hal kahiji anu kudu diémutan nyaéta ngagambarkeun mémori tina jinis data primitif. Janten, dina sadaya alat Apple, variabel integer disimpen dina formatna Endian Saeutik. Ieu ngandung harti yén bait pangsaeutikna signifikan bakal aya di kénca, sarta anjeun moal bisa nyortir integer ngagunakeun ngabandingkeun bait-demi-bait maranéhanana. Contona, nyobian ngalakukeun ieu kalawan susunan angka ti 0 nepi ka 511 bakal ngahasilkeun hasil handap.

// value (hex dump)
000 (0000)
256 (0001)
001 (0100)
257 (0101)
...
254 (fe00)
510 (fe01)
255 (ff00)
511 (ff01)

Pikeun ngajawab masalah ieu, integer kudu disimpen dina konci dina format cocog pikeun comparator bait. Fungsi kulawarga bakal ngabantosan ngalaksanakeun transformasi anu diperyogikeun. hton* (khususna htons pikeun angka ganda-bait tina conto).

Format pikeun ngagambarkeun string dina programming nyaeta, sakumaha anjeun terang, sakabeh dongeng. Lamun semantik string, kitu ogé encoding dipaké pikeun ngagambarkeun aranjeunna dina mémori, nunjukkeun yen meureun aya leuwih ti hiji bait per karakter, eta leuwih hade mun geuwat abandon pamanggih ngagunakeun comparator standar.

Hal kadua pikeun tetep dina pikiran prinsip alignment kompiler widang struct. Kusabab aranjeunna, bait sareng nilai sampah tiasa dibentuk dina mémori antara widang, anu, tangtosna, ngarecah asihan bait. Pikeun ngaleungitkeun sampah, anjeun kedah ngadéklarasikeun kolom dina urutan anu didefinisikeun sacara ketat, ngémutan aturan alignment, atanapi nganggo atribut dina deklarasi struktur. packed.

Urutan konci ku comparator éksternal

Logika ngabandingkeun konci tiasa janten rumit teuing pikeun komparator binér. Salah sahiji seueur alesan nyaéta ayana widang téknis di jero struktur. Kuring baris ngagambarkeun lumangsungna maranéhanana dina conto konci geus wawuh ka kami pikeun unsur diréktori.

typedef struct NodeKey {​
    EntityId parentId;​
    uint8_t type;​
    uint8_t nameBuffer[256];​
} NodeKey;

Pikeun sakabéh kesederhanaan na, dina kalolobaan kasus eta meakeun teuing memori. Judul panyangga nyaéta 256 bait, sanaos rata-rata nami file sareng folder jarang ngaleuwihan 20-30 karakter.

Salah sahiji téknik standar pikeun ngaoptimalkeun ukuran rékaman nyaéta motong éta pikeun nyocogkeun ukuranana anu sabenerna. Intina nyaéta yén eusi sadaya widang variabel-panjangna disimpen dina panyangga di tungtung struktur, sareng panjangna disimpen dina variabel anu misah. NodeKey dirobah ku cara kieu.

typedef struct NodeKey {​
    EntityId parentId;​
    uint8_t type;​
    uint8_t nameLength;​
    uint8_t nameBuffer[256];​
} NodeKey;

Saterusna, salila serialization, teu dieusian salaku ukuran data sizeof sakabéh struktur, sarta ukuran sadaya widang anu panjangna tetep ditambah ukuran bagian sabenerna dipaké panyangga nu.

MDB_val serialize(NodeKey * const key) {
    return MDB_val {
        .mv_size = offsetof(NodeKey, nameBuffer) + key->nameLength,
        .mv_data = (void *)key
    };
}

Salaku hasil tina refactoring, urang meunang hiji tabungan signifikan dina spasi dikawasaan ku kenop. Sanajan kitu, alatan widang teknis nameLength, komparator binér standar henteu cocog deui pikeun ngabandingkeun konci. Upami urang henteu ngagentos ku urang sorangan, maka panjang nami bakal janten faktor anu langkung prioritas dina asihan tibatan nami éta sorangan.

LMDB ngamungkinkeun unggal database gaduh fungsi ngabandingkeun konci sorangan. Hal ieu dilakukeun ngagunakeun fungsi mdb_set_compare mastikeun saméméh muka. Pikeun alesan atra, database teu bisa dirobah sapanjang hirupna. Dina input, komparator nampi dua konci dina format binér, sareng dina kaluaran éta ngahasilkeun hasil babandingan: kirang ti (-1), langkung ageung tibatan (1) atanapi sami (0). Pseudocode pikeun NodeKey siga kitu.

int compare(MDB_val * const a, MDB_val * const b) {​
    NodeKey * const aKey = (NodeKey * const)a->mv_data;​
    NodeKey * const bKey = (NodeKey * const)b->mv_data;​
    return // ...
}​

Salami sadaya konci dina pangkalan data tina jinis anu sami, éta sah pikeun ngawakilan bait tanpa syarat kana jinis struktur aplikasi konci. Aya hiji nuansa di dieu, tapi bakal dibahas saeutik handap dina subsection "Reading Records".

Serialisasi nilai

Kalayan konci rékaman anu disimpen, LMDB jalanna sacara intensif. Aranjeunna dibandingkeun saling dina kerangka tina sagala operasi aplikasi, sarta kinerja sakabéh solusi gumantung kana speed comparator nu. Di dunya anu idéal, komparator binér standar kedah cekap pikeun ngabandingkeun konci, tapi upami anjeun leres-leres kedah nganggo anjeun nyalira, maka prosedur pikeun deserializing konci di jerona kedah gancang-gancang.

database teu utamana kabetot dina Niley-bagian tina catetan (nilai). Konvérsi na tina répréséntasi bait ka obyék lumangsung ngan lamun eta geus diperlukeun ku kode aplikasi, contona, pikeun mintonkeun eta dina layar. Kusabab ieu jarang kajantenan, sarat pikeun laju prosedur ieu henteu kritis, sareng dina palaksanaanna kami langkung bébas museurkeun kana genah. NSKeyedArchiver.

NSData *data = serialize(object);​
MDB_val value = {​
    .mv_size = data.length,​
    .mv_data = (void *)data.bytes​
};

Nanging, aya waktos nalika kinerja penting. Contona, nalika nyimpen meta-informasi ngeunaan struktur file tina awan pamaké, kami nganggo dump memori objék sarua. Sorotan tina tugas ngahasilkeun perwakilan sérial nyaéta kanyataan yén unsur-unsur diréktori dimodelkeun ku hierarki kelas.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Pikeun palaksanaan na dina basa C, widang husus tina ahli waris dibawa kaluar kana struktur misah, sarta sambungan maranéhanana jeung dasar hiji dieusian ngaliwatan widang tipe union. Eusi sabenerna union dieusian via tipe atribut teknis.

typedef struct NodeValue {​
    EntityId localId;​
    EntityType type;​
    union {​
        FileInfo file;​
        DirectoryInfo directory;​
    } info;​
    uint8_t nameLength;​
    uint8_t nameBuffer[256];​
} NodeValue;​

Nambahkeun sareng ngapdet éntri

The serialized konci na nilai bisa ditambahkeun kana toko. Pikeun ieu, fungsina dianggo mdb_put.

// key и value имеют тип MDB_val​
mdb_put(..., &key, &value, MDB_NOOVERWRITE);

Dina tahapan konfigurasi, gudang tiasa diidinan atanapi dilarang pikeun nyimpen sababaraha rékaman sareng konci anu sami. Lamun fraying ngan bisa lumangsung salaku hasil tina kasalahan dina kode, mangka anjeun bisa nanggungkeun ka kantor asuransi ngalawan eta ku nangtukeun bandéra. NOOVERWRITE.

Rékaman bacaan

Fungsi pikeun maca rékaman dina LMDB nyaéta mdb_get. Upami pasangan konci-nilai diwakilan ku struktur anu dibuang sateuacana, maka prosedur ieu sapertos kieu.

NodeValue * const readNode(..., NodeKey * const key) {​
    MDB_val rawKey = serialize(key);​
    MDB_val rawValue;​
    mdb_get(..., &rawKey, &rawValue);​
    return (NodeValue * const)rawValue.mv_data;​
}

Listing anu disayogikeun nunjukkeun kumaha sérialisasi ngaliwatan tumpukan struktur ngamungkinkeun anjeun nyingkirkeun alokasi dinamis henteu ngan ukur nalika nyerat, tapi nalika maca data. Diturunkeun tina fungsi mdb_get pointer Sigana persis dina alamat mémori maya dimana database nyimpen ngagambarkeun bait obyék. Kanyataanna, urang meunang jenis ORM, ampir haratis nyadiakeun speed kacida luhurna maca data. Kalayan sagala kaéndahan pendekatan, anjeun kedah émut sababaraha fitur anu aya hubunganana sareng éta.

  1. Pikeun urus readonly, pointer kana struktur nilai dijamin tetep valid ngan dugi urus ditutup. Salaku nyatet saméméhna, kaca tina B-tangkal on nu obyék resides, hatur nuhun kana prinsip copy-on-write, tetep unchanged salami sahanteuna hiji urus nujul ka aranjeunna. Dina waktos anu sami, pas transaksi terakhir anu aya hubunganana sareng aranjeunna réngsé, halaman tiasa dianggo deui pikeun data énggal. Upami diperlukeun pikeun objék salamet tina transaksi anu nyiptakeunana, maka aranjeunna tetep kedah disalin.
  2. Pikeun transaksi readwrite, pointer kana struktur-nilai anu dihasilkeun bakal valid ngan nepi ka prosedur modifying munggaran (nulis atawa ngahapus data).
  3. Sanajan strukturna NodeValue teu pinuh-fledged, tapi dipangkas (tingali subsection "Mesen konci ku hiji comparator éksternal"), ngaliwatan pointer nu, anjeun bisa kalayan gampang ngakses widang na. Hal utama henteu dereference!
  4. Dina sagala hal anjeun bisa ngarobah struktur ngaliwatan pointer narima. Sadaya parobihan kedah dilakukeun ngan ukur ku cara mdb_put. Nanging, kalayan sagala kahayang pikeun ngalakukeun ieu, éta moal jalan, sabab daérah mémori dimana struktur ieu dipetakeun dina modeu ngan ukur dibaca.
  5. Remap file kana spasi alamat prosés pikeun, contona, ningkatkeun ukuran gudang maksimum ngagunakeun fungsi mdb_env_set_map_size lengkep invalidates sadaya transaksi jeung éntitas patali sacara umum jeung pointers pikeun maca objék hususna.

Tungtungna, hiji deui fitur anu jadi insidious yén panyingkepan hakekat na teu pas kana ngan hiji titik deui. Dina bab dina B-tangkal, abdi masihan diagram organisasi kaca na dina mémori. Ieu nuturkeun ti dinya yén alamat awal panyangga kalayan data serialized tiasa leres-leres wenang. Kusabab ieu, pointer ka aranjeunna, diala dina struktur MDB_val jeung tuang kana pointer kana struktur umumna unaligned. Dina waktos anu sami, arsitéktur sababaraha chip (dina kasus ios, ieu armv7) meryogikeun yén alamat data naon waé mangrupikeun sababaraha ukuran kecap mesin, atanapi, dina basa sanés, bitness sistem. (pikeun armv7, ieu 32 bit). Dina basa sejen, hiji operasi kawas *(int *foo)0x800002 on aranjeunna equated kabur sarta ngabalukarkeun palaksanaan kalawan vonis a EXC_ARM_DA_ALIGN. Aya dua cara pikeun nyingkahan nasib sedih sapertos kitu.

Anu kahiji nyaéta nyalin data kana struktur anu disaluyuan sateuacanna. Contona, dina comparator custom, ieu bakal reflected kieu.

int compare(MDB_val * const a, MDB_val * const b) {
    NodeKey aKey, bKey;
    memcpy(&aKey, a->mv_data, a->mv_size);
    memcpy(&bKey, b->mv_data, b->mv_size);
    return // ...
}

Cara alternatif nyaéta nginpokeun ka kompiler sateuacanna yén struktur sareng konci sareng nilai moal tiasa dijajarkeun nganggo atribut. aligned(1). Dina ARM pangaruh anu sami tiasa ngahontal sarta ngagunakeun atribut dipak. Tempo yén éta ogé nyumbang kana optimasi spasi dikawasaan ku struktur, metoda ieu sigana kuring leuwih hade, sanajan. приводит pikeun ngaronjatkeun biaya operasi aksés data.

typedef struct __attribute__((packed)) NodeKey {
    uint8_t parentId;
    uint8_t type;
    uint8_t nameLength;
    uint8_t nameBuffer[256];
} NodeKey;

Patarosan rentang

Pikeun iterate leuwih grup rékaman, LMDB nyadiakeun abstraksi kursor. Hayu urang tingali kumaha damel sareng éta nganggo conto tabel sareng métadata awan pangguna anu parantos wawuh ka urang.

Salaku bagian tina mintonkeun daptar payil dina diréktori, Anjeun kudu manggihan sakabeh kenop nu pakait jeung file anak na polder na. Dina subsections saméméhna, urang nyortir konci NodeKey ambéh maranéhanana kahiji maréntahkeun ku ID diréktori indungna maranéhanana. Ku kituna, sacara teknis, tugas pikeun meunangkeun eusi folder diréduksi jadi nempatkeun kursor dina wates luhur grup konci kalayan awalan dibikeun, dituturkeun ku iteration ka wates handap.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Anjeun tiasa mendakan wates luhur "dina dahi" ku milarian sequential. Jang ngalampahkeun ieu, kursor ditempatkeun di awal sakabéh daptar konci dina database lajeng incremented dugi konci kalayan identifier diréktori indungna mucunghul di handap eta. Pendekatan ieu ngagaduhan 2 kalemahan anu jelas:

  1. Pajeulitna linier pilarian, sanajan, sakumaha anjeun terang, dina tangkal umumna sarta dina B-tangkal hususna, éta bisa dipigawé dina waktu logaritmik.
  2. Sia-sia, sadaya halaman sateuacanna anu dipikahoyong diangkat tina file kana mémori utama, anu mahal pisan.

Untungna, API LMDB nyadiakeun cara efisien keur mimitina posisi kursor. Jang ngalampahkeun ieu, anjeun kudu ngabentuk konci anu nilai dipikawanoh kirang ti atawa sarua jeung konci ayana dina wates luhur interval. Contona, dina hubungan daptar dina gambar di luhur, urang tiasa ngadamel konci nu widang parentId bakal sarua jeung 2, sarta sakabeh sésana dieusian ku nol. Sapertos konci sawaréh dieusian ieu fed kana input fungsi mdb_cursor_get nunjukkeun operasi MDB_SET_RANGE.

NodeKey upperBoundSearchKey = {​
    .parentId = 2,​
    .type = 0,​
    .nameLength = 0​
};​
MDB_val value, key = serialize(upperBoundSearchKey);​
MDB_cursor *cursor;​
mdb_cursor_open(..., &cursor);​
mdb_cursor_get(cursor, &key, &value, MDB_SET_RANGE);

Lamun wates luhur grup konci kapanggih, teras urang iterate leuwih eta nepi ka boh urang papanggih atawa konci jeung nu sejen. parentId, atanapi koncina moal béak pisan.​

do {​
    rc = mdb_cursor_get(cursor, &key, &value, MDB_NEXT);​
    // processing...​
} while (MDB_NOTFOUND != rc && // check end of table​
         IsTargetKey(key));    // check end of keys group​​

Naon nice, salaku bagian tina Iteration maké mdb_cursor_get, urang meunang teu ukur konci, tapi ogé nilai. Lamun, dina raraga minuhan kaayaan seleksi, perlu mariksa, diantara hal séjén, widang tina nilai-bagian tina catetan, teras aranjeunna cukup diaksés sorangan tanpa sapuan tambahan.

4.3. Hubungan modeling antara tabel

Nepi ka ayeuna, kami geus junun mertimbangkeun sagala aspek ngarancang jeung gawé bareng database single-tabel. Urang tiasa nyebatkeun yén méja mangrupikeun sakumpulan rékaman anu diurutkeun anu diwangun ku pasangan konci-nilai tina jinis anu sami. Upami anjeun ningalikeun konci salaku sagi opat sareng nilai anu aya hubunganana salaku kotak, anjeun bakal nampi diagram visual tina pangkalan data.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Sanajan kitu, dina kahirupan nyata, éta jarang mungkin meunang ku saeutik getih. Seringna dina pangkalan data diperyogikeun, mimitina, gaduh sababaraha tabel, sareng kadua, pikeun ngalaksanakeun pilihanana dina urutan anu béda ti konci primér. Bagian panungtungan ieu devoted kana isu kreasi maranéhanana sarta interkonéksi.

tabél indéks

Aplikasi awan ngagaduhan bagian "Galeri". Ieu mintonkeun eusi media ti sakabéh awan, diurutkeun dumasar titimangsa. Pikeun palaksanaan optimal pilihan sapertos kitu, gigireun tabel utama, Anjeun kudu nyieun hiji sejen kalawan tipe anyar konci. Éta bakal ngandung widang sareng tanggal file diciptakeun, anu bakal janten kriteria asihan primér. Kusabab konci anyar ngarujuk kana data anu sami sareng konci dina tabel dasar, aranjeunna disebut konci indéks. Aranjeunna disorot dina jeruk dina gambar di handap ieu.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Pikeun misahkeun konci tabel béda ti silih dina database sarua, hiji tableId widang teknis tambahan geus ditambahkeun kana sakabéh éta. Ku nyieun prioritas pangluhurna pikeun asihan, urang bakal ngagolongkeun konci heula dumasar tabel, sarta geus di jero tabel - nurutkeun aturan urang sorangan.

Konci indéks ngarujuk kana data anu sami sareng konci primér. Palaksanaan lugas tina sipat ieu ku ngahubungkeun sareng salinan éta bagian nilai konci primér henteu optimal tina sababaraha sudut pandang sakaligus:

  1. Ti sudut pandang spasi nempatan, metadata tiasa rada euyeub.
  2. Tina sudut pandang kinerja, sabab nalika ngamutahirkeun metadata titik, anjeun kedah nimpa dua konci.
  3. Tina sudut pandang pangrojong kode, saatosna, upami urang hilap ngapdet data pikeun salah sahiji konci, urang bakal nampi bug halus tina inconsistency data dina panyimpenan.

Salajengna, urang bakal mertimbangkeun cara ngaleungitkeun kakurangan ieu.

Organisasi hubungan antara tabel

Polana cocog pikeun ngaitkeun méja indéks sareng anu utama "konci salaku nilai". Sakumaha ngaranna ngakibatkeun, bagian nilai tina catetan indéks mangrupa salinan tina nilai konci primér. Pendekatan ieu ngaleungitkeun sagala kalemahan anu didaptarkeun di luhur anu aya hubunganana sareng nyimpen salinan bagian-nilai tina rékaman primér. Hijina fee éta pikeun meunangkeun nilai ku konci indéks, Anjeun kudu nyieun 2 queries kana database tinimbang hiji. Sacara skéma, skéma database anu dihasilkeun nyaéta kieu.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Pola séjén pikeun ngatur hubungan antara tabel nyaéta "kunci kaleuleuwihan". Intina nyaéta pikeun nambihan atribut tambahan kana konci, anu diperyogikeun sanés pikeun nyortir, tapi pikeun nyiptakeun deui konci anu aya hubunganana.. Aya conto nyata pamakeanna dina aplikasi Mail.ru Cloud, kumaha oge, pikeun ngahindarkeun nyilem jero kana konteks frameworks ios husus, Kuring bakal mere hiji fiktif, tapi tapi conto leuwih kaharti.

Klién sélulér awan ngagaduhan halaman anu ningalikeun sadaya file sareng polder anu parantos dibagikeun ku pangguna ka jalma sanés. Kusabab aya rélatif sababaraha file sapertos, sareng aya seueur inpormasi khusus ngeunaan publisitas anu aya hubunganana sareng aranjeunna (ka saha aksés anu dipasihkeun, kalayan hak naon, jsb), éta moal rasional pikeun ngabeungbeuratan éta ku bagian-nilai éntri dina tabel utama. Nanging, upami anjeun hoyong nampilkeun file sapertos offline, maka anjeun tetep kedah nyimpen di mana waé. Solusi alami nyaéta nyiptakeun méja anu misah pikeun éta. Dina diagram di handap, konci na diawalan ku "P", sarta "propname" placeholder bisa diganti ku nilai leuwih husus "inpormasi umum".

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Kabéh metadata unik, demi nu tabel anyar dijieun, dipindahkeun ka bagian nilai catetan. Dina waktos anu sami, kuring henteu hoyong duplikat data ngeunaan file sareng polder anu parantos disimpen dina tabel utama. Gantina, data kaleuleuwihan ditambahkeun kana konci "P" dina bentuk widang "node ID" jeung "timestamp". Hatur nuhun ka aranjeunna, anjeun tiasa ngawangun konci indéks, dimana anjeun tiasa kéngingkeun konci primér, anu tungtungna anjeun tiasa nampi metadata tina titik.

kacindekan

Urang evaluate hasil palaksanaan LMDB positif. Saatos éta, jumlah aplikasi freezes turun ku 30%.

Kacemerlangan sareng kamiskinan LMDB pangkalan data konci-nilai dina aplikasi ios

Hasil pagawéan anu dilakukeun parantos mendakan réspon di luar tim ios. Ayeuna, salah sahiji bagian "Payil" utama dina aplikasi Android ogé parantos ngalih ka nganggo LMDB, sareng bagian-bagian sanésna nuju jalan. Basa C, dimana panyimpen nilai-konci dilaksanakeun, mangrupikeun pitulung anu saé pikeun mimitina ngajantenkeun aplikasi anu ngariung dina éta cross-platform dina basa C ++. Pikeun sambungan lancar tina perpustakaan C ++ anu dihasilkeun kalayan kode platform dina Objective-C sareng Kotlin, generator kode dianggo. Djinni ti Dropbox, tapi éta carita sejen.

sumber: www.habr.com

Tambahkeun komentar