Stóráil Sonraí CRUA agus APIs Comhad Linux

Chinn mé, ag déanamh taighde ar chobhsaíocht stórála sonraí i gcórais scamall, mé féin a thástáil, chun a chinntiú go dtuigim na rudaí bunúsacha. mé tosaithe ag léamh an tsonraíocht NVMe chun a thuiscint cad iad na ráthaíochtaí maidir le marthanacht sonraí (is é sin, ráthaíochtaí go mbeidh sonraí ar fáil tar éis teip córais) dioscaí NMVe a thabhairt dúinn. Rinne mé na príomhchonclúidí seo a leanas: ní mór duit na sonraí a ndearnadh damáiste dóibh a mheas ón nóiméad a thugtar an t-ordú scríobh sonraí, agus go dtí an nóiméad a scríobhtar iad chuig an meán stórála. Mar sin féin, i bhformhór na gclár, úsáidtear glaonna córais sách sábháilte chun sonraí a scríobh.

San Airteagal seo, déanaim iniúchadh ar na meicníochtaí marthanachta a sholáthraíonn na APIs comhad Linux. Dealraíonn sé gur chóir go mbeadh gach rud simplí anseo: glaonna an clár an t-ordú write(), agus tar éis oibriú an ordaithe seo a bheith críochnaithe, déanfar na sonraí a stóráil go slán ar dhiosca. Ach write() ní dhéanann ach sonraí feidhmchláir a chóipeáil go dtí an taisce eithne atá suite i RAM. Chun iallach a chur ar an gcóras sonraí a scríobh chuig diosca, ní mór roinnt meicníochtaí breise a úsáid.

Stóráil Sonraí CRUA agus APIs Comhad Linux

Go ginearálta, is sraith nótaí é an t-ábhar seo a bhaineann leis an méid atá foghlamtha agam ar ábhar a bhfuil spéis agam ann. Má labhairt linn go han-ghairid faoi na cinn is tábhachtaí, is cosúil go gcaithfidh tú an t-ordú a úsáid chun stóráil sonraí inbhuanaithe a eagrú. fdatasync() nó comhaid a oscailt le bratach O_DSYNC. Má tá suim agat níos mó a fhoghlaim faoi cad a tharlaíonn do shonraí ar an mbealach ó chód go diosca, féach ar seo alt.

Gnéithe a bhaineann le húsáid na feidhme write().

Glao córais write() sainithe sa chaighdeán IEEE POSIX mar iarracht sonraí a scríobh chuig tuairisceoir comhaid. Tar éis críochnú rathúil na hoibre write() ní mór d'oibríochtaí léite sonraí na bearta a scríobhadh roimhe seo a thabhairt ar ais go beacht, agus é sin á dhéanamh fiú má tá rochtain á fháil ar na sonraí ó phróisis nó snáitheanna eile (anseo alt comhfhreagrach de chaighdeán POSIX). Anseo, sa chuid ar idirghníomhú snáitheanna le gnáthoibríochtaí comhaid, tá nóta ann a deir, má ghlaonn dhá shnáithe ar na feidhmeanna seo, ansin caithfidh gach glao na hiarmhairtí go léir a léiríodh a d’fhéadfadh a bheith mar thoradh ar fhorghníomhú an ghlao eile, nó ní fheiceáil ar chor ar bith iarmhairtí. Is é an tátal a bhaintear as seo ná go gcaithfidh gach oibríocht comhaid I/O glas a choinneáil ar an acmhainn a bhfuiltear ag obair uirthi.

