Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Sa pagkahulog sa 2019, usa ka dugay nang gipaabot nga panghitabo ang nahitabo sa Mail.ru Cloud iOS team. Ang nag-unang database alang sa padayon nga pagtipig sa kahimtang sa aplikasyon nahimo’g labi ka lahi sa mobile nga kalibutan Database nga Mapa sa Kilat nga Memorya (LMDB). Ubos sa pagputol, ang imong pagtagad gidapit sa detalyadong pagrepaso niini sa upat ka bahin. Una, atong hisgotan ang mga rason alang sa ingon nga usa ka non-trivial ug lisud nga pagpili. Dayon magpadayon kita sa pagkonsiderar sa tulo ka mga balyena sa kasingkasing sa arkitektura sa LMDB: memory-mapped files, B + tree, copy-on-write nga pamaagi para sa pagpatuman sa transactional ug multiversioning. Sa katapusan, alang sa dessert - ang praktikal nga bahin. Niini, atong tan-awon kung giunsa ang pagdesinyo ug pagpatuman sa usa ka database schema nga adunay daghang mga lamesa, lakip ang usa ka indeks, sa ibabaw sa ubos nga lebel nga key-value API.​

Mga sulod

  1. Pagdasig sa Pagpatuman
  2. Pagpahimutang sa LMDB
  3. Tulo ka balyena LMDB
    3.1. Balyena #1. Mga file nga gi-mapa sa memorya
    3.2. Balyena #2. B+-kahoy
    3.3. Balyena #3. copy-on-write
  4. Pagdesinyo ug data schema sa ibabaw sa key-value API
    4.1. Panguna nga abstraction
    4.2. Pagmodelo sa lamesa
    4.3. Pag-modelo sa mga relasyon tali sa mga lamesa

1. Pagdasig sa pagpatuman

Kausa sa usa ka tuig, sa 2015, among giatiman ang pagkuha sa usa ka sukatan, kung unsa ka sagad ang interface sa among aplikasyon nalangan. Dili lang nato kini gibuhat. Kami adunay daghan ug daghan nga mga reklamo mahitungod sa kamatuoran nga usahay ang aplikasyon mohunong sa pagtubag sa mga aksyon sa user: ang mga buton wala gipugos, ang mga lista wala mag-scroll, ug uban pa. Mahitungod sa mga mekaniko sa pagsukod misulti sa AvitoTech, mao nga ania ako naghatag lamang sa han-ay sa mga numero.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang mga resulta sa pagsukod nahimong bugnaw nga ulan alang kanamo. Nahibal-an nga ang mga problema nga gipahinabo sa mga pag-freeze labi pa sa uban. Kung, sa wala pa makaamgo niini nga kamatuoran, ang nag-unang teknikal nga timailhan sa kalidad mao ang crash free, unya human sa focus gibalhin sa freeze free.

Nakatukod dashboard nga adunay mga freeze ug nakagasto quantitative и kalidad pagtuki sa ilang mga hinungdan, ang nag-unang kaaway nahimong tin-aw - bug-at nga negosyo lohika pagpatuman sa nag-unang hilo sa aplikasyon. Ang usa ka natural nga reaksyon sa kini nga kaulawan mao ang usa ka nagdilaab nga tinguha sa pagduso niini ngadto sa mga sapa sa trabaho. Alang sa usa ka sistematikong solusyon niini nga problema, midangop kami sa usa ka multi-threaded nga arkitektura nga gibase sa gaan nga mga aktor. Gipahinungod nako ang iyang mga adaptasyon alang sa kalibutan sa iOS duha ka hilo sa kolektibong twitter ug artikulo sa Habré. Isip kabahin sa kasamtangan nga istorya, gusto nakong hatagan og gibug-aton kadtong mga aspeto sa desisyon nga nakaimpluwensya sa pagpili sa database.​

Ang modelo sa aktor sa organisasyon sa sistema nagtuo nga ang multithreading nahimong ikaduha nga esensya. Ang mga butang nga modelo niini gusto nga motabok sa mga utlanan sa hilo. Ug gibuhat nila kini dili usahay ug sa pipila ka mga lugar, apan hapit kanunay ug bisan diin.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang database usa sa mga sangkap nga bato sa pamag-ang sa gipakita nga diagram. Ang nag-unang tahas niini mao ang pagpatuman sa usa ka macro pattern Gipaambit nga Database. Kung sa kalibutan sa negosyo kini gigamit sa pag-organisar sa pag-synchronize sa datos tali sa mga serbisyo, nan sa kaso sa arkitektura sa aktor, ang datos tali sa mga hilo. Sa ingon, kinahanglan namon ang ingon nga database, nga nagtrabaho diin sa usa ka multi-threaded nga palibot dili hinungdan bisan gamay nga mga kalisud. Sa partikular, kini nagpasabut nga ang mga butang nga nakuha gikan niini kinahanglan nga labing menos luwas sa hilo, ug labing maayo nga dili mabag-o. Sama sa imong nahibal-an, ang naulahi mahimong magamit nga dungan gikan sa daghang mga hilo nga wala mogamit sa bisan unsang matang sa mga kandado, nga adunay mapuslanon nga epekto sa pasundayag.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applicationsAng ikaduha nga hinungdanon nga hinungdan nga nakaimpluwensya sa pagpili sa database mao ang among cloud API. Giinspirar kini sa git nga pamaagi sa pag-synchronize. Sama niya nga among gitumong offline una nga API, nga tan-awon labaw pa sa angay alang sa mga kliyente sa panganod. Gituohan nga kausa ra nila ibomba ang tibuuk nga kahimtang sa panganod, ug dayon ang pag-synchronize sa kadaghanan sa mga kaso mahitabo pinaagi sa mga pagbag-o. Alaut, kini nga posibilidad anaa lamang sa theoretical zone, ug sa praktis, ang mga kliyente wala makakat-on unsaon pagtrabaho sa mga patch. Adunay ubay-ubay nga tumong nga mga rason alang niini, nga, aron dili malangan ang pagpaila, biyaan nato ang mga bracket. Karon mas makapaikag mao ang pagtudlo nga mga resulta sa leksyon mahitungod sa unsay mahitabo sa diha nga ang API miingon nga "A" ug ang konsumidor niini wala moingon "B".

Mao nga, kung mahanduraw nimo ang git, nga, kung nagpatuman sa usa ka pull command, imbis nga mag-aplay sa mga patch sa usa ka lokal nga snapshot, itandi ang tibuuk nga estado niini sa usa ka bug-os nga server, nan ikaw adunay usa ka tukma nga ideya kung giunsa ang pag-synchronize. mahitabo sa mga kliyente sa panganod. Sayon ang pagtag-an nga alang sa pagpatuman niini gikinahanglan ang paggahin sa duha ka punoan sa DOM sa memorya nga adunay meta-impormasyon bahin sa tanan nga server ug lokal nga mga file. Kini nahimo nga kung ang usa ka tiggamit magtipig sa 500 ka libo nga mga file sa panganod, unya aron ma-synchronize kini, kinahanglan nga maghimo pag-usab ug gub-on ang duha ka mga kahoy nga adunay 1 milyon nga mga node. Apan ang matag node usa ka aggregate nga adunay usa ka graph sa mga subobject. Niini nga kahayag, ang mga resulta sa profiling gilauman. Nahibal-an nga bisan kung wala gikonsiderar ang algorithm sa paghiusa, ang mismong pamaagi sa paghimo ug pagkahuman sa paglaglag sa usa ka dako nga gidaghanon sa gagmay nga mga butang nagkantidad usa ka matahum nga sentimos. sa mga script sa tiggamit. Ingon usa ka sangputanan, among giayo ang ikaduha nga hinungdanon nga sukdanan sa pagpili sa usa ka database - ang abilidad sa pagpatuman sa mga operasyon sa CRUD nga wala’y dinamikong alokasyon sa mga butang.

Ang ubang mga kinahanglanon mas tradisyonal, ug ang ilang tibuok nga listahan mao ang mosunod.

  1. Kaluwasan sa thread.
  2. Multiprocessing. Gidikta sa tinguha nga gamiton ang parehas nga database nga pananglitan aron ma-synchronize ang estado dili lamang sa taliwala sa mga hilo, apan usab sa taliwala sa panguna nga aplikasyon ug mga extension sa iOS.
  3. Ang abilidad sa pagrepresentar sa gitipigan nga mga entidad isip dili mausab nga mga butang.​
  4. Kakulang sa dinamikong alokasyon sulod sa mga operasyon sa CRUD.
  5. Suporta sa Transaksyon alang sa Basic Properties ASIDPangunang mga pulong: atomicity, pagkamakanunayon, pagkahimulag ug kasaligan.
  6. Speed ​​sa labing popular nga mga kaso.

Uban niini nga hugpong sa mga kinahanglanon, ang SQLite kaniadto ug sa gihapon usa ka maayong pagpili. Bisan pa, isip bahin sa pagtuon sa mga alternatibo, nakit-an nako ang usa ka libro "Pagsugod sa LevelDB". Ubos sa iyang pagpangulo, usa ka benchmark ang gisulat nga nagtandi sa katulin sa pagtrabaho sa lainlaing mga database sa tinuud nga mga senaryo sa panganod. Ang resulta milapas sa labing wildest gilauman. Sa labing popular nga mga kaso - pagkuha sa usa ka cursor sa usa ka sorted listahan sa tanan nga mga files ug usa ka sorted listahan sa tanan nga mga files alang sa usa ka gihatag nga direktoryo - LMDB nahimong 10 ka beses nga mas paspas kay sa SQLite. Ang pagpili nahimong klaro.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

2. LMDB Positioning

Ang LMDB usa ka librarya, gamay kaayo (10K lang nga linya), nga nagpatuman sa labing ubos nga sukaranan nga layer sa mga database - pagtipig.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang dayagram sa ibabaw nagpakita nga ang pagtandi sa LMDB sa SQLite, nga nagpatuman sa mas taas nga lebel, sa kasagaran dili mas husto kaysa SQLite nga adunay Core Data. Mas makiangayon nga hisgotan ang parehas nga mga makina sa pagtipig ingon parehas nga mga kakompetensya - BerkeleyDB, LevelDB, Sophia, RocksDB, ug uban pa. Adunay bisan mga pag-uswag diin ang LMDB naglihok ingon usa ka sangkap sa pagtipig sa makina alang sa SQLite. Ang una nga ingon nga eksperimento sa 2012 naggasto tagsulat LMDB Howard Chu. Результаты nahimo nga makaiikag kaayo nga ang iyang inisyatiba gikuha sa mga mahiligon sa OSS, ug nakit-an ang pagpadayon niini atubangan sa LumoSQL. Niadtong Enero 2020 ang tagsulat niini nga proyekto mao si Den Shearer gipresentar kini sa LinuxConfAu.

