Ҳангоми таҳқиқи устувории нигоҳдории маълумот дар системаҳои абрӣ, ман қарор додам, ки худро санҷам, то боварӣ ҳосил кунам, ки чизҳои асосиро фаҳмидам. И то бифаҳмем, ки чӣ гуна кафолатҳо дар бораи нигоҳдории устувори додаҳо (яъне кафолат медиҳанд, ки маълумот пас аз шикасти система дастрас хоҳад шуд) ба мо дискҳои NMVe медиҳад. Ман чунин хулосаҳои асосиро баровардам: маълумот бояд аз лаҳзаи дода шудани фармони навиштани маълумот то лаҳзаи навиштани он ба муҳити нигоҳдорӣ вайроншуда ҳисобида шавад. Бо вуҷуди ин, аксари барномаҳо барои сабти маълумот зангҳои системаро бо хушнудӣ истифода мебаранд.
Дар ин мақола, ман механизмҳои нигоҳдории доимии маълумотро, ки аз ҷониби API-ҳои файлӣ таъмин карда мешаванд, меомӯзам. LinuxЧунин ба назар мерасад, ки ҳама чиз дар ин ҷо бояд содда бошад: барнома фармонро даъват мекунад write(), ва пас аз иҷрои ин фармон, маълумот дар диск бехатар захира карда мешавад. Аммо write() танҳо маълумоти барномаро ба кэши ядрои дар RAM ҷойгиршуда нусхабардорӣ мекунад. Барои маҷбур кардани система ба навиштани маълумот ба диск, шумо бояд якчанд механизмҳои иловагиро истифода баред.
Умуман, ин мавод маҷмӯаи ёддоштҳоест, ки ба он чизе ки ман дар мавзӯи мароқовар омӯхтаам. Агар мо дар бораи чизи аз ҳама муҳим хеле мухтасар сухан ронем, маълум мешавад, ки барои ташкили нигоҳдории устувори маълумот шумо бояд фармонро истифода баред. fdatasync() ё файлҳоро бо парчам кушоед O_DSYNC. Агар шумо ба гирифтани маълумоти бештар дар бораи он, ки бо маълумот дар роҳи аз код ба диск чӣ рӯй медиҳад, таваҷҷӯҳ дошта бошед, ба он назар андозед мақола.
Хусусиятҳои истифодаи функсияи write()
Зангҳои системавӣ write() дар стандарт муайян карда шудааст ҳамчун кӯшиши навиштани маълумот ба тавсифкунандаи файл. Пас аз анҷоми бомуваффақият write() Амалиётҳои хондани маълумот бояд маҳз байтҳоеро, ки қаблан навишта шуда буданд, баргардонанд, ин корро ҳатто агар ба маълумот аз дигар равандҳо ё риштаҳо дастрас бошад ( фасли дахлдори стандарти POSIX). , дар бахш дар бораи он ки чӣ тавр риштаҳо бо амалиёти муқаррарии файл мутақобила мекунанд, ёддоште мавҷуд аст, ки агар ду ришта ҳар кадом ин функсияҳоро даъват кунад, пас ҳар як занг бояд ҳама оқибатҳои таъиншудаи занги дигарро бубинад, ё тамоман. оқибатҳои. Ин ба хулосае оварда мерасонад, ки ҳамаи амалиётҳои воридотӣ/базаркунии файл бояд дар захирае, ки дар онҳо кор мекунанд, қулф дошта бошанд.
Оё ин маънои онро дорад, ки амалиёт write() атом аст? Аз чихати техникй, бале. Амалиётҳои хондани маълумот бояд ҳама чизеро, ки бо он навишта шудааст, баргардонад write(). Аммо амалиёт write(), тибқи стандарт, ҳатман бояд бо навиштани ҳама чизе, ки аз он навишта шудааст, анҷом дода шавад. Ба вай иҷозат дода мешавад, ки танҳо як қисми маълумотро нависад. Масалан, мо метавонем ду ришта дошта бошем, ки ҳар кадоми онҳо 1024 байтро ба файле, ки аз ҷониби як дескриптори файл тавсиф шудааст, замима мекунанд. Аз нуқтаи назари стандарт, натиҷаи қобили қабул хоҳад буд, вақте ки ҳар як амалиёти навиштан метавонад ба файл танҳо як байт илова кунад. Ин амалиётҳо атомӣ боқӣ мемонанд, аммо пас аз анҷоми онҳо, маълумоте, ки онҳо ба файл навиштаанд, омехта мешавад. муҳокимаи хеле ҷолиб дар бораи ин мавзӯъ дар Stack Overflow.
Функсияҳои fsync () ва fdatasync ().
Роҳи осонтарини тоза кардани маълумот ба диск ин даъват кардани функсия мебошад . Ин функсия аз системаи оператсионӣ хоҳиш мекунад, ки ҳамаи блокҳои тағирёфтаро аз кэш ба диск интиқол диҳад. Ин ҳама метамаълумоти файлро дар бар мегирад (вақти дастрасӣ, вақти тағир додани файл ва ғайра). Ман боварӣ дорам, ки ин метадата хеле кам лозим аст, бинобар ин, агар шумо донед, ки ин барои шумо муҳим нест, шумо метавонед ин функсияро истифода баред fdatasync(). Дар ба fdatasync() Гуфта мешавад, ки дар ҷараёни кори ин функсия чунин миқдори метамаълумотҳо дар диск захира карда мешаванд, ки "барои иҷрои дурусти амалиёти хондани маълумотҳои зерин заруранд". Ва ин маҳз он чизест, ки аксари барномаҳо дар бораи он ғамхорӣ мекунанд.
Як мушкилоте, ки дар ин ҷо пайдо шуда метавонад, ин аст, ки ин механизмҳо кафолат намедиҳанд, ки файл пас аз нокомии эҳтимолӣ ошкор мешавад. Аз ҷумла, ҳангоми сохтани файли нав, шумо бояд занг занед fsync() барои директорияе, ки онро дарбар мегирад. Дар акси ҳол, пас аз нокомӣ, маълум мешавад, ки ин файл вуҷуд надорад. Сабаби ин дар он аст, ки дар UNIX аз сабаби истифодаи истинодҳои сахт, файл метавонад дар якчанд директория мавҷуд бошад. Бинобар ин, хангоми занг задан fsync() Ягон роҳе нест, ки файл бидонад, ки кадом маълумоти директория инчунин бояд ба диск тоза карда шавад ( Шумо метавонед дар ин бора бештар хонед). Чунин ба назар мерасад, ки системаи файлии ext4 қодир аст истифода бурдан fsync() ба директорияҳои дорои файлҳои мувофиқ, аммо ин метавонад бо дигар системаҳои файлӣ набошад.
Ин механизм метавонад дар системаҳои файлии гуногун ба таври гуногун амалӣ карда шавад. истифода кардам Барои фаҳмидани он, ки кадом амалиётҳои диск дар системаҳои файлии ext4 ва XFS истифода мешаванд. Ҳарду фармонҳои муқаррарии навиштанро ба диск ҳам барои мундариҷаи файл ва ҳам маҷаллаи системаи файлӣ медиҳанд, кэшро тоза мекунанд ва тавассути иҷрои FUA (Force Unit Access, навиштани маълумот ба диск мустақиман, гузариш аз кэш) ба маҷалла нависед. Эҳтимол онҳо ин корро барои тасдиқи он анҷом медиҳанд, ки муомилот сурат гирифтааст. Дар дискҳое, ки FUA-ро дастгирӣ намекунанд, ин боиси ду тозакунии кэш мегардад. Тачрибахои ман инро нишон доданд fdatasync() каме тезтар fsync(). Утилита blktrace нишон медихад fdatasync() одатан ба диск камтар маълумот менависад (дар ext4 fsync() менависад 20 КБ, ва fdatasync() - 16 КБ). Инчунин, ман фаҳмидам, ки XFS нисбат ба ext4 каме тезтар аст. Ва дар ин ҷо бо кӯмак blktrace муяссар шуд, ки онро фахмад fdatasync() кам маълумотро ба диск мерезад (4 киб дар XFS).
Ҳолатҳои номуайяне, ки ҳангоми истифодаи fsync() ба вуҷуд меоянд
Ман метавонам дар бораи се ҳолати номуайян дар бораи он фикр кунам fsync()ки дар амал дучор шудам.
Аввалин чунин ҳодиса соли 2008 рух дода буд. Пас аз он интерфейси Firefox 3 ях мекунад, агар шумораи зиёди файлҳо ба диск навишта шуда бошанд. Мушкилот дар он буд, ки татбиқи интерфейс аз пойгоҳи додаҳои SQLite барои нигоҳ доштани маълумот дар бораи ҳолати он истифода мешуд. Пас аз ҳар як тағирот, ки дар интерфейс рух дод, функсия даъват карда шуд fsync(), ки кафолати хуби нигоҳдории устувори маълумот дод. Дар системаи файлии ext3, он гоҳ функсия истифода мешавад fsync() ҳамаи саҳифаҳои "ифлос"-и системаро ба диск партофтанд, на танҳо саҳифаҳое, ки ба файли мувофиқ алоқаманд буданд. Ин маънои онро дошт, ки пахш кардани тугма дар Firefox метавонад мегабайтҳои маълумотро ба диски магнитӣ навишт, ки сонияҳои зиёдеро дарбар мегирад. Ҳалли мушкилот, то ҷое ки ман аз он фаҳмидам мавод барои интиқол додани кор бо пойгоҳи додаҳо ба вазифаҳои заминаи асинхронӣ буд. Ин маънои онро дорад, ки Firefox қаблан талаботҳои сахттари нигаҳдории нигоҳдорӣ нисбат ба воқеан лозим буд, ва хусусиятҳои системаи файлии ext3 ин мушкилотро боз ҳам шадидтар карданд.
Мушкилоти дуюм дар соли 2009 рух дод. Сипас, пас аз садамаи система, корбарони системаи нави файлии ext4 бо он дучор шуданд, ки бисёре аз файлҳои навтаъсис сифр дарозӣ доштанд, аммо ин бо системаи файлии кӯҳнаи ext3 рӯй надодааст. Дар параграфи қаблӣ, ман дар бораи он сӯҳбат кардам, ки чӣ тавр ext3 ба диск маълумотҳои аз ҳад зиёд рехтааст, ки ин корро хеле суст мекунад. fsync(). Барои беҳтар кардани вазъият, дар ext4 танҳо он саҳифаҳои ифлос, ки ба файли мушаххас мувофиқанд, ба диск тоза карда мешаванд. Ва маълумот аз файлҳои дигар назар ба ext3 дар хотира муддати хеле дароз боқӣ мемонад. Ин барои беҳтар кардани кор анҷом дода шудааст (бо нобаёнӣ, маълумот дар ин ҳолат 30 сония боқӣ мемонад, шумо метавонед онро бо истифода аз он танзим кунед. ; Шумо метавонед дар ин бора маводи иловагиро пайдо кунед). Ин маънои онро дорад, ки миқдори зиёди маълумот метавонад пас аз нокомӣ бебозгашт гум шавад. Халли ин масъала истифода бурдан аст fsync() дар барномаҳое, ки бояд нигоҳдории устувори маълумотро таъмин кунанд ва онҳоро то ҳадди имкон аз оқибатҳои нокомиҳо муҳофизат кунанд. Функсия fsync() ҳангоми истифодаи ext4 назар ба истифодаи ext3 хеле самараноктар кор мекунад. Камбудии ин равиш дар он аст, ки истифодабарии он мисли пештара иҷрои баъзе амалиётҳоро, масалан насб кардани барномаҳоро суст мекунад. Тафсилотро дар ин бора бубинед и .
Масъалаи сеюм вобаста ба fsync(), дар соли 2018 таъсис ёфтааст. Сипас, дар доираи лоиҳаи PostgreSQL маълум шуд, ки агар функсия fsync() ба хато дучор мешавад, он саҳифаҳои "ифлос" -ро ҳамчун "тоза" қайд мекунад. Дар натича зангхои зерин fsync() Онҳо бо чунин саҳифаҳо коре намекунанд. Аз ин сабаб, саҳифаҳои тағирёфта дар хотира нигоҳ дошта мешаванд ва ҳеҷ гоҳ ба диск навишта намешаванд. Ин як фалокати воқеӣ аст, зеро барнома фикр мекунад, ки баъзе маълумот ба диск навишта шудааст, аммо дар асл ин тавр нахоҳад буд. Чунин нобарориҳо fsync() каманд, барнома дар чунин ҳолатҳо барои мубориза бо мушкилот қариб ҳеҷ кор карда наметавонад. Дар ин рӯзҳо, вақте ки ин рӯй медиҳад, PostgreSQL ва дигар барномаҳо ба кор медароянд. , дар маводи "Оё барномаҳо аз хатогиҳои fsync барқарор мешаванд?", ин мушкилот ба таври муфассал омӯхта шудааст. Дар айни замон беҳтарин роҳи ҳалли ин мушкилот истифодаи мустақими I/O бо парчам мебошад O_SYNC ё бо парчам O_DSYNC. Бо ин равиш, система хатогиҳоеро, ки дар ҷараёни амалиёти мушаххаси навиштан рух дода метавонанд, гузориш медиҳад, аммо ин равиш аз барнома идора кардани буферҳо талаб мекунад. Дар ин бора бештар хонед и .
Кушодани файлҳо бо истифода аз парчамҳои O_SYNC ва O_DSYNC
Биёед ба баҳси механизмҳо баргардем Linux, таъмини нигоҳдории устувори маълумот. Хусусан, мо дар бораи истифодаи парчам сухан меронем O_SYNC ё парчам O_DSYNC ҳангоми кушодани файлҳо бо истифода аз занги система . Бо ин равиш, ҳар як амалиёти навиштани маълумот гӯё пас аз ҳар як фармон иҷро карда мешавад write() ба система мувофики фармонхо дода мешавад fsync() и fdatasync(). Дар ин "Анҷоми якпорчагии файли синхронизатсияшудаи вуруд/чор" ва "анҷоми тамомияти маълумот" номида мешавад. Бартарии асосии ин равиш дар он аст, ки барои таъмини тамомияти додаҳо, шумо бояд танҳо як занги системавӣ кунед, на ду (масалан - write() и fdatasync()). Камбудии асосии ин равиш дар он аст, ки ҳама навиштаҷот бо истифода аз дескриптори файли мувофиқ ҳамоҳанг карда мешавад, ки метавонад қобилияти сохтори коди барномаро маҳдуд кунад.
Истифодаи мустақими I/O бо парчами O_DIRECT
Зангҳои системавӣ open() байракро дастгирй мекунад O_DIRECT, ки барои гузаштан аз кэши системаи оператсионӣ барои иҷрои амалиёти воридотӣ / баромад тавассути мутақобилаи мустақим бо диск пешбинӣ шудааст. Ин, дар бисёр мавридҳо, маънои онро дорад, ки фармонҳои навиштани аз ҷониби барнома додашуда мустақиман ба фармонҳое, ки барои кор бо диск нигаронида шудаанд, тарҷума карда мешаванд. Аммо, дар маҷмӯъ, ин механизм иваз кардани вазифаҳо нест fsync() ё fdatasync(). Гап дар сари он аст, ки худи диск метавонад фармонҳои мувофиқи навиштани маълумот. Ва бадтар аз ин, дар баъзе ҳолатҳои махсус амалиёти I/O ҳангоми истифодаи парчам анҷом дода мешавад O_DIRECT, ба амалиёти анъанавии буферӣ. Роҳи осонтарини ҳалли ин мушкилот истифодаи парчам барои кушодани файлҳо мебошад O_DSYNC, ки ин маънои онро дорад, ки ҳар як амалиёти навиштан бо занг пайгирӣ карда мешавад fdatasync().
Маълум шуд, ки системаи файлии XFS ба наздикӣ "роҳи зуд" барои O_DIRECT|O_DSYNC- сабти маълумот. Агар блок бо истифода аз нав навишта шавад O_DIRECT|O_DSYNC, пас XFS ба ҷои тоза кардани кэш, агар дастгоҳ онро дастгирӣ кунад, фармони навиштани FUA-ро иҷро мекунад. Ман инро бо истифода аз утилита тасдиқ кардам blktrace дар система Linux 5.4 /Ubuntu 20.04. Ин равиш бояд самараноктар бошад, зеро он миқдори ками маълумотро ба диск менависад ва ба ҷои ду амалиёт як амалиётро истифода мебарад (навиштани кэш ва тоза кардани он). Ман истинодеро ёфтам ба ядрои 2018, ки ин механизмро амалӣ мекунад. Дар бораи татбиқи ин оптимизатсия дар дигар системаҳои файлӣ баҳс вуҷуд дорад, аммо то ҷое ки ман медонам, XFS ягона системаи файлист, ки то ҳол инро дастгирӣ мекунад.
функсияи sync_file_range().
В Linux як занги системавӣ вуҷуд дорад , ки ба шумо имкон медиҳад, ки танҳо як қисми файлро ба диск тоза кунед, на тамоми файл. Ин занг тозакунии асинхронии маълумотро оғоз мекунад ва мунтазири анҷоми он нест. Аммо дар шаҳодатнома sync_file_range() гуфта мешавад, ки команда «хеле хавфнок» аст. Истифодаи он тавсия дода намешавад. Хусусиятҳо ва хатарҳо sync_file_range() хеле хуб тасвир шудааст материал. Махсусан, ин занг ба назар мерасад, ки RocksDB-ро барои назорат кардани вақте ки ядро маълумоти ифлосро ба диск тоза мекунад, истифода мебарад. Аммо дар айни замон, барои таъмини нигоҳдории устувори маълумот, он низ истифода мешавад fdatasync(). Дар RocksDB дар ин мавзӯъ шарҳҳои ҷолиб дорад. Масалан, чунин ба назар мерасад, ки занг sync_file_range() Ҳангоми истифодаи ZFS, он маълумотро ба диск тоза намекунад. Таҷриба ба ман мегӯяд, ки рамзи кам истифодашаванда эҳтимол дорад хатогиҳо дошта бошад. Аз ин рӯ, ман маслиҳат медиҳам, ки ин занги системаро дар ҳолати зарурӣ истифода набаред.
Зангҳои системавӣ, ки барои таъмини устувории маълумот кӯмак мекунанд
Ман ба хулосае омадам, ки се равиш вуҷуд дорад, ки онҳоро барои иҷрои амалиёти вуруд/чор истифода бурдан мумкин аст, ки устувории маълумотро таъмин мекунанд. Ҳамаи онҳо занги функсияро талаб мекунанд fsync() барои директорияе, ки дар он файл сохта шудааст. Инҳоянд равишҳо:
- Даъвати функсия
fdatasync()ёfsync()пас аз функсияwrite()(истифода бурдан беҳтар астfdatasync()). - Кор бо дескриптори файл, ки бо парчам кушода мешавад
O_DSYNCёO_SYNC(беҳтараш - бо парчамO_DSYNC). - Истифодаи фармон
pwritev2()бо байракRWF_DSYNCёRWF_SYNC(бењтараш бо парчамRWF_DSYNC).
Қайдҳои иҷроиш
Ман кори механизмхои гуногуни тафтишкардаамро бодиккат чен накардаам. Фарқиятҳое, ки ман дар суръати кори онҳо мушоҳида кардам, хеле каманд. Ин маънои онро дорад, ки ман хато карда метавонам ва дар шароити гуногун як чиз метавонад натиҷаҳои гуногун диҳад. Аввалан, ман дар бораи он сухан хоҳам гуфт, ки чӣ ба кор бештар таъсир мерасонад ва баъд ба он чӣ камтар таъсир мерасонад.
- Навиштани маълумоти файл нисбат ба илова кардани маълумот ба файл тезтар аст (фоидаи иҷроиш метавонад 2-100% бошад). Илова кардани маълумот ба файл ҳатто пас аз занги система тағироти иловагиро ба метамаълумоти файл талаб мекунад
fallocate(), аммо андозаи ин таъсир метавонад гуногун бошад. Ман тавсия медиҳам, ки барои иҷрои беҳтарин занг занедfallocate()ки чои заруриро пешакй чудо кунанд. Пас ин фосила бояд ба таври возеҳ бо сифрҳо пур карда шавад ва даъват карда шавадfsync(). Ин кафолат медиҳад, ки блокҳои мувофиқ дар системаи файлӣ ҳамчун "тақсимшуда" ба ҷои "тақсимнашуда" қайд карда мешаванд. Ин як беҳбудии каме (тақрибан 2%) медиҳад. Илова бар ин, баъзе дискҳо метавонанд дастрасии аввал ба блок нисбат ба дигарон сусттар бошанд. Ин маънои онро дорад, ки пур кардани фазо бо сифрҳо метавонад ба беҳбудии назаррас (тақрибан 100%) дар кор оварда расонад. Махсусан, ин метавонад бо дискҳо рӯй диҳад (ин маълумоти ғайрирасмӣ аст, ман онро тасдиқ карда натавонистам). Ҳамин чиз барои нигоҳдорӣ меравад (ва ин аллакай маълумоти расмӣ аст, ки бо санҷишҳо тасдиқ карда шудааст). Мутахассисони дигар низ ҳамин тавр кардаанд , вобаста ба дискҳои гуногун. - Чӣ қадаре ки зангҳои система камтар бошад, ҳамон қадар кор баландтар мешавад (фоида метавонад тақрибан 5% бошад). Ба назар душворӣ ба назар мерасад
open()бо байракO_DSYNCё занг занедpwritev2()бо байракRWF_SYNCтезтар аз зангfdatasync(). Ман гумон мекунам, ки нуқтаи ин ҷо дар он аст, ки ин равиш дар он нақш мебозад, ки барои ҳалли як мушкилот (як занг ба ҷои ду) камтар зангҳои система анҷом дода шаванд. Аммо фарқият дар иҷроиш хеле ночиз аст, бинобар ин шумо метавонед онро комилан нодида гиред ва дар барнома чизеро истифода баред, ки мантиқи онро мушкил накунад.
Агар шумо ба мавзӯи нигоҳдории устувори маълумот таваҷҷӯҳ дошта бошед, инҳоянд чанд маводи муфид:
- — шарҳи асосҳои механизмҳои воридотӣ.
- — хикоя дар бораи он ки бо маълумот дар рох аз замима ба диск чй мешавад.
- - ҷавоб ба саволи кай бояд истифода шавад
fsync()барои директорияҳо. Хулоса, маълум мешавад, ки ин бояд ҳангоми эҷоди файли нав анҷом дода шавад ва сабаби ин тавсия дар он аст, ки дар Linux Мумкин аст, ки ба ҳамон як файл пайвандҳои зиёде мавҷуд бошанд. - — дар ин ҷо тавсифи он оварда шудааст, ки чӣ гуна нигоҳдории доимии маълумот дар SQL Server дар платформа амалӣ карда мешавад LinuxДар ин ҷо баъзе муқоисаҳои ҷолиб байни зангҳои системавӣ мавҷуданд. Windows и LinuxМан қариб мутмаинам, ки маҳз ба шарофати ин мавод ман дар бораи беҳсозии FUA-и XFS маълумот гирифтам.
Оё шумо маълумотеро гум кардаед, ки ба назари шумо дар диск бехатар нигоҳ дошта шудааст?
Манбаъ: will.com