Chiallaíonn sé seo go bhfuil an oibríocht write() an bhfuil adamhach? Ó thaobh teicniúil de, tá. Ní mór d'oibríochtaí léite sonraí an méid ar fad nó aon chuid dá raibh scríofa a thabhairt ar ais write(). Ach an oibríocht write(), i gcomhréir leis an gcaighdeán, ní gá deireadh a chur leis, tar éis gach rud a iarradh uirthi a scríobh síos. Tá sé ceadaithe a scríobh ach cuid de na sonraí. Mar shampla, d’fhéadfadh go mbeadh dhá shruth an ceann againn ag gabháil 1024 beart le comhad a bhfuil cur síos air ag an tuairisceoir comhaid céanna. Ó thaobh an chaighdeáin de, beidh an toradh inghlactha nuair nach féidir ach beart amháin a chur i gceangal leis an gcomhad i ngach ceann de na hoibríochtaí scríbhneoireachta. Fanfaidh na hoibríochtaí seo adamhach, ach tar éis dóibh a bheith críochnaithe, déanfar na sonraí a scríobhann siad chuig an gcomhad a mheascadh. Anseo plé an-suimiúil ar an ábhar seo ar Stack Overflow.

feidhmeanna fsync() agus fdatasync().

Is é an bealach is éasca chun sonraí a shruthlú go diosca ná an fheidhm a ghlaoch fsync(). Iarrann an fheidhm seo ar an gcóras oibriúcháin gach bloc modhnaithe a bhogadh ón taisce go diosca. Áirítear leis seo meiteashonraí uile an chomhaid (am rochtana, am modhnú comhaid, agus mar sin de). Creidim gur annamh a bhíonn gá leis na meiteashonraí seo, mar sin má tá a fhios agat nach bhfuil sé tábhachtach duit, is féidir leat an fheidhm a úsáid fdatasync(). I cabhrú ar fdatasync() deir sé, le linn oibriú na feidhme seo, go ndéantar méid meiteashonraí den sórt sin a shábháil ar an diosca, rud atá "riachtanach chun na hoibríochtaí léitheoireachta sonraí seo a leanas a chur i gcrích i gceart." Agus is é seo go díreach cad cúram an chuid is mó iarratas faoi.

Fadhb amháin a d’fhéadfadh teacht chun cinn anseo ná nach ráthaíonn na meicníochtaí seo gur féidir an comhad a aimsiú tar éis teipe. Go háirithe, nuair a chruthaítear comhad nua, ba cheart glaoch fsync() don eolaire ina bhfuil sé. Seachas sin, tar éis timpiste, d'fhéadfadh sé tarlú nach bhfuil an comhad seo ann. Is é an chúis atá leis seo ná, faoi UNIX, mar gheall ar úsáid naisc chrua, is féidir le comhad a bheith ann i il-eolairí. Dá bhrí sin, nuair a ghlaoch fsync() níl bealach ar bith le fios a bheith ag comhad cé na sonraí eolaire ba cheart a shruthlú go diosca (anseo is féidir leat tuilleadh a léamh faoi seo). Tá an chuma ar an scéal go bhfuil an córas comhaid ext4 in ann go huathoibríoch iarratas a dhéanamh fsync() chuig eolairí ina bhfuil na comhaid chomhfhreagracha, ach b’fhéidir nach amhlaidh an cás le córais comhad eile.

Is féidir an mheicníocht seo a chur i bhfeidhm go difriúil i gcórais comhaid éagsúla. d'úsáid mé blktrace chun foghlaim faoi na hoibríochtaí diosca a úsáidtear i gcórais comhaid ext4 agus XFS. Eisíonn an bheirt na gnáthorduithe scríobh chuig diosca le haghaidh ábhar na gcomhad agus dialann an chórais comhad, sruthlaigh an taisce agus scoir trí FUA (Rochtain Aonad Fórsa, sonraí a scríobh go díreach ar an diosca, an taisce a sheachaint) scríobh chuig an dialann. Is dócha go ndéanann siad é sin chun fírinne an idirbhirt a dhearbhú. Ar thiomáineann nach dtacaíonn FUA leo, is cúis le dhá shruthán taisce dá bharr. Tá sé léirithe ag mo thurgnaimh sin fdatasync() beagán níos tapúla fsync(). Fóntas blktrace léiríonn sin fdatasync() de ghnáth scríobhann sé níos lú sonraí chuig diosca (i ext4 fsync() scríobhann 20 KiB, agus fdatasync() - 16 KiB). Chomh maith leis sin, fuair mé amach go bhfuil XFS beagán níos tapúla ná ext4. Agus anseo le cabhair blktrace bhí sé in ann é sin a fháil amach fdatasync() sruthlaíonn sé níos lú sonraí chuig diosca (4 KiB in XFS).