Ang panguna nga paggamit sa LMDB mao ang usa ka makina alang sa mga database sa aplikasyon. Ang librarya adunay utang sa hitsura niini sa mga nag-develop OpenLDAP, kinsa kusganong wala matagbaw sa BerkeleyDB isip basehan sa ilang proyekto. Nagduso palayo sa ubos nga librarya btree, si Howard Chu nakahimo sa paghimo sa usa sa labing inila nga mga alternatibo sa atong panahon. Iyang gigugol ang iyang bugnaw kaayong report niini nga istorya, ingon man sa internal nga istruktura sa LMDB. "Ang Lightning Memory-mapped Database". Leonid Yuriev (aka yleo) gikan sa Positive Technologies sa iyang pakigpulong sa Highload 2015 "Ang makina sa LMDB usa ka espesyal nga kampeon". Niini, naghisgot siya bahin sa LMDB sa konteksto sa parehas nga tahas sa pagpatuman sa ReOpenLDAP, ug ang LevelDB gipailalom na sa pagtandi nga pagsaway. Ingon usa ka sangputanan sa pagpatuman, ang Positive Technologies nakakuha bisan usa ka aktibo nga nag-uswag nga tinidor MDBX nga adunay lami kaayo nga mga bahin, pag-optimize ug mga pag-ayo sa bug.

Ang LMDB sagad gigamit ingon usa ka pagtipig usab. Pananglitan, ang Mozilla Firefox browser mipili kini alang sa daghang mga panginahanglan, ug, sugod sa bersyon 9, Xcode gipalabi ang SQLite niini aron tipigan ang mga indeks.

Ang makina nakuha usab sa kalibutan sa mobile development. Ang mga pagsubay sa paggamit niini mahimong sa pagpangita sa kliyente sa iOS alang sa Telegram. Ang LinkedIn mipadayon ug usa ka lakang ug mipili sa LMDB isip default storage alang sa iyang homegrown data caching framework, Rocket Data, mahitungod niini misulti sa usa ka artikulo sa 2016.

Malampuson nga nakig-away ang LMDB alang sa usa ka lugar sa adlaw sa niche nga gibiyaan sa BerkeleyDB pagkahuman sa pagbalhin sa ilawom sa kontrol sa Oracle. Gimahal ang librarya tungod sa katulin ug kasaligan niini, bisan kung itandi sa kaugalingon nga klase niini. Sama sa imong nahibal-an, wala’y libre nga paniudto, ug gusto nako nga hatagan og gibug-aton ang trade-off nga kinahanglan nimong atubangon kung magpili tali sa LMDB ug SQLite. Ang dayagram sa ibabaw tin-aw nga nagpakita kung giunsa ang pagtaas sa tulin nga nakab-ot. Una, dili kami mobayad alang sa dugang nga mga lut-od sa abstraction sa ibabaw sa disk storage. Siyempre, sa usa ka maayo nga arkitektura, dili nimo mahimo kung wala sila, ug kini dili kalikayan nga makita sa code sa aplikasyon, apan kini labi ka nipis. Wala sila'y mga bahin nga wala gikinahanglan sa usa ka piho nga aplikasyon, pananglitan, suporta alang sa mga pangutana sa SQL nga pinulongan. Ikaduha, mahimo’g posible nga ma-optimize nga ipatuman ang pagmapa sa mga operasyon sa aplikasyon sa mga hangyo sa pagtipig sa disk. Kung ang SQLite sa akong trabaho gikan sa kasagaran nga mga panginahanglan sa usa ka kasagaran nga aplikasyon, unya ikaw, isip usa ka developer sa aplikasyon, nahibal-an pag-ayo ang mga nag-unang mga senaryo sa pagkarga. Para sa mas produktibo nga solusyon, kinahanglan kang mobayad ug dugang nga tag sa presyo para sa pag-uswag sa inisyal nga solusyon ug sa sunod nga suporta niini.

3. Tulo ka balyena LMDB

Human matan-aw ang LMDB gikan sa panan-aw sa langgam, panahon na aron mas lawom pa. Ang sunod nga tulo ka mga seksyon igahin sa pag-analisar sa mga nag-unang mga balyena diin ang arkitektura sa pagtipig nagsalig:

  1. Ang memory-mapped nga mga file isip mekanismo sa pagtrabaho sa disk ug pag-synchronize sa internal nga mga istruktura sa datos.
  2. B+-tree isip usa ka organisasyon sa gitipigan nga istruktura sa datos.
  3. Copy-on-write isip pamaagi sa paghatag ug ACID transactional properties ug multiversioning.

3.1. Balyena #1. Mga file nga gi-mapa sa memorya

Ang memory-mapped nga mga file usa ka importante nga elemento sa arkitektura nga kini makita pa sa ngalan sa repository. Ang mga isyu sa pag-cache ug pag-synchronize sa pag-access sa gitipigan nga kasayuran hingpit nga naa sa kaluoy sa operating system. Ang LMDB walay bisan unsang mga cache sulod sa iyang kaugalingon. Kini usa ka mahunahunaon nga desisyon sa tagsulat, tungod kay ang pagbasa sa mga datos nga direkta gikan sa mga mapa nga mga file nagtugot kanimo sa pagputol sa daghang mga kanto sa pagpatuman sa makina. Sa ubos mao ang layo sa kompletong listahan sa pipila niini.

  1. Ang pagpadayon sa pagkamakanunayon sa datos sa pagtipig kung nagtrabaho uban niini gikan sa daghang mga proseso nahimo nga responsibilidad sa operating system. Sa sunod nga seksyon, kini nga mekaniko gihisgutan sa detalye ug adunay mga litrato.
  2. Ang pagkawala sa mga cache hingpit nga makapahupay sa LMDB sa overhead nga may kalabutan sa dinamikong mga alokasyon. Ang pagbasa sa datos sa praktis mao ang pagtakda sa pointer sa husto nga adres sa virtual memory ug wala na. Morag pantasya, apan sa tinubdan sa repository, ang tanang tawag sa calloc gikonsentrar sa function sa configuration sa repository.
  3. Ang pagkawala sa mga cache nagpasabot usab sa pagkawala sa mga kandado nga may kalabutan sa pag-synchronize aron ma-access kini. Ang mga magbabasa, diin ang usa ka arbitraryong numero mahimong maglungtad sa parehas nga oras, dili makasugat og usa ka mutex sa ilang pagpaingon sa datos. Tungod niini, ang katulin sa pagbasa adunay usa ka sulundon nga linear scalability sa mga termino sa gidaghanon sa mga CPU. Sa LMDB, ang pag-usab lang sa mga operasyon ang gi-synchronize. Mahimong usa ra ang magsusulat matag higayon.
  4. Ang usa ka minimum nga caching ug synchronization logic nagluwas sa code gikan sa usa ka hilabihan ka komplikado nga matang sa mga sayup nga may kalabutan sa pagtrabaho sa usa ka multi-threaded nga palibot. Adunay duha ka makapaikag nga mga pagtuon sa database sa komperensya sa Usenix OSDI 2014: "Ang Tanan nga Sistema sa File Dili Gibuhat nga Parehas: Sa Pagkakomplikado sa Pag-craft-Consistent nga mga Aplikasyon" и Pagsakit sa mga Database para sa Kalingawan ug Kita. Gikan kanila mahimo nimong makuha ang kasayuran bahin sa wala pa nakit-an nga kasaligan sa LMDB, ug ang hapit wala’y sayup nga pagpatuman sa mga kabtangan sa ACID sa mga transaksyon, nga milabaw niini sa parehas nga SQLite.
  5. Ang minimalism sa LMDB nagtugot sa representasyon sa makina sa code niini nga hingpit nga ibutang sa L1 cache sa processor nga adunay resulta nga mga kinaiya sa tulin.

Ikasubo, sa iOS, ang memory-mapped nga mga file dili sama ka rosy sa gusto namon. Sa paghisgot mahitungod sa mga disadvantages nga may kalabutan sa kanila nga mas mahunahunaon, gikinahanglan nga hinumdoman ang kinatibuk-ang mga prinsipyo sa pagpatuman niini nga mekanismo sa mga operating system.

Kinatibuk-ang impormasyon bahin sa memory-mapped files

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applicationsSa matag executable nga aplikasyon, ang operating system nag-associate sa usa ka entidad nga gitawag og proseso. Ang matag proseso gigahin usa ka magkadugtong nga mga adres diin gibutang niini ang tanan nga kinahanglan aron molihok. Ang pinakaubos nga mga adres adunay mga seksyon nga adunay code ug hardcoded data ug mga kapanguhaan. Sunod moabut ang pataas-nag-uswag nga bloke sa dinamikong espasyo sa adres, nga nailhan namo nga heap. Naglangkob kini sa mga adres sa mga entidad nga makita sa panahon sa operasyon sa programa. Sa ibabaw mao ang dapit sa memorya nga gigamit sa application stack. Kini motubo o mokunhod, sa laing pagkasulti, ang gidak-on niini adunay dinamikong kinaiya. Aron ang stack ug heap dili magduso ug makabalda sa usag usa, sila gibulag sa lain-laing mga tumoy sa address space.Adunay usa ka lungag tali sa duha ka dinamikong mga seksyon sa ibabaw ug sa ubos. Ang mga adres niini nga tungatunga nga seksyon gigamit sa operating system aron makig-uban sa usa ka proseso sa lainlaing mga entidad. Sa partikular, mahimo kini nga mapa ang usa ka padayon nga set sa mga adres sa usa ka file sa disk. Ang ingon nga file gitawag nga memory-mapped file.​

Dako ang address space nga gigahin sa usa ka proseso. Sa teoriya, ang gidaghanon sa mga adres limitado lamang sa gidak-on sa pointer, nga gitino sa bitness sa sistema. Kung ang pisikal nga panumduman gi-assign niini nga 1-in-1, nan ang una nga proseso mokaon sa tibuuk nga RAM, ug wala’y pangutana sa bisan unsang multitasking.

