Ҳангоми таҳқиқи устувории нигоҳдории маълумот дар системаҳои абрӣ, ман қарор додам, ки худро санҷам, то боварӣ ҳосил кунам, ки чизҳои асосиро фаҳмидам. И
Дар ин паём, ман механизмҳои нигаҳдории доимиро, ки аз ҷониби API-ҳои файли Linux пешниҳод шудаанд, меомӯзам. Чунин ба назар мерасад, ки дар ин ҷо ҳама чиз бояд оддӣ бошад: барнома фармонро даъват мекунад write()
, ва пас аз иҷрои ин фармон, маълумот дар диск бехатар захира карда мешавад. Аммо write()
танҳо маълумоти барномаро ба кэши ядрои дар RAM ҷойгиршуда нусхабардорӣ мекунад. Барои маҷбур кардани система ба навиштани маълумот ба диск, шумо бояд якчанд механизмҳои иловагиро истифода баред.
Умуман, ин мавод маҷмӯаи ёддоштҳоест, ки ба он чизе ки ман дар мавзӯи мароқовар омӯхтаам. Агар мо дар бораи чизи аз ҳама муҳим хеле мухтасар сухан ронем, маълум мешавад, ки барои ташкили нигоҳдории устувори маълумот шумо бояд фармонро истифода баред. fdatasync()
ё файлҳоро бо парчам кушоед O_DSYNC
. Агар шумо ба гирифтани маълумоти бештар дар бораи он, ки бо маълумот дар роҳи аз код ба диск чӣ рӯй медиҳад, таваҷҷӯҳ дошта бошед, ба он назар андозед
Хусусиятҳои истифодаи функсияи write()
Зангҳои системавӣ write()
дар стандарт муайян карда шудааст write()
Амалиётҳои хондани маълумот бояд маҳз байтҳоеро, ки қаблан навишта шуда буданд, баргардонанд, ин корро ҳатто агар ба маълумот аз дигар равандҳо ё риштаҳо дастрас бошад (
Оё ин маънои онро дорад, ки амалиёт write()
атом аст? Аз чихати техникй, бале. Амалиётҳои хондани маълумот бояд ҳама чизеро, ки бо он навишта шудааст, баргардонад write()
. Аммо амалиёт write()
, тибқи стандарт, ҳатман бояд бо навиштани ҳама чизе, ки аз он навишта шудааст, анҷом дода шавад. Ба вай иҷозат дода мешавад, ки танҳо як қисми маълумотро нависад. Масалан, мо метавонем ду ришта дошта бошем, ки ҳар кадоми онҳо 1024 байтро ба файле, ки аз ҷониби як дескриптори файл тавсиф шудааст, замима мекунанд. Аз нуқтаи назари стандарт, натиҷаи қобили қабул хоҳад буд, вақте ки ҳар як амалиёти навиштан метавонад ба файл танҳо як байт илова кунад. Ин амалиётҳо атомӣ боқӣ мемонанд, аммо пас аз анҷоми онҳо, маълумоте, ки онҳо ба файл навиштаанд, омехта мешавад.
Функсияҳои fsync () ва fdatasync ().
Роҳи осонтарини тоза кардани маълумот ба диск ин даъват кардани функсия мебошад fdatasync()
. Дар fdatasync()
Гуфта мешавад, ки дар ҷараёни кори ин функсия чунин миқдори метамаълумотҳо дар диск захира карда мешаванд, ки "барои иҷрои дурусти амалиёти хондани маълумотҳои зерин заруранд". Ва ин маҳз он чизест, ки аксари барномаҳо дар бораи он ғамхорӣ мекунанд.
Як мушкилоте, ки дар ин ҷо пайдо шуда метавонад, ин аст, ки ин механизмҳо кафолат намедиҳанд, ки файл пас аз нокомии эҳтимолӣ ошкор мешавад. Аз ҷумла, ҳангоми сохтани файли нав, шумо бояд занг занед fsync()
барои директорияе, ки онро дарбар мегирад. Дар акси ҳол, пас аз нокомӣ, маълум мешавад, ки ин файл вуҷуд надорад. Сабаби ин дар он аст, ки дар UNIX аз сабаби истифодаи истинодҳои сахт, файл метавонад дар якчанд директория мавҷуд бошад. Бинобар ин, хангоми занг задан fsync()
Ягон роҳе нест, ки файл бидонад, ки кадом маълумоти директория инчунин бояд ба диск тоза карда шавад (fsync()
ба директорияҳои дорои файлҳои мувофиқ, аммо ин метавонад бо дигар системаҳои файлӣ набошад.
Ин механизм метавонад дар системаҳои файлии гуногун ба таври гуногун амалӣ карда шавад. истифода кардам 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 метавонад мегабайтҳои маълумотро ба диски магнитӣ навишт, ки сонияҳои зиёдеро дарбар мегирад. Ҳалли мушкилот, то ҷое ки ман аз он фаҳмидам
Мушкилоти дуюм дар соли 2009 рух дод. Сипас, пас аз садамаи система, корбарони системаи нави файлии ext4 бо он дучор шуданд, ки бисёре аз файлҳои навтаъсис сифр дарозӣ доштанд, аммо ин бо системаи файлии кӯҳнаи ext3 рӯй надодааст. Дар параграфи қаблӣ, ман дар бораи он сӯҳбат кардам, ки чӣ тавр ext3 ба диск маълумотҳои аз ҳад зиёд рехтааст, ки ин корро хеле суст мекунад. fsync()
. Барои беҳтар кардани вазъият, дар ext4 танҳо он саҳифаҳои ифлос, ки ба файли мушаххас мувофиқанд, ба диск тоза карда мешаванд. Ва маълумот аз файлҳои дигар назар ба ext3 дар хотира муддати хеле дароз боқӣ мемонад. Ин барои беҳтар кардани кор анҷом дода шудааст (бо нобаёнӣ, маълумот дар ин ҳолат 30 сония боқӣ мемонад, шумо метавонед онро бо истифода аз он танзим кунед. fsync()
дар барномаҳое, ки бояд нигоҳдории устувори маълумотро таъмин кунанд ва онҳоро то ҳадди имкон аз оқибатҳои нокомиҳо муҳофизат кунанд. Функсия fsync()
ҳангоми истифодаи ext4 назар ба истифодаи ext3 хеле самараноктар кор мекунад. Камбудии ин равиш дар он аст, ки истифодабарии он мисли пештара иҷрои баъзе амалиётҳоро, масалан насб кардани барномаҳоро суст мекунад. Тафсилотро дар ин бора бубинед
Масъалаи сеюм вобаста ба fsync()
, дар соли 2018 таъсис ёфтааст. Сипас, дар доираи лоиҳаи PostgreSQL маълум шуд, ки агар функсия fsync()
ба хато дучор мешавад, он саҳифаҳои "ифлос" -ро ҳамчун "тоза" қайд мекунад. Дар натича зангхои зерин fsync()
Онҳо бо чунин саҳифаҳо коре намекунанд. Аз ин сабаб, саҳифаҳои тағирёфта дар хотира нигоҳ дошта мешаванд ва ҳеҷ гоҳ ба диск навишта намешаванд. Ин як фалокати воқеӣ аст, зеро барнома фикр мекунад, ки баъзе маълумот ба диск навишта шудааст, аммо дар асл ин тавр нахоҳад буд. Чунин нобарориҳо fsync()
каманд, барнома дар чунин ҳолатҳо барои мубориза бо мушкилот қариб ҳеҷ кор карда наметавонад. Дар ин рӯзҳо, вақте ки ин рӯй медиҳад, PostgreSQL ва дигар барномаҳо ба кор медароянд. 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()
. Гап дар сари он аст, ки худи диск метавонад O_DIRECT
, O_DSYNC
, ки ин маънои онро дорад, ки ҳар як амалиёти навиштан бо занг пайгирӣ карда мешавад fdatasync()
.
Маълум шуд, ки системаи файлии XFS ба наздикӣ "роҳи зуд" барои O_DIRECT|O_DSYNC
- сабти маълумот. Агар блок бо истифода аз нав навишта шавад O_DIRECT|O_DSYNC
, пас XFS ба ҷои тоза кардани кэш, агар дастгоҳ онро дастгирӣ кунад, фармони навиштани FUA-ро иҷро мекунад. Ман инро бо истифода аз утилита тасдиқ кардам blktrace
дар системаи Linux 5.4/Ubuntu 20.04. Ин равиш бояд самараноктар бошад, зеро ҳангоми истифода ба диск миқдори ками маълумот навишта мешавад ва як амалиёт истифода мешавад, на ду (навиштан ва тоза кардани кэш). Ман пайвандеро пайдо кардам
функсияи sync_file_range().
Linux занги система дорад sync_file_range()
гуфта мешавад, ки команда «хеле хавфнок» аст. Истифодаи он тавсия дода намешавад. Хусусиятҳо ва хатарҳо sync_file_range()
хеле хуб тасвир шудааст fdatasync()
. Дар 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%) дар кор оварда расонад. Махсусан, ин метавонад бо дискҳо рӯй диҳадAWS EBS (ин маълумоти ғайрирасмӣ аст, ман онро тасдиқ карда натавонистам). Ҳамин чиз барои нигоҳдорӣ меравадДиски доимии GCP (ва ин аллакай маълумоти расмӣ аст, ки бо санҷишҳо тасдиқ карда шудааст). Мутахассисони дигар низ ҳамин тавр кардаандмушоҳидаҳо , вобаста ба дискҳои гуногун. - Чӣ қадаре ки зангҳои система камтар бошад, ҳамон қадар кор баландтар мешавад (фоида метавонад тақрибан 5% бошад). Ба назар душворӣ ба назар мерасад
open()
бо байракO_DSYNC
ё занг занедpwritev2()
бо байракRWF_SYNC
тезтар аз зангfdatasync()
. Ман гумон мекунам, ки нуқтаи ин ҷо дар он аст, ки ин равиш дар он нақш мебозад, ки барои ҳалли як мушкилот (як занг ба ҷои ду) камтар зангҳои система анҷом дода шаванд. Аммо фарқият дар иҷроиш хеле ночиз аст, бинобар ин шумо метавонед онро комилан нодида гиред ва дар барнома чизеро истифода баред, ки мантиқи онро мушкил накунад.
Агар шумо ба мавзӯи нигоҳдории устувори маълумот таваҷҷӯҳ дошта бошед, инҳоянд чанд маводи муфид:
Усулҳои дастрасии вуруд / баромад — шарҳи асосҳои механизмҳои воридотӣ.Боварӣ ҳосил кунед, ки маълумот ба диск мерасад — хикоя дар бораи он ки бо маълумот дар рох аз замима ба диск чй мешавад.Кай шумо бояд директорияи дорои файлро ҳамоҳанг созед - ҷавоб ба саволи кай бояд истифода шавадfsync()
барои директорияҳо. Барои ба таври мухтасар баён кардани ин, маълум мешавад, ки шумо бояд ин корро ҳангоми сохтани файли нав анҷом диҳед ва сабаби ин тавсия дар он аст, ки дар Linux истинодҳои зиёде ба як файл вуҷуд доранд.SQL Server дар Linux: FUA Internals — ин ҷо тавсифи он аст, ки чӣ тавр нигоҳдории доимии маълумот дар SQL Server дар платформаи Linux амалӣ карда мешавад. Дар ин ҷо якчанд муқоисаҳои ҷолиб байни зангҳои системаи Windows ва Linux мавҷуданд. Ман қариб боварӣ дорам, ки маҳз ба шарофати ин мавод ман дар бораи оптимизатсияи FUA-и XFS фаҳмидам.
Оё шумо маълумотеро гум кардаед, ки ба назари шумо дар диск бехатар нигоҳ дошта шудааст?
Манбаъ: will.com