Cásanna débhríoch agus fsync() in úsáid

Thig liom smaoineamh ar thrí chás débhríoch a bhaineann leis fsync()a tháinig mé trasna go praiticiúil.

Tharla an chéad eachtra dá leithéid in 2008. Ag an am sin, “reoite” comhéadan Firefox 3 dá mbeadh líon mór comhad á scríobh ar diosca. Ba í an fhadhb a bhí ann ná gur úsáideadh bunachar sonraí SQLite le cur i bhfeidhm an chomhéadain chun faisnéis a stóráil faoina staid. Tar éis gach athrú a tharla sa chomhéadan, glaodh an fheidhm fsync(), a thug ráthaíochtaí maith maidir le stóráil sonraí cobhsaí. Sa chóras comhaid ext3 a úsáidtear ansin, an fheidhm fsync() sruthlaithe chuig diosca na leathanaigh "salach" go léir sa chóras, agus ní amháin iad siúd a bhaineann leis an gcomhad comhfhreagrach. Chiallaigh sé seo go bhféadfaí meigibheart sonraí a scríobh chuig diosca maighnéadach ach cliceáil ar chnaipe i Firefox, rud a d’fhéadfadh go leor soicind a ghlacadh. An réiteach ar an bhfadhb, chomh fada agus a thuig mé as ábhar, ná an obair leis an mbunachar sonraí a aistriú chuig tascanna cúlra asincrónacha. Ciallaíonn sé seo gur úsáideadh Firefox chun ceanglais marthanachta stórála níos déine a chur i bhfeidhm ná mar a bhí riachtanach i ndáiríre, agus níor chuir gnéithe an chórais comhad ext3 ach an fhadhb seo níos measa.

Tharla an dara fadhb in 2009. Ansin, tar éis timpiste córais, d'aimsigh úsáideoirí an chórais comhad ext4 nua go raibh go leor comhad nuachruthaithe fad nialasach, ach níor tharla sé seo leis an gcóras comhaid ext3 níos sine. Sa mhír roimhe seo, labhair mé faoi conas a dhumpáil ext3 an iomarca sonraí ar an diosca, rud a chuir moill ar rudaí go leor. fsync(). Chun an scéal a fheabhsú, ní shruthaíonn ext4 ach na leathanaigh "salach" sin a bhaineann le comhad áirithe. Agus fanann sonraí na gcomhad eile i gcuimhne ar feadh i bhfad níos faide ná mar atá le ext3. Rinneadh é seo chun feidhmíocht a fheabhsú (de réir réamhshocraithe, fanann na sonraí sa riocht seo ar feadh 30 soicind, is féidir leat é seo a chumrú ag úsáid dirty_expire_centisecs; anseo is féidir leat tuilleadh eolais a fháil faoi seo). Ciallaíonn sé seo gur féidir cuid mhór sonraí a chailleadh go do-athghabhála tar éis timpiste. Is é an réiteach ar an bhfadhb seo a úsáid fsync() in iarratais ar gá stóráil sonraí cobhsaí a sholáthar agus iad a chosaint oiread agus is féidir ó iarmhairtí teipeanna. Feidhm fsync() oibríonn sé i bhfad níos éifeachtaí le ext4 ná le ext3. Is é an míbhuntáiste an cur chuige seo go bhfuil a úsáid, mar a rinneadh cheana, slows síos ar roinnt oibríochtaí, mar shampla cláir a shuiteáil. Féach sonraí faoi seo anseo и anseo.