Bisan pa, nahibal-an namon gikan sa kasinatian nga ang mga modernong operating system mahimong magpadagan sa daghang mga proseso nga gusto nimo sa parehas nga oras. Posible kini tungod sa kamatuoran nga naggahin sila og daghang panumduman sa mga proseso lamang sa papel, apan sa tinuud ilang gikarga sa panguna nga pisikal nga panumduman lamang ang bahin nga gipangayo dinhi ug karon. Busa, ang panumduman nga nalangkit sa proseso gitawag nga virtual.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang operating system nag-organisar sa virtual ug pisikal nga panumduman ngadto sa mga panid sa usa ka piho nga gidak-on. Sa diha nga ang usa ka piho nga panid sa virtual nga panumduman gikinahanglan, ang operating system nagkarga niini sa pisikal nga panumduman ug nagbutang sa usa ka sulat tali kanila sa usa ka espesyal nga lamesa. Kung wala’y libre nga mga slot, nan ang usa sa na-load kaniadto nga mga panid gikopya sa disk, ug ang gihangyo mopuli niini. Kini nga pamaagi, nga atong balikan sa dili madugay, gitawag nga swapping. Ang hulagway sa ubos naghulagway sa gihulagway nga proseso. Diha niini, ang panid A nga adunay adres 0 gikarga ug gibutang sa main memory page nga adunay adres 4. Kini nga kamatuoran makita diha sa talaan sa mga sulat sa cell number 0.​

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Uban sa memory-mapped nga mga file, ang istorya parehas ra. Sa lohikal nga paagi, sila kuno padayon ug hingpit nga gibutang sa virtual address space. Bisan pa, nakasulod sila sa pisikal nga panumduman nga panid sa panid ug kung gipangayo lamang. Ang pagbag-o sa ingon nga mga panid gi-synchronize sa file sa disk. Sa ingon, mahimo nimong buhaton ang file I / O, yano nga nagtrabaho gamit ang mga byte sa memorya - ang tanan nga mga pagbag-o awtomatiko nga ibalhin sa kernel sa operating system sa orihinal nga file.​

Gipakita sa hulagway sa ubos kung giunsa pag-synchronize sa LMDB ang kahimtang niini kung nagtrabaho kauban ang database gikan sa lainlaing mga proseso. Pinaagi sa pagmapa sa virtual nga panumduman sa lain-laing mga proseso ngadto sa samang file, de facto mi obligado sa operating system sa transitively nga pag-synchronize sa pipila ka mga bloke sa ilang mga address space sa usag usa, diin ang hitsura sa LMDB.​

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang usa ka importante nga nuance mao nga ang LMDB nag-usab sa data file pinaagi sa default pinaagi sa write system call mechanism, ug ang file mismo nagpakita sa read-only mode. Kini nga pamaagi adunay duha ka importante nga implikasyon.

Ang una nga sangputanan kasagaran sa tanan nga mga operating system. Ang esensya niini mao ang pagdugang proteksyon batok sa wala tuyoa nga kadaot sa database pinaagi sa sayop nga code. Sama sa imong nahibal-an, ang mga executable nga instruksyon sa usa ka proseso libre sa pag-access sa data gikan sa bisan asa sa iyang address space. Sa parehas nga oras, sama sa among nahinumduman, ang pagpakita sa usa ka file sa read-write mode nagpasabut nga ang bisan unsang panudlo mahimo usab nga usbon kini dugang. Kung nahimo niya kini nga sayup, pagsulay, pananglitan, sa aktuwal nga pag-overwrite sa usa ka elemento sa array sa usa ka wala nga indeks, nan sa ingon niini nga paagi mahimo niyang aksidente nga mabag-o ang file nga na-mapa sa kini nga adres, nga mosangput sa korapsyon sa database. Kung ang file gipakita sa read-only mode, nan ang pagsulay sa pag-usab sa address space nga katumbas niini mosangpot sa pagkahagsa sa programa nga adunay signal SIGSEGV, ug ang file magpabilin nga wala.

Ang ikaduha nga sangputanan piho na sa iOS. Ni ang tagsulat o ang bisan unsang ubang mga tinubdan klaro nga naghisgot niini, apan kung wala kini, ang LMDB dili angay alang sa pagdagan sa kini nga mobile operating system. Ang sunod nga seksyon gipahinungod sa konsiderasyon niini.

Mga espesipiko sa memory-mapped nga mga file sa iOS

Sa 2018, adunay nindot nga report sa WWDC iOS Memory Deep Dive. Gisulti niini nga sa iOS ang tanan nga mga panid nga nahimutang sa pisikal nga panumduman nahisakop sa usa sa 3 nga mga tipo: hugaw, compressed ug limpyo.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang limpyo nga memorya usa ka koleksyon sa mga panid nga luwas nga mapalitan gikan sa pisikal nga panumduman. Ang datos nga anaa niini mahimong i-reload gikan sa ilang orihinal nga mga tinubdan kung gikinahanglan. Ang read-only nga memory-mapped nga mga file nahisakop niini nga kategoriya. Ang iOS dili mahadlok nga idiskarga ang mga panid nga gimapa sa usa ka file gikan sa memorya bisan unsang orasa, tungod kay gigarantiyahan sila nga ma-synchronize sa file sa disk.

Ang tanan nga giusab nga mga panid mosulod sa hugaw nga panumduman, bisan asa sila orihinal nga nahimutang. Sa partikular, ang memory-mapped nga mga file nga giusab pinaagi sa pagsulat ngadto sa virtual nga panumduman nga may kalabutan niini pagaklasipikar usab niining paagiha. Pag-abli sa LMDB nga adunay bandila MDB_WRITEMAP, human sa paghimog mga kausaban niini, imong makita sa imong kaugalingon.​

Sa diha nga ang usa ka aplikasyon magsugod sa pagkuha sa sobra nga pisikal nga panumduman, ang iOS mag-compress sa iyang hugaw nga mga panid. Ang koleksyon sa memorya nga giokupar sa hugaw ug compressed nga mga panid mao ang gitawag nga memory footprint sa aplikasyon. Kung moabot kini sa usa ka piho nga kantidad sa threshold, ang OOM killer system nga daemon moabut pagkahuman sa proseso ug pugson nga tapuson kini. Kini mao ang peculiarity sa iOS itandi sa desktop operating system. Sa kasukwahi, ang pagpaubos sa memory footprint pinaagi sa pagbaylo sa mga panid gikan sa pisikal nga memorya ngadto sa disk wala gihatag sa iOS. Makatag-an ra ang usa bahin sa mga hinungdan. Tingali ang pamaagi alang sa intensive nga pagbalhin sa mga panid ngadto sa disk ug balik sobra ka kusog nga nag-usik alang sa mga mobile device, o ang iOS nagtipig sa kapanguhaan sa pagsulat pag-usab sa mga selula sa SSD drive, o tingali ang mga tigdesinyo wala matagbaw sa kinatibuk-ang performance sa sistema, diin ang tanan anaa. kanunay gipalitan. Bisan unsa pa, ang kamatuoran nagpabilin.

Ang maayong balita, nga nahisgotan na sa sayo pa, mao nga ang LMDB wala mogamit sa mmap nga mekanismo sa default sa pag-update sa mga file. Nagsunod kini nga ang gihatag nga datos giklasipikar nga limpyo nga memorya sa iOS ug wala makatampo sa footprint sa memorya. Mahimo kining mapamatud-an gamit ang Xcode tool nga gitawag og VM Tracker. Ang screenshot sa ubos nagpakita sa kahimtang sa virtual nga memorya sa iOS Cloud nga aplikasyon sa panahon sa operasyon. Sa pagsugod, 2 ka mga higayon sa LMDB ang gisugdan niini. Ang una gitugotan nga mapa ang file niini sa 1GiB nga virtual memory, ang ikaduha - 512MiB. Bisan pa sa kamatuoran nga ang duha nga mga tipiganan nag-okupar sa usa ka piho nga kantidad sa panumduman sa residente, walay usa kanila nga nakatampo sa hugaw nga gidak-on.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Karon na ang panahon sa dili maayong balita. Salamat sa mekanismo sa swap sa 64-bit nga mga operating system sa desktop, ang matag proseso mahimong mokuha ug daghang virtual address space sama sa gitugot sa libre nga espasyo sa hard disk alang sa potensyal nga swap niini. Ang pag-ilis sa swap sa compression sa iOS makapakunhod pag-ayo sa theoretical maximum. Karon ang tanan nga buhi nga mga proseso kinahanglan nga mohaum sa panguna (basaha ang RAM) nga panumduman, ug ang tanan nga dili angay ipailalom sa pinugos nga pagtapos. Gihisgotan kini sama sa naa sa ibabaw pagtaho, ug sa opisyal nga dokumentasyon. Ingon usa ka sangputanan, ang iOS grabe nga naglimite sa gidaghanon sa memorya nga magamit alang sa alokasyon pinaagi sa mmap. Dinhi dinhi mahimo nimong tan-awon ang empirical nga mga limitasyon sa gidaghanon sa memorya nga mahimong igahin sa lain-laing mga himan gamit kini nga sistema sa tawag. Sa pinakabag-o nga mga modelo sa mga smartphone, ang iOS nahimong manggihatagon sa 2 gigabytes, ug sa ibabaw nga mga bersyon sa iPad - sa 4. Sa praktis, siyempre, kinahanglan ka nga mag-focus sa pinakabata nga gisuportahan nga mga modelo sa device, diin ang tanan masulub-on kaayo. Mas grabe pa, sa pagtan-aw sa kahimtang sa panumduman sa aplikasyon sa VM Tracker, imong makita nga ang LMDB layo sa usa nga nag-angkon nga memory-mapped nga memorya. Ang maayo nga mga tipak gikaon sa mga tigtagana sa sistema, mga file sa kapanguhaan, mga balangkas sa imahe, ug uban pang gagmay nga mga manunukob.