An tríú fadhb maidir le fsync(), a thionscnamh in 2018. Ansin, laistigh de chreat an tionscadail PostgreSQL, fuarthas amach go má tá an fheidhm fsync() nuair a bhíonn earráid ann, marcálann sé leathanaigh "salach" mar "glan". Mar thoradh air sin, na glaonna seo a leanas fsync() aon rud a dhéanamh le leathanaigh den sórt sin. Mar gheall air seo, coinnítear leathanaigh leasaithe sa chuimhne agus ní scríobhtar ar diosca iad riamh. Is fíor-thubaiste é seo, toisc go gceapfaidh an t-iarratas go bhfuil roinnt sonraí scríofa ar dhiosca, ach i ndáiríre ní bheidh. Teipeanna den sórt sin fsync() is annamh, is féidir leis an iarratas i gcásanna den sórt sin beagnach aon rud a dhéanamh chun dul i ngleic leis an bhfadhb. Na laethanta seo, nuair a tharlaíonn sé seo, tuairteála PostgreSQL agus feidhmchláir eile. Anseo, san alt "An féidir le Feidhmchláir A ghnóthú ó Theipeanna fsync?", Déantar an fhadhb seo a iniúchadh go mion. Faoi láthair is é an réiteach is fearr ar an bhfadhb seo ná Direct I/O a úsáid leis an mbratach O_SYNC nó le bratach O_DSYNC. Leis an gcur chuige seo, tuairisceoidh an córas earráidí a d’fhéadfadh tarlú agus oibríochtaí sonracha scríofa sonraí á ndéanamh, ach éilíonn an cur chuige seo go n-éilíonn an t-iarratas na maoláin féin a bhainistiú. Léigh tuilleadh faoi anseo и anseo.

Comhaid a oscailt ag baint úsáide as na bratacha O_SYNC agus O_DSYNC

Fillfimid ar an bplé ar na meicníochtaí Linux a sholáthraíonn stóráil sonraí leanúnach. Eadhon, táimid ag caint faoi úsáid na brataí O_SYNC nó bratach O_DSYNC nuair a bhíonn comhaid á n-oscailt ag baint úsáide as córas glao oscailte (). Leis an gcur chuige seo, déantar gach oibríocht scríobh sonraí amhail is dá mba tar éis gach ordú write() tugtar orduithe don chóras, faoi seach fsync() и fdatasync(). I Sonraíochtaí POSIX tugtar "Críochnú Sláine Comhaid I/O Sioncrónaithe" agus "Críochnú Sláine Sonraí" air seo. Is é an buntáiste is mó a bhaineann leis an gcur chuige seo ná nach gá ach glaoch córais amháin a dhéanamh chun sláine sonraí a chinntiú, agus ní gá dhá cheann (mar shampla − write() и fdatasync()). Is é an príomh-mhíbhuntáiste a bhaineann leis an gcur chuige seo ná go ndéanfar na hoibríochtaí scríofa go léir a úsáideann an tuairisceoir comhaid comhfhreagrach a shioncrónú, rud a d'fhéadfadh teorainn a chur le cumas an chóid iarratais a struchtúrú.

Úsáid Díreach I/O leis an mbratach O_DIRECT

Glao córais open() Tacaíonn an bhratach O_DIRECT, atá deartha chun taisce an chórais oibriúcháin a sheachbhóthar, oibríochtaí I / O a dhéanamh, ag idirghníomhú go díreach leis an diosca. Ciallaíonn sé seo, i go leor cásanna, go ndéanfar na horduithe scríobh a eisíonn an clár a aistriú go díreach go horduithe atá dírithe ar oibriú leis an diosca. Ach, go ginearálta, níl an meicníocht seo in ionad na bhfeidhmeanna fsync()fdatasync(). Is é an fírinne gur féidir leis an diosca féin moill nó taisce orduithe cuí chun sonraí a scríobh. Agus, níos measa fós, i gcásanna speisialta áirithe, rinneadh na hoibríochtaí I / O agus an bhratach á úsáid O_DIRECT, craoladh isteach in oibríochtaí traidisiúnta maolánacha. Is é an bealach is éasca chun an fhadhb seo a réiteach ná an bhratach a úsáid chun comhaid a oscailt O_DSYNC, rud a chiallóidh go mbeidh glao ina dhiaidh sin ar gach oibríocht scríbhneoireachta fdatasync().

Tharla sé gur chuir córas comhaid XFS "cosán tapa" le déanaí le haghaidh O_DIRECT|O_DSYNC-taifid sonraí. Má tá an bloc overwritten ag baint úsáide as O_DIRECT|O_DSYNC, ansin déanfaidh XFS, in ionad an taisce a shruthlú, an t-ordú scríobh FUA a rith má thacaíonn an gléas leis. D'fhíoraigh mé é seo ag baint úsáide as an bhfóntas blktrace ar chóras Linux 5.4/Ubuntu 20.04. Ba cheart go mbeadh an cur chuige seo níos éifeachtaí, ós rud é go scríobhann sé an t-íosmhéid sonraí ar an diosca agus go n-úsáideann sé oibríocht amháin, ní dhá cheann (scríobh agus sruthlaigh an taisce). Fuair ​​​​mé nasc chuig paiste Eithne 2018 a chuireann an meicníocht seo i bhfeidhm. Tá roinnt plé ann maidir leis an leas iomlán a bhaint seo a chur i bhfeidhm ar chórais comhaid eile, ach chomh fada agus is eol dom, is é XFS an t-aon chóras comhaid a thacaíonn leis go dtí seo.

sync_file_range() feidhm

Tá glao córais ag Linux sync_file_range(), a ligeann duit gan ach cuid den chomhad a shruthlú go diosca, ní an comhad iomlán. Cuireann an glao seo tús le sruthlú asincrónach agus ní fhanann sé chun é a chríochnú. Ach sa tagairt do sync_file_range() deirtear go bhfuil an t-ordú seo “an-chontúirteach”. Ní mholtar é a úsáid. Gnéithe agus contúirtí sync_file_range() cur síos go han-mhaith i seo ábhar. Go háirithe, is cosúil go n-úsáideann an glao seo RocksDB chun rialú a dhéanamh nuair a shruthaíonn an eithne sonraí “salach” chuig diosca. Ach ag an am céanna ann, chun stóráil sonraí cobhsaí a chinntiú, úsáidtear é freisin fdatasync(). I cód Tá roinnt tuairimí suimiúla ag RocksDB ar an ábhar seo. Mar shampla, is cosúil leis an nglao sync_file_range() nuair nach n-úsáideann ZFS sonraí a shruthlú go diosca. Tugann taithí le fios dom go bhféadfadh fabhtanna a bheith i gcód is annamh a úsáidtear. Mar sin, mholfainn gan úsáid a bhaint as an nglao córais seo mura bhfuil fíorghá leis.

Glaonna córais chun marthanacht sonraí a chinntiú