Base sa mga resulta sa mga eksperimento sa Cloud, nakaabot kami sa mosunod nga mga kantidad sa kompromiso sa memorya nga gigahin sa LMDB: 384 megabytes alang sa 32-bit nga mga himan ug 768 alang sa 64-bit nga mga device. Human magamit kini nga volume, ang bisan unsang pag-usab nga mga operasyon magsugod sa pagkompleto sa code MDB_MAP_FULL. Naobserbahan namon ang ingon nga mga sayup sa among pag-monitor, apan kini gamay ra aron mapasagdan sa kini nga yugto.

Ang usa ka dili klaro nga hinungdan sa sobra nga pagkonsumo sa panumduman pinaagi sa pagtipig mahimong dugay nga mga transaksyon. Aron masabtan kon sa unsang paagi nalangkit kining duha ka panghitabo, kini makatabang kanato sa pagkonsiderar sa nahibiling duha ka LMDB whale.

3.2. Balyena #2. B+-kahoy

Aron masundog ang mga lamesa sa ibabaw sa usa ka yawe nga bili nga tindahan, ang mosunod nga mga operasyon kinahanglang anaa sa API niini:

  1. Pagsal-ot og bag-ong elemento.
  2. Pangitaa ang usa ka elemento nga adunay gihatag nga yawe.
  3. Pagtangtang sa usa ka elemento.
  4. Pag-uli sa mga yawe nga agwat sa ilang pagkasunud-sunod.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applicationsAng pinakasimple nga istruktura sa datos nga dali nga makapatuman sa tanan nga upat ka mga operasyon mao ang usa ka binary search tree. Ang matag usa sa mga node niini usa ka yawe nga nagbahin sa tibuuk nga subset sa mga yawe sa bata sa duha nga mga subtree. Sa wala mao ang mga mas gamay kay sa ginikanan, ug sa tuo - ang mga mas dako. Ang pag-angkon og usa ka ordered set sa mga yawe makab-ot pinaagi sa usa sa mga classic tree traversals

Ang binary nga mga kahoy adunay duha ka sukaranan nga mga kakulangan nga nagpugong kanila nga mahimong epektibo ingon usa ka istruktura sa data sa disk. Una, ang lebel sa ilang balanse dili matag-an. Adunay usa ka igo nga peligro sa pagkuha sa mga kahoy diin ang gitas-on sa lainlaing mga sanga mahimong magkalainlain, nga labi nga nagpalala sa pagkakomplikado sa algorithm sa pagpangita kung itandi sa gipaabut. Ikaduha, ang kadagaya sa cross-links tali sa mga node naghikaw sa binary trees sa lokalidad sa memorya. Ingon usa ka sangputanan, bisan ang usa ka yano nga pag-agi sa daghang kasikbit nga mga node sa usa ka punoan mahimo’g kinahanglan nga bisitahan ang parehas nga gidaghanon sa mga panid. Kini usa ka problema bisan kung maghisgot kita bahin sa kaepektibo sa mga binary nga punoan ingon usa ka istruktura sa datos sa memorya, tungod kay ang kanunay nga pag-rotate sa mga panid sa cache sa processor dili barato. Kung bahin sa kanunay nga pagpataas sa mga panid nga may kalabotan sa node gikan sa disk, ang mga butang mahimong daotan. makaluluoy.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applicationsAng mga B-tree, nga usa ka ebolusyon sa binary tree, nagsulbad sa mga problema nga nahibal-an sa miaging parapo. Una, sila nagbalanse sa kaugalingon. Ikaduha, ang matag usa sa ilang mga node nagbahin sa set sa mga yawe sa bata dili sa 2, apan sa gimando nga M nga mga subset, ug ang numero nga M mahimong dako, sa pagkasunud-sunod sa pila ka gatos o bisan libu.

Sa ingon:

  1. Ang matag node adunay daghang gidaghanon sa na-order na nga mga yawe ug ang mga kahoy ubos kaayo.
  2. Nakuha sa kahoy ang kabtangan sa lokalidad sa panumduman, tungod kay ang mga yawe nga duol sa kantidad natural nga nahimutang tapad sa usag usa sa usa o kasikbit nga mga node.
  3. Gipamub-an ang gidaghanon sa mga transit node sa pagkanaog sa kahoy atol sa operasyon sa pagpangita.
  4. Gipakunhod ang gidaghanon sa mga target nga node nga gibasa alang sa mga pangutana sa range, tungod kay ang matag usa niini adunay daghan na nga gimando nga mga yawe.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Gigamit sa LMDB ang usa ka variant sa B-tree nga gitawag og B+ tree aron magtipig og datos. Ang dayagram sa ibabaw nagpakita sa tulo ka matang sa mga node nga anaa niini:

  1. Sa ibabaw mao ang gamut. Wala’y nahimo nga labi pa sa konsepto sa usa ka database sa sulod sa usa ka tipiganan. Sulod sa usa ka pananglitan sa LMDB, makahimo ka og daghang mga database nga nag-ambit sa gimapa nga virtual address space. Ang matag usa kanila nagsugod gikan sa kaugalingon nga gamut.
  2. Sa labing ubos nga lebel mao ang mga dahon (dahon). Kini sila ug sila ra ang adunay sulud nga mga pares sa yawe nga kantidad nga gitipigan sa database. Pinaagi sa dalan, kini mao ang peculiarity sa B+-mga kahoy. Kung ang usa ka normal nga B-tree nagtipig sa mga bahin sa kantidad sa mga node sa tanan nga lebel, nan ang B + -variation anaa ra sa labing ubos. Sa pag-ayo niini nga kamatuoran, sa mosunod tawgon nato ang subtype sa kahoy nga gigamit sa LMDB nga usa lang ka B-tree.
  3. Sa tunga-tunga sa gamut ug mga dahon, adunay 0 o labaw pa nga teknikal nga lebel nga adunay nabigasyon (sanga) nga mga buko. Ang ilang tahas mao ang pagbahin sa mga hut-ong sa mga yawe taliwala sa mga dahon.

Sa pisikal, ang mga node maoy mga bloke sa memorya sa gitino nang daan nga gitas-on. Ang ilang gidak-on usa ka multiple sa gidak-on sa mga panid sa panumduman sa operating system, nga among gihisgutan sa ibabaw. Ang istruktura sa node gipakita sa ubos. Ang ulohan adunay meta-impormasyon, ang labing klaro nga, pananglitan, mao ang checksum. Sunod moabut ang impormasyon bahin sa mga offset, diin nahimutang ang mga cell nga adunay data. Ang papel sa datos mahimong mga yawe, kung maghisgot kita bahin sa navigation nodes, o tibuok key-value pairs sa kaso sa mga dahon. Makabasa ka og dugang mahitungod sa istruktura sa mga panid sa trabaho "Ebalwasyon sa High Performance Key-Value Stores".

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Sa pag-atubang sa internal nga sulod sa mga node sa panid, kita dugang nga magrepresentar sa LMDB B-tree sa gipasimple nga paagi sa mosunod nga porma.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang mga panid nga adunay mga node sunodsunod nga gihan-ay sa disk. Ang mga panid nga adunay mas taas nga numero nahimutang sa katapusan sa file. Ang gitawag nga meta page (meta page) adunay impormasyon bahin sa mga offset, nga magamit sa pagpangita sa mga gamot sa tanang kahoy. Kung giablihan ang usa ka file, gi-scan sa LMDB ang panid sa file pinaagi sa panid gikan sa katapusan hangtod sa sinugdanan sa pagpangita sa usa ka balido nga panid sa meta ug nakit-an ang naglungtad nga mga database pinaagi niini.​

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Karon, nga adunay ideya sa lohikal ug pisikal nga istruktura sa organisasyon sa datos, mahimo naton ipadayon ang paghunahuna sa ikatulo nga balyena sa LMDB. Uban sa tabang niini nga ang tanan nga mga pagbag-o sa pagtipig mahitabo sa transaksyon ug sa pag-inusara gikan sa usag usa, nga naghatag sa database sa kinatibuk-an usab ang multiversion nga kabtangan.

3.3. Balyena #3. copy-on-write

Ang ubang mga operasyon sa B-tree naglakip sa paghimo sa tibuok serye sa mga kausaban sa mga buko niini. Usa ka pananglitan mao ang pagdugang og bag-ong yawe sa usa ka node nga nakaabot na sa kinatas-ang kapasidad niini. Sa kini nga kaso, gikinahanglan, una, nga bahinon ang node sa duha, ug ikaduha, aron idugang ang usa ka link sa bag-ong spun off nga node sa bata sa ginikanan niini. Kini nga pamaagi mahimong peligroso kaayo. Kung sa usa ka hinungdan (crash, pagkawala sa kuryente, ug uban pa) usa ra ka bahin sa mga pagbag-o gikan sa serye ang mahitabo, nan ang kahoy magpabilin sa usa ka dili managsama nga kahimtang.

Usa ka tradisyonal nga solusyon sa paghimo sa usa ka database fault-tolerant mao ang pagdugang sa usa ka dugang nga disk-based data structure, ang transaction log, nailhan usab nga write-ahead log (WAL), sunod sa B-tree. Kini usa ka file, sa katapusan niini, sa wala pa ang pagbag-o sa B-tree mismo, gisulat ang gituyo nga operasyon. Busa, kung ang data corruption mamatikdan sa panahon sa self-diagnosis, ang database mokonsulta sa log aron sa paglimpyo sa iyang kaugalingon.

Nagpili ang LMDB og lahi nga pamaagi isip mekanismo sa pagtugot sa sayup, nga gitawag nga copy-on-write. Ang esensya niini mao nga imbes nga i-update ang datos sa usa ka naglungtad nga panid, una nga kopyahon kini sa hingpit ug himuon ang tanan nga mga pagbag-o nga naa na sa kopya.​

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Dugang pa, aron magamit ang na-update nga datos, kinahanglan nga usbon ang link sa node nga nahimong labing bag-o sa node sa ginikanan nga may kalabotan niini. Tungod kay kini kinahanglan usab nga usbon alang niini, kini usab pre-kopya. Ang proseso nagpadayon nga balikbalik hangtod sa gamut. Ang datos sa meta page mao ang kataposang giusab.​​

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Kung ang proseso kalit nga nahagsa sa panahon sa pamaagi sa pag-update, nan ang usa ka bag-ong panid sa meta dili mahimo, o kini dili isulat sa disk hangtod sa katapusan, ug ang checksum niini dili husto. Sa bisan hain niining duha ka kaso, ang bag-ong mga panid dili maabot ug ang mga daan dili maapektuhan. Giwagtang niini ang panginahanglan alang sa LMDB nga magsulat sa unahan nga log aron mapadayon ang pagkamakanunayon sa datos. De facto, ang istruktura sa pagtipig sa datos sa disk, nga gihulagway sa ibabaw, dungan nga naglihok niini. Ang pagkawala sa usa ka tin-aw nga log sa transaksyon mao ang usa sa mga bahin sa LMDB, nga naghatag taas nga katulin sa pagbasa sa datos.​

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang resulta nga konstruksyon, nga gitawag og append-only B-tree, natural nga naghatag ug transaction isolation ug multiversioning. Sa LMDB, ang matag bukas nga transaksyon adunay pinakabag-o nga punoan sa kahoy nga nalangkit niini. Hangtud nga ang transaksyon dili makompleto, ang mga panid sa kahoy nga nalangkit niini dili na mausab o magamit pag-usab alang sa bag-ong mga bersyon sa datos. Sa ingon, mahimo ka nga magtrabaho kutob sa imong gusto nga eksakto sa set sa datos nga may kalabutan sa oras nga giablihan ang transaksyon, bisan kung ang pagtipig nagpadayon nga aktibo nga gi-update karong panahona. Kini ang esensya sa multiversioning, nga naghimo sa LMDB nga usa ka sulundon nga gigikanan sa datos alang sa among minahal UICollectionView. Ang pag-abli sa usa ka transaksyon, dili nimo kinahanglan nga dugangan ang memorya sa footprint sa aplikasyon, nga nagdali sa pagbomba sa kasamtangan nga datos ngadto sa pipila ka in-memorya nga istruktura, nga nahadlok nga mabiyaan nga wala. Kini nga bahin nagpalahi sa LMDB gikan sa parehas nga SQLite, nga dili makapanghambog sa ingon nga kinatibuk-ang pagkahimulag. Ang pag-abli sa duha ka mga transaksyon sa ulahi ug pagtangtang sa usa ka piho nga rekord sa sulod sa usa niini, ang parehas nga rekord dili na makuha sa ikaduha nga nahabilin.

Ang pikas nga bahin sa sensilyo mao ang posibleng mas taas nga konsumo sa virtual memory. Gipakita sa slide kung unsa ang hitsura sa istruktura sa database kung kini giusab sa parehas nga oras nga adunay 3 nga bukas nga pagbasa nga mga transaksyon nga nagtan-aw sa lainlaing mga bersyon sa database. Tungod kay ang LMDB dili makagamit pag-usab sa mga node nga maabot gikan sa mga ugat nga nalangkit sa aktuwal nga mga transaksyon, ang storage walay kapilian gawas sa paggahin ug laing ikaupat nga ugat sa memorya ug sa makausa pa i-clone ang giusab nga mga panid ubos niini.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Dinhi dili kinahanglan nga hinumdoman ang seksyon sa mga file nga gi-mapa sa memorya. Ingon og ang dugang nga pagkonsumo sa virtual nga panumduman kinahanglan dili makahasol kanamo, tungod kay wala kini makatampo sa footprint sa panumduman sa aplikasyon. Bisan pa, sa parehas nga oras, nahibal-an nga ang iOS grabe kaayo sa paggahin niini, ug dili kami makahatag usa ka 1 terabyte nga rehiyon sa LMDB sa usa ka server o desktop gikan sa abaga sa agalon ug wala gyud maghunahuna bahin sa kini nga bahin. Kung mahimo, kinahanglan nimong sulayan nga huptan nga mubo ang kinabuhi sa mga transaksyon kutob sa mahimo.

4. Pagdesinyo ug data schema sa ibabaw sa key-value API

Atong sugdan ang pag-parse sa API pinaagi sa pagtan-aw sa mga batakang abstraction nga gihatag sa LMDB: palibot ug mga database, mga yawe ug mga bili, mga transaksyon ug mga cursor.

Usa ka nota bahin sa mga listahan sa code

Ang tanan nga mga gimbuhaton sa LMDB public API nagbalik sa resulta sa ilang trabaho sa porma sa usa ka error code, apan sa tanan nga sunod-sunod nga mga listahan ang tseke niini wala iapil tungod sa pagkamubo.Sa praktis, gigamit namo ang among kaugalingong code aron makig-uban sa repositoryo. tinidor C++ wrapper lmdbxx, diin ang mga kasaypanan mahitabo isip mga eksepsiyon sa C++.

Isip labing paspas nga paagi sa pagkonektar sa LMDB sa usa ka proyekto sa iOS o macOS, akong gitanyag ang akong CocoaPod POSLMDB.

4.1. Panguna nga abstraction

Kalibutan

gambalay MDB_env mao ang repository sa internal nga kahimtang sa LMDB. Pamilya sa prefixed functions mdb_env nagtugot kanimo sa pag-configure sa pipila sa mga kabtangan niini. Sa pinakasimple nga kaso, ang pagsugod sa makina ingon niini.

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

Sa aplikasyon sa Mail.ru Cloud, gibag-o namon ang mga default nga kantidad alang sa duha ra nga mga parameter.

Ang una mao ang gidak-on sa virtual address space diin ang storage file gimapa. Ikasubo, bisan sa parehas nga aparato, ang piho nga kantidad mahimong magkalainlain gikan sa pagdagan hangtod sa pagdagan. Aron mahunahuna kini nga bahin sa iOS, gipili namon ang labing kadaghan nga pagtipig sa dinamikong paagi. Sugod gikan sa usa ka piho nga kantidad, kini sunud-sunod nga natunga hangtod sa function mdb_env_open dili mubalik ug resulta gawas sa ENOMEM. Sa teorya, adunay usa ka kaatbang nga paagi - una nga igahin ang usa ka minimum nga memorya sa makina, ug dayon, kung ang mga sayup madawat MDB_MAP_FULL, dugangi kini. Bisan pa, kini labi ka tunok. Ang hinungdan mao nga ang pamaagi alang sa pag-remapping sa memorya gamit ang function mdb_env_set_map_size dili balido ang tanan nga mga entidad (mga cursor, mga transaksyon, mga yawe ug mga kantidad) nga nadawat gikan sa makina sa sayo pa. Ang pag-asoy sa ingon nga pagbag-o sa mga panghitabo sa code magdala sa hinungdanon nga komplikasyon. Kung, bisan pa, ang virtual nga panumduman mahal kaayo kanimo, nan mahimo’g kini usa ka hinungdan nga tan-awon ang tinidor nga nag-una. MDBX, diin taliwala sa gideklarar nga mga bahin adunay "awtomatikong on-the-fly database size adjustment".

Ang ikaduha nga parameter, ang default nga kantidad nga dili angay kanamo, nag-regulate sa mga mekaniko sa pagsiguro sa kaluwasan sa hilo. Ikasubo, labing menos sa iOS 10, adunay mga problema sa suporta sa lokal nga pagtipig sa thread. Tungod niini nga rason, sa panig-ingnan sa ibabaw, ang repository giablihan sa bandila MDB_NOTLS. Dugang pa, gikinahanglan usab kini tinidor C++ wrapper lmdbxxsa pagputol sa mga baryable nga adunay ug niini nga hiyas.

Mga database

Ang database usa ka lahi nga pananglitan sa B-tree nga among gihisgutan sa ibabaw. Ang pag-abli niini mahitabo sa sulod sa usa ka transaksyon, nga sa sinugdan daw medyo katingad-an.

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);

Sa tinuud, ang usa ka transaksyon sa LMDB usa ka entidad sa pagtipig, dili usa ka piho nga database. Kini nga konsepto nagtugot kanimo sa paghimo sa atomic nga mga operasyon sa mga entidad nga nahimutang sa lain-laing mga database. Sa teorya, kini nagbukas sa posibilidad sa pagmodelo sa mga lamesa sa porma sa lainlaing mga database, apan sa usa ka higayon miadto ako sa laing paagi, nga gihulagway sa detalye sa ubos.

Mga yawe ug mithi

gambalay MDB_val nagmodelo sa konsepto sa usa ka yawe ug usa ka bili. Ang repository walay ideya bahin sa ilang mga semantika. Alang kaniya, ang usa ka butang nga lahi usa ra ka han-ay sa mga byte sa gihatag nga gidak-on. Ang pinakataas nga gidak-on sa yawe mao ang 512 bytes.

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

Ang tindahan naggamit ug usa ka komparator sa paghan-ay sa mga yawe sa pataas nga han-ay. Kung dili nimo kini pulihan sa imong kaugalingon, nan ang default gamiton, nga nagsunud kanila byte-by-byte sa han-ay sa lexicographic.​

Mga Transaksyon

Ang aparato sa transaksyon gihulagway sa detalye sa miaging kapitulo, mao nga dinhi akong sublion ang ilang mga nag-unang kabtangan sa usa ka mubo nga linya:

  1. Suporta alang sa tanan nga sukaranan nga mga kabtangan ASIDPangunang mga pulong: atomicity, pagkamakanunayon, pagkahimulag ug kasaligan. Dili nako malikayan nga matikdan nga sa mga termino sa durability sa macOS ug iOS adunay bug nga naayos sa MDBX. Makabasa ka og dugang sa ilang README.
  2. Ang pamaagi sa multithreading gihulagway sa "usa ka magsusulat / daghang mga magbabasa" nga pamaagi. Gibabagan sa mga magsusulat ang usag usa, apan wala nila gibabagan ang mga magbabasa. Ang mga magbabasa dili mobabag sa mga magsusulat o sa usag usa.
  3. Suporta alang sa nested nga mga transaksyon.
  4. Multiversion nga suporta.

Ang multiversioning sa LMDB maayo kaayo nga gusto nako nga ipakita kini sa aksyon. Ang code sa ubos nagpakita nga ang matag transaksyon nagtrabaho uban sa eksakto nga bersyon sa database nga may kalabutan sa panahon sa pag-abli niini, nga hingpit nga nahimulag gikan sa tanan nga nagsunod nga mga pagbag-o. Ang pagsugod sa repository ug pagdugang sa usa ka test record niini walay interes, mao nga kini nga mga ritwal gibilin ubos sa spoiler.

Pagdugang usa ka pagsulay nga entry

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);

Opsyonal, girekomenda ko nga sulayan ang parehas nga limbong sa SQLite ug tan-awa kung unsa ang mahitabo.