Tháinig mé ar an tátal go bhfuil trí chur chuige ann is féidir a úsáid chun oibríochtaí leanúnacha I/O a dhéanamh. Teastaíonn glao feidhme uathu go léir fsync() don eolaire inar cruthaíodh an comhad. Seo iad na cuir chuige:

  1. Glaoch feidhm fdatasync()fsync() tar éis feidhm write() (níos fearr a úsáid fdatasync()).
  2. Osclaíodh oibriú le tuairisceoir comhaid le bratach O_DSYNCO_SYNC (níos fearr - le bratach O_DSYNC).
  3. Úsáid ordú pwritev2() le bratach RWF_DSYNCRWF_SYNC (B'fhearr le bratach RWF_DSYNC).

Nótaí Feidhmíochta

Ní dhearna mé tomhas cúramach ar fheidhmíocht na meicníochtaí éagsúla a d'imscrúdaigh mé. Is beag na difríochtaí a thug mé faoi deara i luas a gcuid oibre. Ciallaíonn sé seo gur féidir liom a bheith mícheart, agus go bhféadfadh an rud céanna torthaí éagsúla a thaispeáint i gcoinníollacha eile. Ar dtús, labhróidh mé faoi na rudaí a théann i bhfeidhm níos mó ar fheidhmíocht, agus ansin, faoi na rudaí a théann i bhfeidhm níos lú ar fheidhmíocht.

  1. Tá sé níos tapúla sonraí comhaid a fhorscríobh ná sonraí a chur i gceangal le comhad (is féidir leis an ngnóthachan feidhmíochta a bheith 2-100%). Teastaíonn athruithe breise ar mheiteashonraí an chomhaid, fiú tar éis glao an chórais, chun sonraí a cheangal le comhad fallocate(), ach d'fhéadfadh méid na héifeachta seo a bheith éagsúil. Molaim, don fheidhmíocht is fearr, glaoch fallocate() chun an spás riachtanach a réamh-leithdháileadh. Ansin ní mór an spás seo a líonadh go sainráite le nialais agus ar a dtugtar fsync(). Fágfaidh sé seo go ndéanfar na bloic chomhfhreagracha sa chóras comhad a mharcáil mar "leithdháilte" in ionad "neamh-leithdháilte". Tugann sé seo feabhas beag (thart ar 2%) ar fheidhmíocht. Chomh maith leis sin, d'fhéadfadh go mbeadh oibríocht rochtana bloc níos moille ag roinnt dioscaí ná cinn eile. Ciallaíonn sé seo gur féidir feabhas suntasach (thart ar 100%) a bheith mar thoradh ar an spás a líonadh le nialais. Go háirithe, is féidir leis seo tarlú le dioscaí. AWS EBS (sonraí neamhoifigiúla é seo, ní raibh mé in ann iad a dhearbhú). Téann an rud céanna le haghaidh stórála. Diosca Seasmhach GCP (agus is faisnéis oifigiúil í seo cheana féin, arna dhearbhú ag tástálacha). Tá an rud céanna déanta ag saineolaithe eile breathnóireachta bhaineann le dioscaí éagsúla.
  2. Dá lú glaonna an chórais, is airde an fheidhmíocht (is féidir an gnóthachan a bheith thart ar 5%). Breathnaíonn sé cosúil le glaoch open() le bratach O_DSYNC nó glaoch pwritev2() le bratach RWF_SYNC glaoch níos tapúla fdatasync(). Is dóigh liom gurb é an pointe anseo ná leis an gcur chuige seo, go bhfuil ról ag baint le níos lú glaonna córais chun an tasc céanna a réiteach (glao amháin in ionad dhá). Ach tá an difríocht feidhmíochta an-bheag, ionas gur féidir leat neamhaird a dhéanamh air go héasca agus úsáid a bhaint as rud éigin san iarratas nach n-eascraíonn casta a loighic.

Má tá suim agat san ábhar a bhaineann le stóráil inbhuanaithe sonraí, seo roinnt ábhar úsáideach:

  • I/O Modhanna rochtana — forbhreathnú ar na bunghnéithe meicníochtaí ionchuir / aschuir.
  • A chinntiú go sroicheann sonraí diosca - scéal faoi cad a tharlaíonn do na sonraí ar an mbealach ón bhfeidhmchlár go dtí an diosca.
  • Cathain ba chóir duit fsync an eolaire ina bhfuil - an freagra ar an gceist cathain ba cheart iarratas a dhéanamh fsync() le haghaidh eolairí. Go hachomair, tharlaíonn sé go gcaithfidh tú é seo a dhéanamh agus comhad nua á chruthú agat, agus is é an chúis atá leis an moladh seo ná gur féidir go leor tagairtí don chomhad céanna i Linux.
  • Freastalaí SQL ar Linux: FUA Internals - seo cur síos ar conas a chuirtear stóráil sonraí leanúnach i bhfeidhm i SQL Server ar an ardán Linux. Tá roinnt comparáidí suimiúla idir glaonna córais Windows agus Linux anseo. Táim beagnach cinnte gurb é a bhuíochas leis an ábhar seo a d'fhoghlaim mé faoi bharrfheabhsú FUA XFS.

Ar chaill tú riamh sonraí a cheap tú a bhí stóráilte go slán ar diosca?

Stóráil Sonraí CRUA agus APIs Comhad Linux

Stóráil Sonraí CRUA agus APIs Comhad Linux

Foinse: will.com