Ang multiversioning nagdala og nindot kaayo nga mga benepisyo sa kinabuhi sa usa ka iOS developer. Gamit kini nga kabtangan, dali ug natural nimo nga ma-adjust ang rate sa pag-update sa gigikanan sa datos alang sa mga porma sa screen base sa mga konsiderasyon sa kasinatian sa gumagamit. Pananglitan, atong kuhaon ang ingon nga bahin sa Mail.ru Cloud nga aplikasyon sama sa autoloading content gikan sa system media gallery. Uban sa maayo nga koneksyon, ang kliyente makahimo sa pagdugang daghang mga litrato matag segundo sa server. Kung mag-update ka pagkahuman sa matag pag-download UICollectionView nga adunay sulud sa media sa panganod sa tiggamit, mahimo nimong kalimtan ang bahin sa 60 fps ug hapsay nga pag-scroll sa panahon niini nga proseso. Aron mapugngan ang kanunay nga pag-update sa screen, kinahanglan nimo nga limitahan ang rate sa pagbag-o sa datos sa sukaranan UICollectionViewDataSource.

Kung ang database dili mosuporta sa multiversioning ug motugot kanimo sa pagtrabaho lamang uban sa kasamtangan nga kasamtangan nga kahimtang, unya sa paghimo sa usa ka time-stable data snapshot, kinahanglan nimo nga kopyahon kini bisan sa pipila nga in-memorya nga istruktura sa datos o sa usa ka temporaryo nga lamesa. Ang bisan hain niini nga mga pamaagi mahal kaayo. Sa kaso sa in-memory storage, makuha nato ang mga gasto sa panumduman tungod sa pagtipig sa mga butang nga gitukod ug ang mga gasto sa oras nga may kalabutan sa sobra nga pagbag-o sa ORM. Sama sa alang sa temporaryo nga lamesa, kini usa ka labi ka mahal nga kalipayan, nga makatarunganon lamang sa mga dili hinungdan nga mga kaso.

Gisulbad sa multiversioning LMDB ang problema sa pagpadayon sa usa ka lig-on nga tinubdan sa datos sa usa ka elegante kaayo nga paagi. Igo na lang ang pag-abli sa usa ka transaksyon ug voila - hangtud nga makompleto nato kini, ang data set garantisado nga ayohon. Ang lohika sa rate sa pag-update niini anaa na sa mga kamot sa layer sa presentasyon, nga walay overhead sa mahinungdanong mga kapanguhaan.

Mga cursor

Naghatag ang mga cursor ug mekanismo alang sa hapsay nga pag-uli sa mga pares nga kantidad sa yawe pinaagi sa pagtabok sa usa ka B-tree. Kung wala sila, imposible nga epektibo nga mamodelo ang mga lamesa sa database, nga karon atong gipunting.

4.2. Pagmodelo sa lamesa

Ang yawe nga pag-order nga kabtangan nagtugot kanimo sa paghimo sa usa ka top-level abstraction sama sa usa ka lamesa sa ibabaw sa mga batakang abstraction. Atong tagdon kini nga proseso sa panig-ingnan sa main table sa cloud client, diin ang impormasyon bahin sa tanang file ug folder sa user gi-cache.

Table Schema

Usa sa kasagarang mga senaryo diin ang estraktura sa usa ka lamesa nga adunay usa ka folder nga kahoy kinahanglan nga mahait mao ang pagpili sa tanan nga mga elemento nga nahimutang sa sulod sa usa ka gihatag nga direktoryo. Lista sa Adjacency. Sa pagpatuman niini sa ibabaw sa yawe-bili storage, kini mao ang gikinahanglan nga sa paghan-ay sa mga yawe sa mga file ug mga folder sa paagi nga sila gigrupo base sa nahisakop sa ginikanan directory. Dugang pa, aron ipakita ang mga sulud sa direktoryo sa porma nga pamilyar sa usa ka tiggamit sa Windows (mga folder una, dayon ang mga file, ang duha gisunud sa alpabeto), kinahanglan nga ilakip ang katugbang nga dugang nga mga natad sa yawe.

Ang hulagway sa ubos nagpakita kung giunsa, base sa buluhaton, ang representasyon sa mga yawe isip usa ka han-ay sa mga byte mahimong tan-awon. Una, ang mga byte nga adunay identifier sa direktoryo sa ginikanan (pula) gibutang, dayon ang tipo (berde), ug naa na sa ikog nga adunay ngalan (asul). ang gikinahanglan nga paagi. Ang sunud-sunod nga paglatas sa mga yawe nga adunay parehas nga pula nga prefix naghatag kanamo sa mga kantidad nga kauban niini sa han-ay kung diin kini kinahanglan nga ipakita sa interface sa gumagamit (tuo), nga wala magkinahanglan bisan unsang dugang nga pagproseso sa post.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Pag-serye sa mga yawe ug mga bili

Adunay daghang mga pamaagi sa pag-serialize sa mga butang sa tibuuk kalibutan. Tungod kay wala kami'y laing kinahanglanon gawas sa katulin, gipili namo ang pinakapaspas nga posible alang sa among kaugalingon - usa ka memory dump nga giokupar sa usa ka pananglitan sa istruktura sa pinulongang C. Busa, ang yawe sa usa ka elemento sa direktoryo mahimong modelo sa mosunod nga istruktura NodeKey.

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

Aron makatipig NodeKey sa pagtipig kinahanglan sa butang MDB_val ibutang ang pointer sa data sa adres sa sinugdanan sa istruktura, ug kuwentaha ang ilang gidak-on sa function sizeof.

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

Sa unang kapitulo sa mga criteria sa pagpili sa database, akong gihisgutan ang pagminus sa dinamikong alokasyon isip kabahin sa mga operasyon sa CRUD isip usa ka importante nga butang sa pagpili. Function code serialize nagpakita kung giunsa, sa kaso sa LMDB, sila hingpit nga malikayan kung ang mga bag-ong rekord gisal-ot sa database. Ang umaabot nga han-ay sa mga byte gikan sa server una nga gibag-o ngadto sa mga istruktura sa stack, ug unya kini gamay nga gilabay sa pagtipig. Gikonsiderar nga wala usab mga dinamikong alokasyon sa sulod sa LMDB, mahimo nimong makuha ang usa ka matahum nga kahimtang sa mga sukdanan sa iOS - aron magamit lamang ang stack memory aron magtrabaho uban ang datos gikan sa network hangtod sa disk!

Pag-order sa mga yawe nga adunay binary comparator

Ang mahinungdanong order nga relasyon gihatag sa usa ka espesyal nga function nga gitawag og comparator. Tungod kay ang makina walay nahibal-an mahitungod sa mga semantiko sa mga byte nga anaa niini, ang default comparator walay kapilian gawas sa paghan-ay sa mga yawe sa lexicographic nga han-ay, nga naggamit sa ilang byte-by-byte nga pagtandi. Ang paggamit niini sa paghan-ay sa mga istruktura susama sa pagpamalbas gamit ang pagkulit nga wasay. Apan, sa yano nga mga kaso, akong nakita nga kini nga pamaagi madawat. Ang alternatibo gihulagway sa ubos, apan dinhi akong mamatikdan ang usa ka magtiayon nga mga rake nga nagkatag sa dalan.

Ang una nga butang nga hinumdoman mao ang representasyon sa panumduman sa mga primitive nga tipo sa datos. Mao nga, sa tanan nga mga aparato sa Apple, ang mga variable nga integer gitipig sa format Gamay nga Endian. Kini nagpasabut nga ang labing gamay nga hinungdanon nga byte naa sa wala, ug dili ka makahimo sa paghan-ay sa mga integer gamit ang ilang byte-by-byte nga pagtandi. Pananglitan, ang pagsulay sa pagbuhat niini sa usa ka hugpong sa mga numero gikan sa 0 ngadto sa 511 moresulta sa mosunod nga resulta.

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

Aron masulbad kini nga problema, ang mga integer kinahanglan nga tipigan sa yawe sa usa ka format nga angay alang sa byte comparator. Ang mga gimbuhaton gikan sa pamilya makatabang sa paghimo sa kinahanglan nga pagbag-o. hton* (sa partikular htons alang sa double-byte nga mga numero gikan sa pananglitan).

Ang pormat alang sa pagrepresentar sa mga kuwerdas sa pagprograma kay, sama sa imong nahibal-an, usa ka tibuuk kasaysayan. Kung ang mga semantiko sa mga kuwerdas, ingon man ang pag-encode nga gigamit sa pagrepresentar kanila sa panumduman, nagsugyot nga mahimo’g adunay labaw pa sa usa ka byte matag karakter, nan mas maayo nga biyaan dayon ang ideya sa paggamit sa usa ka default comparator.

Ang ikaduha nga butang nga hinumduman mao ang mga prinsipyo sa pag-align struct field compiler. Tungod niini, ang mga byte nga adunay mga kantidad sa basura mahimong maporma sa panumduman tali sa mga uma, nga, siyempre, nagguba sa pagsunud sa byte. Aron mawagtang ang basura, kinahanglan nimo nga ipahayag ang mga uma sa usa ka estrikto nga pagkahan-ay, ibutang sa hunahuna ang mga lagda sa pag-align, o gamiton ang hiyas sa deklarasyon sa istruktura packed.

Panguna nga pag-order pinaagi sa usa ka external comparator

Ang yawe nga lohika sa pagtandi mahimong labi ka komplikado alang sa usa ka binary comparator. Usa sa daghang mga hinungdan mao ang presensya sa mga teknikal nga natad sa sulod sa mga istruktura. Akong ihulagway ang ilang panghitabo sa pananglitan sa usa ka yawe nga pamilyar na kanato alang sa usa ka elemento sa direktoryo.

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

Alang sa tanan nga kayano niini, sa kadaghanan sa mga kaso nagkonsumo kini og daghang memorya. Ang buffer sa titulo kay 256 bytes, bisan pa sa kasagaran nga mga ngalan sa file ug folder panagsa ra molapas sa 20-30 ka karakter.

Usa sa mga sumbanan nga pamaagi sa pag-optimize sa gidak-on sa usa ka rekord mao ang pagputol niini aron mohaum sa aktuwal nga gidak-on niini. Ang esensya niini mao nga ang mga sulud sa tanan nga mga variable nga gitas-on nga mga natad gitipigan sa usa ka buffer sa katapusan sa istruktura, ug ang ilang mga gitas-on gitipigan sa lain nga mga variable. NodeKey giusab sa mosunod nga paagi.

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

Dugang pa, sa panahon sa serialization, wala gipiho nga gidak-on sa datos sizeof ang tibuok nga gambalay, ug ang gidak-on sa tanan nga mga natad gitakdang gitas-on plus ang gidak-on sa aktuwal nga gigamit nga bahin sa buffer.

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

Ingon usa ka sangputanan sa refactoring, nakakuha kami usa ka hinungdanon nga pagtipig sa wanang nga giokupar sa mga yawe. Bisan pa, tungod sa teknikal nga natad nameLength, ang default binary comparator dili na angay alang sa mahinungdanong pagtandi. Kung dili nato kini pulihan sa atong kaugalingon, nan ang gitas-on sa ngalan mahimong mas prayoridad nga butang sa paghan-ay kay sa ngalan mismo.

Gitugotan sa LMDB ang matag database nga adunay kaugalingon nga hinungdanon nga function sa pagtandi. Gihimo kini gamit ang function mdb_set_compare estrikto sa dili pa ablihan. Alang sa klaro nga mga hinungdan, ang usa ka database dili mabag-o sa tibuuk nga kinabuhi niini. Sa input, ang comparator makadawat sa duha ka yawe sa binary format, ug sa output kini mibalik sa resulta sa pagtandi: ubos pa kay sa (-1), mas dako pa kay sa (1) o managsama (0). Pseudocode para sa NodeKey ingon ana.

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 // ...
}​

Hangtud nga ang tanan nga mga yawe sa database parehas nga tipo, ligal nga wala’y kondisyon nga ihulog ang ilang byte nga representasyon sa tipo sa istruktura sa aplikasyon sa yawe. Adunay usa ka nuance dinhi, apan kini hisgutan nga mas ubos sa subsection nga "Reading Records".

Serialisasyon sa Bili

Uban sa mga yawe sa gitipigan nga mga rekord, ang LMDB nagtrabaho sa hilabihan ka intensive. Gitandi sila sa usag usa sulod sa gambalay sa bisan unsang operasyon sa aplikasyon, ug ang paghimo sa tibuok nga solusyon nagdepende sa gikusgon sa comparator. Sa usa ka sulundon nga kalibutan, ang default binary comparator kinahanglan nga igo aron itandi ang mga yawe, apan kung kinahanglan nimo nga gamiton ang imong kaugalingon, nan ang pamaagi sa pag-deserialize sa mga yawe niini kinahanglan nga labing kadali.

Ang database dili kaayo interesado sa Value-bahin sa record (value). Ang pagkakabig niini gikan sa representasyon sa byte ngadto sa usa ka butang mahitabo lamang kung gikinahanglan na kini sa code sa aplikasyon, pananglitan, aron ipakita kini sa screen. Tungod kay kini mahitabo medyo talagsa ra, ang mga kinahanglanon alang sa katulin sa kini nga pamaagi dili kaayo kritikal, ug sa pagpatuman niini labi kami nga gawasnon nga magpunting sa kasayon.Pananglitan, aron ma-serialize ang metadata bahin sa mga file nga wala pa ma-download, gigamit namon NSKeyedArchiver.

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

Bisan pa, adunay mga higayon nga hinungdanon ang pasundayag. Pananglitan, kung nagtipig sa meta-impormasyon bahin sa istruktura sa file sa user cloud, gigamit namon ang parehas nga butang nga memory dump. Ang highlight sa tahas sa paghimo sa ilang serialized nga representasyon mao ang kamatuoran nga ang mga elemento sa usa ka direktoryo gimodelo sa usa ka hierarchy sa klase.​

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Alang sa pagpatuman niini sa C nga pinulongan, ang mga piho nga natad sa mga manununod gikuha ngadto sa lain nga mga istruktura, ug ang ilang koneksyon sa base usa gitino pinaagi sa usa ka natad sa tipo sa unyon. Ang aktuwal nga sulod sa unyon gipiho pinaagi sa matang teknikal nga hiyas.

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

Pagdugang ug pag-update sa mga entry

Ang serialized nga yawe ug bili mahimong idugang sa tindahan. Alang niini, gigamit ang function mdb_put.

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

Sa yugto sa pag-configure, ang repository mahimong tugutan o gidid-an nga magtipig daghang mga rekord nga adunay parehas nga yawe.​ Kung gidili ang pagdoble sa mga yawe, unya kung magsulud usa ka rekord, mahimo nimong mahibal-an kung gitugotan ba o dili ang pag-update sa usa ka naa na nga rekord. Kung ang fraying mahimo ra nga mahitabo ingon usa ka sangputanan sa usa ka sayup sa code, nan mahimo nimong maseguro kini pinaagi sa pagtino sa bandila NOOVERWRITE.

Mga Rekord sa Pagbasa

Ang function alang sa pagbasa sa mga rekord sa LMDB mao ang mdb_get. Kung ang key-value nga pares girepresentahan sa kaniadto gilabay nga mga istruktura, nan kini nga pamaagi ingon niini.

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

Gipakita sa gipresentar nga lista kung giunsa ang pag-serialization pinaagi sa usa ka dump sa mga istruktura nagtugot kanimo nga makuha ang mga dinamikong alokasyon dili lamang kung nagsulat, apan kung nagbasa sa datos. Nakuha gikan sa function mdb_get ang pointer motan-aw gayud sa virtual memory address diin ang database nagtipig sa byte nga representasyon sa butang. Sa tinuud, nakakuha kami usa ka klase nga ORM, halos wala’y bayad nga naghatag usa ka taas nga tulin sa datos sa pagbasa. Sa tanan nga katahum sa pamaagi, kinahanglan nga hinumdoman ang daghang mga bahin nga may kalabotan niini.

  1. Alang sa usa ka readonly nga transaksyon, ang usa ka pointer sa usa ka value structure gigarantiyahan nga magpabilin nga balido lamang hangtud ang transaksyon masira. Sama sa nahisgotan na, ang mga panid sa B-tree diin ang butang nagpuyo, salamat sa copy-on-write nga prinsipyo, nagpabilin nga wala mausab basta labing menos usa ka transaksyon ang nagtumong kanila. Sa samang higayon, sa diha nga ang katapusan nga transaksyon nga may kalabutan kanila makompleto, ang mga panid mahimong magamit pag-usab alang sa bag-ong datos. Kung gikinahanglan alang sa mga butang nga mabuhi sa transaksyon nga nagmugna kanila, nan kinahanglan pa sila nga kopyahon.
  2. Alang sa usa ka readwrite nga transaksyon, ang pointer sa resulta nga structure-value mahimong balido lamang hangtud sa unang pamaagi sa pag-usab (pagsulat o pagtangtang sa datos).
  3. Bisan pa sa istruktura NodeValue dili bug-os, apan giputol (tan-awa ang subseksyon nga "Pag-order sa mga yawe pinaagi sa usa ka external comparator"), pinaagi sa pointer, dali ka maka-access sa mga natad niini. Ang nag-unang butang mao ang dili pag-dereference niini!
  4. Sa bisan unsang kaso dili nimo mabag-o ang istruktura pinaagi sa nadawat nga pointer. Ang tanan nga mga pagbag-o kinahanglan himuon lamang pinaagi sa pamaagi mdb_put. Bisan pa, sa tanan nga tinguha nga buhaton kini, dili kini molihok, tungod kay ang lugar sa panumduman kung diin nahimutang kini nga istruktura gimapa sa readonly mode.
  5. I-remap ang usa ka file ngadto sa address space sa usa ka proseso aron, pananglitan, madugangan ang maximum storage size gamit ang function mdb_env_set_map_size hingpit nga dili balido ang tanan nga mga transaksyon ug may kalabutan nga mga entidad sa kinatibuk-an ug mga punto sa pagbasa sa mga butang sa partikular.

Sa kataposan, ang usa pa ka bahin malimbungon kaayo nga ang pagbutyag sa esensya niini dili mohaom sa usa pa ka punto. Sa kapitulo sa B-tree, mihatag ko og diagram sa organisasyon sa mga panid niini sa memorya. Kini nagsunod gikan niini nga ang adres sa sinugdanan sa buffer nga adunay serialized data mahimong hingpit nga arbitraryo. Tungod niini, ang pointer sa kanila, nakuha sa istruktura MDB_val ug ang pagsalibay ngadto sa usa ka pointer sa usa ka estraktura kasagaran dili aligned. Sa samang higayon, ang mga arkitektura sa pipila ka mga chips (sa kaso sa iOS, kini mao ang armv7) nagkinahanglan nga ang adres sa bisan unsa nga data mahimong usa ka multiple sa gidak-on sa usa ka pulong sa makina, o, sa laing pagkasulti, ang bitness sa sistema. (alang sa armv7, kini 32 bits). Sa laing pagkasulti, usa ka operasyon sama sa *(int *foo)0x800002 sa kanila gipakasama sa pag-ikyas ug mosangpot sa pagpatay sa usa ka hukom EXC_ARM_DA_ALIGN. Adunay duha ka paagi aron malikayan ang ingon nga makapasubo nga kapalaran.

Ang una mao ang pagkopya sa datos sa usa ka nahibal-an nga istruktura nga daan. Pananglitan, sa usa ka naandan nga komparator, kini makita sama sa mosunod.

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 // ...
}

Ang usa ka alternatibo nga paagi mao ang pagpahibalo daan sa compiler nga ang mga istruktura nga adunay usa ka yawe ug bili mahimong dili ma-align gamit ang usa ka hiyas aligned(1). Sa ARM ang parehas nga epekto mahimo aron makab-ot ug gamit ang packed attribute. Gikonsiderar nga nakatampo usab kini sa pag-optimize sa wanang nga giokupahan sa istruktura, kini nga pamaagi daw mas gusto nako, bisan kung приводит aron madugangan ang gasto sa mga operasyon sa pag-access sa datos.

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

Mga Pangutana sa Range

Aron masubli ang usa ka grupo sa mga rekord, ang LMDB naghatag usa ka abstraction sa cursor. Atong tan-awon kung giunsa kini pagtrabaho gamit ang panig-ingnan sa usa ka lamesa nga adunay metadata sa panganod sa user nga pamilyar na kanato.

Isip bahin sa pagpakita sa usa ka lista sa mga file sa usa ka direktoryo, kinahanglan nimo nga pangitaon ang tanan nga mga yawe kung diin ang mga file ug folder sa bata nga adunay kalabotan. Sa miaging mga subseksyon, among gisunod ang mga yawe NodeKey aron sila una nga gimando sa ilang ginikanan nga direktoryo nga ID. Sa ingon, sa teknikal, ang tahas sa pagkuha sa mga sulud sa usa ka folder gipakunhod sa pagbutang sa cursor sa ibabaw nga utlanan sa usa ka grupo sa mga yawe nga adunay gihatag nga prefix, gisundan sa pag-uli sa ubos nga utlanan.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Makita nimo ang ibabaw nga bound "sa agtang" pinaagi sa sunod-sunod nga pagpangita. Aron mahimo kini, ang cursor gibutang sa sinugdanan sa tibuok nga listahan sa mga yawe sa database ug dayon gidugangan hangtud nga ang yawe uban sa parent directory identifier makita sa ubos niini. Kini nga pamaagi adunay 2 klaro nga mga disbentaha:

  1. Ang linear nga pagkakomplikado sa pagpangita, bisan pa, sama sa imong nahibal-an, sa mga kahoy sa kinatibuk-an ug sa usa ka B-tree sa partikular, mahimo kini sa logarithmic nga oras.​
  2. Sa walay kapuslanan, ang tanan nga mga panid nga nag-una sa gitinguha gipataas gikan sa file ngadto sa main memory, nga hilabihan ka mahal.

Maayo na lang, ang LMDB API naghatag ug usa ka episyente nga paagi sa pagsugod sa posisyon sa cursor.Aron mahimo kini, kinahanglan nimo nga maghimo usa ka yawe kansang kantidad nahibal-an nga ubos o parehas sa yawe nga nahimutang sa ibabaw nga utlanan sa interval. Pananglitan, sa relasyon ngadto sa listahan sa hulagway sa ibabaw, kita makahimo sa usa ka yawe diin ang uma parentId mahimong katumbas sa 2, ug ang tanan nga uban napuno sa mga sero. Ang ingon nga usa ka bahin nga napuno nga yawe gipakaon sa input sa function mdb_cursor_get nagpaila sa operasyon 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);

Kung makit-an ang taas nga bound sa grupo sa mga yawe, unya usbon namon kini hangtod magkita kami o ang yawe sa lain. parentId, o dili na mahurot ang mga yawe.​

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​​

Unsa ang nindot, isip bahin sa pag-uli gamit ang mdb_cursor_get, makuha nato dili lamang ang yawe, kondili usab ang bili. Kung, aron matuman ang mga kondisyon sa pagpili, kinahanglan nga susihon, taliwala sa ubang mga butang, ang mga uma gikan sa kantidad nga bahin sa rekord, nan kini dali nga ma-access sa ilang kaugalingon nga wala’y dugang nga mga lihok.

4.3. Pag-modelo sa mga relasyon tali sa mga lamesa

Hangtud karon, nakahimo kami sa pagkonsiderar sa tanan nga mga aspeto sa pagdesinyo ug pagtrabaho sa usa ka database nga usa ka lamesa. Mahimo natong isulti nga ang usa ka lamesa usa ka hugpong sa mga gihan-ay nga mga rekord nga gilangkuban sa mga pares sa yawe nga kantidad sa parehas nga tipo. Kung magpakita ka usa ka yawe ingon usa ka rectangle ug ang kauban nga kantidad niini ingon usa ka kahon, makakuha ka usa ka biswal nga diagram sa database.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Bisan pa, sa tinuud nga kinabuhi, panagsa ra nga mahimo’g makaagi sa gamay nga dugo. Kasagaran sa usa ka database gikinahanglan, una, nga adunay daghang mga lamesa, ug ikaduha, aron himuon ang mga pagpili niini sa usa ka han-ay nga lahi sa panguna nga yawe. Kining kataposang seksyon gipahinungod sa mga isyu sa ilang paglalang ug pagkadugtong.

Mga lamesa sa indeks

Ang cloud app adunay seksyon nga "Gallery". Gipakita niini ang sulud sa media gikan sa tibuuk nga panganod, gisunud sa petsa. Alang sa kamalaumon nga pagpatuman sa ingon nga pagpili, sunod sa main table, kinahanglan nimo nga maghimo usa nga adunay bag-ong tipo sa mga yawe. Maglangkob kini og usa ka field nga adunay petsa nga gibuhat ang file, nga molihok isip nag-unang sukdanan sa paghan-ay. Tungod kay ang bag-ong mga yawe nagtumong sa parehas nga datos sa mga yawe sa ilawom nga lamesa, kini gitawag nga mga yawe sa indeks. Gi-highlight sila sa orange sa litrato sa ubos.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Aron mabulag ang mga yawe sa lainlaing mga lamesa gikan sa usag usa sulod sa parehas nga database, usa ka dugang nga teknikal nga field tableId ang gidugang sa tanan niini. Pinaagi sa paghimo niini nga labing taas nga prayoridad sa paghan-ay, among grupoon una ang mga yawe sa mga lamesa, ug naa sa sulod sa mga lamesa - sumala sa among kaugalingon nga mga lagda.​

Ang yawe sa indeks nagtumong sa parehas nga datos sa panguna nga yawe. Ang prangka nga pagpatuman niini nga kabtangan pinaagi sa pag-asoy niini og usa ka kopya sa kantidad nga bahin sa nag-unang yawe mao ang suboptimal gikan sa daghang mga punto sa panglantaw sa usa ka higayon:

  1. Gikan sa usa ka luna nga okupar nga punto sa panglantaw, ang metadata mahimong dato kaayo.
  2. Gikan sa punto sa pasundayag, tungod kay kung gi-update ang metadata sa node, kinahanglan nimo nga i-overwrite ang duha ka yawe.
  3. Gikan sa punto sa panglantaw sa suporta sa code, human sa tanan, kon kita makalimot sa pag-update sa data alang sa usa sa mga yawe, kita sa pagkuha sa usa ka maliputon bug sa data inconsistency sa storage.

Sunod, atong hisgotan kon unsaon pagwagtang niini nga mga kakulangan.

Organisasyon sa mga relasyon tali sa mga lamesa

Ang sumbanan haom kaayo alang sa pagsumpay sa usa ka index table sa nag-unang usa "key isip bili". Sama sa gipasabot sa ngalan niini, ang bili nga bahin sa index record usa ka kopya sa nag-unang yawe nga bili. Kini nga pamaagi nagwagtang sa tanang mga disbentaha nga gilista sa ibabaw nga may kalabutan sa pagtipig sa usa ka kopya sa bili-bahin sa nag-unang rekord. Ang bugtong bayad mao nga aron makuha ang kantidad pinaagi sa index key, kinahanglan nimo nga maghimo 2 nga mga pangutana sa database imbis sa usa. Sa eskematiko, ang resulta nga database schema mao ang mosunod.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang laing sumbanan alang sa pag-organisar sa mga relasyon tali sa mga lamesa mao ang "kabus nga yawe". Ang esensya niini mao ang pagdugang og dugang nga mga hiyas sa yawe, nga gikinahanglan dili alang sa paghan-ay, apan alang sa paghimo pag-usab sa kauban nga yawe.Adunay tinuod nga mga pananglitan sa paggamit niini sa Mail.ru Cloud nga aplikasyon, bisan pa, aron malikayan ang lawom nga pag-dive sa konteksto sa piho nga mga gambalay sa iOS, maghatag ko og usa ka tinumotumo, apan mas masabtan nga pananglitan.

Ang mga kliyente sa Cloud mobile adunay usa ka panid nga nagpakita sa tanan nga mga file ug folder nga gipaambit sa user sa ubang mga tawo. Tungod kay gamay ra ang ingon nga mga file, ug adunay daghang piho nga kasayuran bahin sa publisidad nga kauban niini (kang kinsa gihatagan ang pag-access, kung unsang mga katungod, ug uban pa), dili makatarunganon nga pabug-atan kini sa kantidad nga bahin sa ang rekord sa main table. Bisan pa, kung gusto nimo ipakita ang ingon nga mga file sa offline, nan kinahanglan nimo nga tipigan kini bisan diin. Ang usa ka natural nga solusyon mao ang paghimo og usa ka bulag nga lamesa alang niini. Sa dayagram sa ubos, ang yawe niini adunay prefix nga "P", ug ang "propname" nga placeholder mahimong pulihan sa mas espesipikong bili nga "public info".​

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang tanan nga talagsaon nga metadata, alang sa kaayohan diin ang bag-ong lamesa gihimo, gibalhin sa kantidad nga bahin sa rekord. Sa parehas nga oras, dili ko gusto nga doblehon ang datos bahin sa mga file ug folder nga gitipigan na sa main table. Hinuon, ang sobra nga datos idugang sa "P" nga yawe sa porma sa "node ID" ug "timestamp" nga mga uma. Salamat sa kanila, mahimo ka magtukod usa ka yawe sa indeks, diin makuha nimo ang panguna nga yawe, diin, sa katapusan, makuha nimo ang metadata sa node.

Konklusyon

Positibo ang atong pagtimbang-timbang sa mga resulta sa pagpatuman sa LMDB. Pagkahuman niini, ang gidaghanon sa mga pag-freeze sa aplikasyon mikunhod sa 30%.

Ang kahayag ug kakabos sa key-value database LMDB sa iOS applications

Ang mga resulta sa trabaho nga nahimo nakakaplag usa ka tubag sa gawas sa iOS team. Sa pagkakaron, ang usa sa mga nag-unang "Files" nga mga seksyon sa Android nga aplikasyon mibalhin usab sa paggamit sa LMDB, ug ang ubang mga bahin anaa sa dalan. Ang C nga lengguwahe, diin ang key-value storage gipatuman, usa ka maayong tabang aron sa sinugdan mahimo ang aplikasyon nga nagbugkos sa palibot niini nga cross-platform sa C ++ nga pinulongan. Alang sa usa ka seamless nga koneksyon sa resulta nga C ++ library nga adunay platform code sa Objective-C ug Kotlin, usa ka code generator ang gigamit Djinni gikan sa Dropbox, apan kana laing istorya.

Source: www.habr.com

Idugang sa usa ka comment