කල් පවතින දත්ත ගබඩාව සහ Linux ගොනු API

වලාකුළු පද්ධතිවල දත්ත ගබඩා කිරීමේ තිරසාරභාවය පිළිබඳ පර්යේෂණ කරන අතරතුර, මම මූලික දේවල් තේරුම් ගෙන ඇති බව සහතික කර ගැනීමට මා පරීක්ෂා කිරීමට තීරණය කළෙමි. මම NVMe පිරිවිතර කියවීමෙන් ආරම්භ විය තිරසාර දත්ත ගබඩා කිරීම (එනම්, පද්ධති අසාර්ථක වීමෙන් පසුව දත්ත ලබා ගත හැකි බවට සහතික වීම) පිළිබඳ සහතික මොනවාද යන්න තේරුම් ගැනීමට NMVe තැටි අපට ලබා දෙන්න. මම පහත සඳහන් ප්‍රධාන නිගමන ඉදිරිපත් කළෙමි: දත්ත ලිවීමේ විධානය ලබා දුන් මොහොතේ සිට ගබඩා මාධ්‍යයට ලියා ඇති මොහොත දක්වා දත්ත හානියට පත් වූ බව සැලකිය යුතුය. කෙසේ වෙතත්, බොහෝ වැඩසටහන් දත්ත වාර්තා කිරීම සඳහා පද්ධති ඇමතුම් ඉතා සතුටින් භාවිතා කරයි.

මෙම සටහනේදී, මම Linux ගොනු API මඟින් සපයන ස්ථීර ගබඩා යාන්ත්‍රණයන් ගවේෂණය කරමි. මෙහි සෑම දෙයක්ම සරල විය යුතු බව පෙනේ: වැඩසටහන විධානය අමතන්න write(), සහ මෙම විධානය අවසන් වූ පසු, දත්ත ආරක්ෂිතව තැටියට සුරකිනු ඇත. එහෙත් write() RAM හි ඇති කර්නල් හැඹිලියට පමණක් යෙදුම් දත්ත පිටපත් කරයි. තැටියට දත්ත ලිවීමට පද්ධතියට බල කිරීම සඳහා, ඔබට අමතර යාන්ත්රණ කිහිපයක් භාවිතා කිරීමට අවශ්ය වේ.

කල් පවතින දත්ත ගබඩාව සහ Linux ගොනු API

සමස්තයක් වශයෙන්, මෙම ද්‍රව්‍යය මට උනන්දුවක් දක්වන මාතෘකාවක් පිළිබඳව මා ඉගෙන ගත් දේට අදාළ සටහන් එකතුවකි. අපි වැදගත්ම දේ ගැන ඉතා කෙටියෙන් කතා කරන්නේ නම්, තිරසාර දත්ත ගබඩා කිරීම සංවිධානය කිරීම සඳහා ඔබ විධානය භාවිතා කළ යුතු බව පෙනේ. fdatasync() හෝ ධජය සමඟ ගොනු විවෘත කරන්න O_DSYNC. කේතයේ සිට තැටිය දක්වා දත්ත වලට සිදුවන්නේ කුමක්ද යන්න ගැන වැඩිදුර ඉගෙන ගැනීමට ඔබ කැමති නම්, බලන්න මේ ලිපිය.

ලිවීම () ශ්‍රිතය භාවිතා කිරීමේ විශේෂාංග

පද්ධති ඇමතුම write() සම්මතයේ අර්ථ දක්වා ඇත IEEE POSIX ගොනු විස්තරයක් වෙත දත්ත ලිවීමේ උත්සාහයක් ලෙස. සාර්ථකව නිම කිරීමෙන් පසු write() දත්ත කියවීමේ මෙහෙයුම් මගින් කලින් ලියා ඇති බයිට් හරියටම ආපසු ලබා දිය යුතුය, දත්ත වෙනත් ක්‍රියාවලි හෝ නූල් වලින් ප්‍රවේශ වුව ද මෙය සිදු කරයි (බලන්නකෝ POSIX සම්මතයේ අදාළ කොටස). එය, සාමාන්‍ය ගොනු මෙහෙයුම් සමඟ නූල් අන්තර්ක්‍රියා කරන ආකාරය පිළිබඳ කොටසේ, සටහනක් ඇත, එක් එක් ත්‍රෙඩ් දෙකක් මෙම ශ්‍රිතයන් හඳුන්වන්නේ නම්, එක් එක් ඇමතුම අනෙක් ඇමතුමේ නම් කර ඇති සියලුම ප්‍රතිවිපාක දැකිය යුතුය, නැතහොත් කිසිවක් නැත. නැත. ප්රතිවිපාක. සියලුම ගොනු I/O මෙහෙයුම් ඔවුන් ක්‍රියාත්මක වන සම්පත මත අගුලක් තබා ගත යුතු බවට මෙය නිගමනය කරයි.

මෙයින් අදහස් කරන්නේ මෙහෙයුම බවයි write() එය පරමාණුක ද? තාක්ෂණික දෘෂ්ටි කෝණයකින්, ඔව්. දත්ත කියවීමේ මෙහෙයුම් ලියා ඇති දේ සියල්ල හෝ කිසිවක් ආපසු ලබා දිය යුතුය write(). නමුත් මෙහෙයුම write(), සම්මතයට අනුව, එය ලිවීමට ඉල්ලා සිටි සියල්ල ලිවීමෙන් අවසන් කළ යුතු නොවේ. දත්ත වලින් කොටසක් පමණක් ලිවීමට ඇයට අවසර ඇත. උදාහරණයක් ලෙස, එකම ගොනු විස්තරය මගින් විස්තර කර ඇති ගොනුවකට බයිට් 1024ක් එක් කරන නූල් දෙකක් අපට තිබිය හැක. සම්මතයේ දෘෂ්ටි කෝණයෙන්, පිළිගත හැකි ප්රතිඵලය වනුයේ එක් එක් ලිවීමේ මෙහෙයුම ගොනුවට එක් බයිටයක් පමණක් එකතු කළ හැකි විටය. මෙම මෙහෙයුම් පරමාණුකව පවතිනු ඇත, නමුත් ඒවා සම්පූර්ණ වූ පසු, ඔවුන් ගොනුවට ලියූ දත්ත මිශ්‍ර වේ. මෙහි Stack Overflow පිළිබඳ මෙම මාතෘකාව පිළිබඳ ඉතා රසවත් සාකච්ඡාවක්.

fsync() සහ fdatasync() ශ්‍රිත

තැටියට දත්ත ෆ්ලෂ් කිරීමට පහසුම ක්රමය වන්නේ කාර්යය ඇමතීමයි fsync(). මෙම කාර්යය මඟින් සියලුම වෙනස් කරන ලද බ්ලොක් හැඹිලියේ සිට තැටිය වෙත මාරු කිරීමට මෙහෙයුම් පද්ධතියෙන් ඉල්ලා සිටී. මෙයට සියලුම ගොනු පාර-දත්ත (ප්‍රවේශ කාලය, ගොනු වෙනස් කිරීමේ කාලය, සහ වෙනත්) ඇතුළත් වේ. මෙම පාර-දත්ත අවශ්‍ය වන්නේ කලාතුරකිනි, එබැවින් එය ඔබට වැදගත් නොවන බව ඔබ දන්නේ නම්, ඔබට කාර්යය භාවිතා කළ හැකිය fdatasync(). මෙම උදව් මත fdatasync() මෙම ශ්‍රිතයේ ක්‍රියාකාරිත්වය අතරතුර, එවැනි පාර-දත්ත ප්‍රමාණයක් තැටියට සුරකින අතර එය “පහත සඳහන් දත්ත කියවීමේ මෙහෙයුම් නිවැරදිව ක්‍රියාත්මක කිරීම සඳහා අවශ්‍ය” බව කියනු ලැබේ. බොහෝ යෙදුම් සැලකිලිමත් වන්නේ මෙයයි.

මෙහිදී මතුවිය හැකි එක් ගැටලුවක් නම්, මෙම යාන්ත්‍රණය මඟින් සිදුවිය හැකි අසාර්ථකත්වයකින් පසුව ගොනුව සොයා ගත හැකි බවට සහතික නොවීමයි. විශේෂයෙන්ම, නව ගොනුවක් නිර්මාණය කිරීමේදී, ඔබ ඇමතීමට අවශ්ය වේ fsync() එය අඩංගු නාමාවලිය සඳහා. එසේ නොමැතිනම්, අසාර්ථක වීමෙන් පසුව, මෙම ගොනුව නොපවතින බව පෙනී යා හැක. මෙයට හේතුව වන්නේ UNIX හි දෘඪ සබැඳි භාවිතය හේතුවෙන් ගොනුවක් නාමාවලි කිහිපයක පැවතිය හැකි වීමයි. එබැවින්, ඇමතීමේදී fsync() කුමන ඩිරෙක්ටරි දත්ත ද තැටියට ෆ්ලෂ් කළ යුතුදැයි දැන ගැනීමට ගොනුවකට ක්‍රමයක් නොමැත (මෙහි ඔබට මේ ගැන වැඩිදුර කියවිය හැකිය). ext4 ගොනු පද්ධතියට හැකියාව ඇති බව පෙනේ ස්වයංක්රීයව භාවිත fsync() අනුරූප ගොනු අඩංගු නාමාවලි වෙත, නමුත් මෙය අනෙකුත් ගොනු පද්ධති සමඟ සිදු නොවිය හැක.

මෙම යාන්ත්රණය විවිධ ගොනු පද්ධති මත වෙනස් ලෙස ක්රියාත්මක විය හැක. මම පාවිච්චි කළා blktrace ext4 සහ XFS ගොනු පද්ධතිවල භාවිතා වන තැටි මෙහෙයුම් මොනවාද යන්න දැන ගැනීමට. දෙකම ගොනු අන්තර්ගතය සහ ගොනු පද්ධති සඟරාව සඳහා තැටිය වෙත නිතිපතා ලිවීමේ විධාන නිකුත් කරයි, හැඹිලිය ෆ්ලෂ් කරන්න, සහ FUA (බල ඒකක ප්‍රවේශය, දත්ත කෙලින්ම තැටියට ලිවීම, හැඹිලිය මග හැරීම) සිදු කිරීමෙන් පිටවීම ජර්නලයට ලියන්න. ගනුදෙනුව සිදුවී ඇති බව තහවුරු කිරීම සඳහා ඔවුන් මෙය සිදු කරනු ඇත. FUA සඳහා සහය නොදක්වන ධාවකයන් මත, මෙය හැඹිලි ෆ්ලෂ් දෙකක් ඇති කරයි. මගේ අත්හදා බැලීම්වලින් එය පෙන්නුම් කළා fdatasync() ටිකක් වේගවත් fsync(). උපයෝගිතා blktrace බව පෙන්නුම් කරයි fdatasync() සාමාන්‍යයෙන් අඩු දත්ත තැටියට ලියයි (ext4 හි fsync() 20 KiB ලියයි, සහ fdatasync() - 16 KiB). ඒ වගේම XFS ext4 වලට වඩා ටිකක් වේගවත් බව මට දැනගන්නට ලැබුණා. සහ මෙහි උපකාරයෙන් blktrace බව සොයා ගැනීමට සමත් විය fdatasync() අඩු දත්ත තැටියට ෆ්ලෂ් කරයි (XFS හි 4 KiB).

fsync() භාවිතා කරන විට ඇතිවන නොපැහැදිලි තත්වයන්

මට අපැහැදිලි අවස්ථා තුනක් ගැන සිතිය හැකිය fsync()මම ප්රායෝගිකව මුහුණ දුන්.

එවැනි පළමු නඩුව 2008 දී සිදු විය. එවිට ගොනු විශාල ප්‍රමාණයක් තැටියට ලියා ඇත්නම් Firefox 3 අතුරුමුහුණත කැටි විය. ගැටළුව වූයේ අතුරු මුහුණත ක්රියාත්මක කිරීම එහි තත්වය පිළිබඳ තොරතුරු ගබඩා කිරීම සඳහා SQLite දත්ත ගබඩාවක් භාවිතා කිරීමයි. අතුරු මුහුණතේ සිදු වූ එක් එක් වෙනස් වීමෙන් පසුව, ශ්රිතය කැඳවනු ලැබීය fsync(), ස්ථාවර දත්ත ගබඩා කිරීම සඳහා හොඳ සහතිකයක් ලබා දුන්නේය. පසුව භාවිතා කරන ලද ext3 ගොනු පද්ධතියේ, ශ්‍රිතය fsync() පද්ධතියේ ඇති සියලුම "අපිරිසිදු" පිටු තැටියට දමා, අනුරූප ගොනුවට සම්බන්ධ ඒවා පමණක් නොවේ. මෙයින් අදහස් කළේ ෆයර්ෆොක්ස් හි බොත්තමක් ක්ලික් කිරීමෙන් චුම්බක තැටියකට මෙගාබයිට් දත්ත ලිවිය හැකි අතර එය තත්පර ගණනාවක් ගත විය හැකි බවයි. ගැටලුවට විසඳුම, මා තේරුම් ගත් පරිදි එය ද්රව්යය වූයේ දත්ත සමුදාය සමඟ වැඩ අසමමුහුර්ත පසුබිම් කාර්යයන් වෙත මාරු කිරීමයි. මෙයින් අදහස් කරන්නේ ෆයර්ෆොක්ස් මීට පෙර ඇත්ත වශයෙන්ම අවශ්‍ය ප්‍රමාණයට වඩා දැඩි ගබඩා අවශ්‍යතා ක්‍රියාත්මක කළ අතර ext3 ගොනු පද්ධතියේ විශේෂාංග මෙම ගැටලුව තවත් උග්‍ර කළේය.

දෙවන ගැටලුව 2009 දී ඇති විය. ඉන්පසුව, පද්ධති බිඳවැටීමකින් පසුව, නව ext4 ගොනු පද්ධතිය භාවිතා කරන්නන් අලුතින් සාදන ලද බොහෝ ගොනු වල දිග ශුන්‍ය වූ නමුත් පැරණි ext3 ගොනු පද්ධතිය සමඟ මෙය සිදු නොවීය. කලින් ඡේදයේ, මම ext3 තැටියට වැඩිපුර දත්ත ෆ්ලෂ් කළ ආකාරය ගැන කතා කළෙමි, එමඟින් දේවල් බොහෝ සෙමින් අඩු විය. fsync(). තත්වය වැඩිදියුණු කිරීම සඳහා, ext4 හි විශේෂිත ගොනුවකට අදාළ වන අපිරිසිදු පිටු පමණක් තැටියට ෆ්ලෂ් කරනු ලැබේ. තවද අනෙකුත් ගොනු වල දත්ත ext3 සමඟ වඩා දිගු කාලයක් මතකයේ පවතී. මෙය කාර්ය සාධනය වැඩි දියුණු කිරීම සඳහා සිදු කරන ලදී (පෙරනිමියෙන්, දත්ත තත්පර 30 ක් මෙම තත්වයේ පවතී, ඔබට මෙය වින්‍යාසගත කළ හැක dirty_expire_centisecs; මෙහි ඔබට මේ ගැන අමතර ද්රව්ය සොයාගත හැකිය). මෙයින් අදහස් කරන්නේ අසාර්ථක වීමෙන් පසු විශාල දත්ත ප්රමාණයක් ආපසු හැරවිය නොහැකි ලෙස අහිමි විය හැකි බවයි. මෙම ගැටලුවට විසඳුම භාවිතා කිරීමයි fsync() ස්ථාවර දත්ත ගබඩා කිරීම සහතික කිරීමට සහ අසාර්ථකත්වයේ ප්රතිවිපාකවලින් හැකිතාක් ඒවා ආරක්ෂා කිරීමට අවශ්ය යෙදුම්වල. කාර්යය fsync() ext4 භාවිතා කරන විට වඩා ext3 භාවිතා කරන විට වඩා කාර්යක්ෂමව ක්රියා කරයි. මෙම ප්රවේශයේ අවාසිය නම්, එහි භාවිතය, පෙර මෙන්, වැඩසටහන් ස්ථාපනය කිරීම වැනි සමහර මෙහෙයුම් ක්රියාත්මක කිරීම මන්දගාමී වේ. මේ ගැන විස්තර බලන්න මෙහි и මෙහි.

සම්බන්ධ තුන්වන ගැටලුව fsync(), 2018 දී ආරම්භ විය. පසුව, PostgreSQL ව්‍යාපෘතියේ රාමුව තුළ, එය ශ්‍රිතය නම් බව සොයා ගන්නා ලදී fsync() දෝෂයක් හමු වේ, එය "අපිරිසිදු" පිටු "පිරිසිදු" ලෙස සලකුණු කරයි. ප්රතිඵලයක් වශයෙන්, පහත සඳහන් ඇමතුම් fsync() ඔවුන් එවැනි පිටු සමඟ කිසිවක් නොකරයි. මේ නිසා, වෙනස් කරන ලද පිටු මතකයේ ගබඩා කර ඇති අතර කිසි විටෙකත් තැටියට ලියා නොමැත. මෙය සැබෑ ව්‍යසනයකි, මන්ද යෙදුම සමහර දත්ත තැටියට ලියා ඇති බව සිතනු ඇත, නමුත් ඇත්ත වශයෙන්ම එය එසේ නොවේ. එවැනි අසාර්ථකත්වයන් fsync() දුර්ලභ ය, එවැනි අවස්ථාවන්හිදී යෙදුමට ගැටලුව සමඟ සටන් කිරීමට කිසිවක් කළ නොහැක. මේ දිනවල, මෙය සිදු වූ විට, PostgreSQL සහ අනෙකුත් යෙදුම් බිඳ වැටේ. එය, "අයදුම්පත් fsync අසමත්වීම් වලින් ප්‍රතිසාධනය කළ හැකිද?" යන ද්‍රව්‍යයේ, මෙම ගැටළුව විස්තරාත්මකව ගවේෂණය කර ඇත. දැනට මෙම ගැටලුවට හොඳම විසඳුම වන්නේ ධජය සමඟ Direct I/O භාවිතා කිරීමයි O_SYNC හෝ කොඩියක් සමඟ O_DSYNC. මෙම ප්‍රවේශය සමඟ, පද්ධතිය නිශ්චිත ලිවීමේ මෙහෙයුම් වලදී සිදුවිය හැකි දෝෂ වාර්තා කරනු ඇත, නමුත් මෙම ප්‍රවේශය සඳහා යෙදුමට බෆර කළමනාකරණය කිරීමට අවශ්‍ය වේ. මේ ගැන වැඩිදුර කියවන්න මෙහි и මෙහි.

O_SYNC සහ O_DSYNC ධජ භාවිතයෙන් ගොනු විවෘත කිරීම

ස්ථාවර දත්ත ගබඩාවක් සපයන ලිනක්ස් යාන්ත්‍රණ පිළිබඳ සාකච්ඡාවට නැවත යමු. එනම්, අපි කොඩිය භාවිතා කිරීම ගැන කතා කරමු O_SYNC හෝ කොඩිය O_DSYNC පද්ධති ඇමතුම භාවිතයෙන් ගොනු විවෘත කරන විට විවෘත(). මෙම ප්‍රවේශය සමඟින්, එක් එක් දත්ත ලිවීමේ ක්‍රියාව එක් එක් විධානයට පසුව මෙන් සිදු කෙරේ write() පද්ධතියට ඒ අනුව විධාන ලබා දේ fsync() и fdatasync(). මෙම POSIX පිරිවිතර මෙය "Synchronized I/O File Integrity Completion" සහ "Data Integrity Completion" ලෙස හැඳින්වේ. මෙම ප්‍රවේශයේ ප්‍රධාන වාසිය නම්, දත්ත අඛණ්ඩතාව සහතික කිරීම සඳහා, ඔබට අවශ්‍ය වන්නේ පද්ධති ඇමතුම් දෙකකට වඩා එක් ඇමතුමක් පමණි (උදාහරණයක් ලෙස - write() и fdatasync()) මෙම ප්‍රවේශයේ ප්‍රධාන අවාසිය නම්, අදාළ ගොනු විස්තරය භාවිතා කරන සියලුම ලිවීම් සමමුහුර්ත වන අතර එමඟින් යෙදුම් කේතය ව්‍යුහගත කිරීමේ හැකියාව සීමා කළ හැකිය.

O_DIRECT ධජය සමඟ සෘජු I/O භාවිතා කිරීම

පද්ධති ඇමතුම open() ධජයට සහය දක්වයි O_DIRECT, තැටිය සමඟ සෘජුව අන්තර්ක්‍රියා කිරීමෙන් I/O මෙහෙයුම් සිදු කිරීම සඳහා මෙහෙයුම් පද්ධති හැඹිලිය මඟ හැරීමට සැලසුම් කර ඇත. මෙය බොහෝ අවස්ථාවලදී, වැඩසටහන මඟින් නිකුත් කරන ලද ලිවීමේ විධාන තැටිය සමඟ වැඩ කිරීම ඉලක්ක කරගත් විධානයන් බවට සෘජුවම පරිවර්තනය කරනු ඇත. නමුත්, සාමාන්යයෙන්, මෙම යාන්ත්රණය කාර්යයන් සඳහා ආදේශකයක් නොවේ 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() කණ්ඩායම "ඉතා භයානක" යැයි කියනු ලැබේ. එය භාවිතා කිරීම නිර්දේශ නොකරයි. විශේෂාංග සහ අන්තරායන් sync_file_range() ඉතා හොඳින් විස්තර කර ඇත මේ ද්රව්ය. විශේෂයෙන්ම, කර්නලය අපිරිසිදු දත්ත තැටියට ෆ්ලෂ් කරන විට පාලනය කිරීමට මෙම ඇමතුම RocksDB භාවිතා කරන බව පෙනේ. නමුත් ඒ සමඟම, ස්ථාවර දත්ත ගබඩා කිරීම සහතික කිරීම සඳහා, එය ද භාවිතා වේ fdatasync(). මෙම කේතය RocksDB මෙම මාතෘකාව පිළිබඳ රසවත් අදහස් කිහිපයක් ඇත. උදාහරණයක් ලෙස, එය ඇමතුම බව පෙනේ sync_file_range() ZFS භාවිතා කරන විට, එය තැටියට දත්ත ෆ්ලෂ් නොකරයි. අත්දැකීමෙන් මට කියන්නේ කලාතුරකින් භාවිතා වන කේතය දෝෂ අඩංගු වීමට ඉඩ ඇති බවයි. එබැවින්, අත්‍යවශ්‍ය නම් මිස මෙම පද්ධති ඇමතුම භාවිතා කිරීමට එරෙහිව මම උපදෙස් දෙමි.

දත්ත පැවැත්ම සහතික කිරීමට උපකාර වන පද්ධති ඇමතුම්

දත්ත අඛණ්ඩතාව සහතික කරන I/O මෙහෙයුම් සිදු කිරීමට භාවිතා කළ හැකි ප්‍රවේශයන් තුනක් ඇති බව මම නිගමනය කර ඇත්තෙමි. ඔවුන් සියල්ලටම ක්රියාකාරී ඇමතුමක් අවශ්ය වේ fsync() ගොනුව නිර්මාණය කරන ලද නාමාවලිය සඳහා. මෙම ප්රවේශයන් වේ:

  1. කාර්යයක් ඇමතීම fdatasync() හෝ fsync() කාර්යයෙන් පසුව write() (එය භාවිතා කිරීම වඩා හොඳය fdatasync()).
  2. ධජයක් සමඟ විවෘත කරන ලද ගොනු විස්තරයක් සමඟ වැඩ කිරීම O_DSYNC හෝ O_SYNC (වඩා හොඳ - කොඩියක් සමඟ O_DSYNC).
  3. විධානය භාවිතා කිරීම pwritev2() කොඩිය සමඟ RWF_DSYNC හෝ RWF_SYNC (වඩාත් සුදුසු කොඩියක් සමඟ RWF_DSYNC).

කාර්ය සාධන සටහන්

මා විසින් පරීක්‍ෂා කරන ලද විවිධ යාන්ත්‍රණවල ක්‍රියාකාරීත්වය මම පරෙස්සමින් මනින්නේ නැත. ඔවුන්ගේ කාර්යයේ වේගයේ මා දුටු වෙනස්කම් ඉතා කුඩා ය. මෙයින් අදහස් කරන්නේ මා වැරදි විය හැකි බවත්, විවිධ තත්වයන් යටතේ එකම දෙය විවිධ ප්‍රතිඵල ඇති කළ හැකි බවත්ය. පළමුව, මම කාර්ය සාධනයට වැඩිපුර බලපාන දේ ගැන කතා කරමි, පසුව කාර්ය සාධනයට අඩුවෙන් බලපාන දේ.

  1. ගොනු දත්ත නැවත ලිවීම ගොනුවකට දත්ත එක් කිරීමට වඩා වේගවත් වේ (කාර්ය සාධන ප්‍රතිලාභය 2-100% විය හැක). ගොනුවකට දත්ත එක් කිරීමට පද්ධති ඇමතුමකින් පසුව පවා ගොනුවේ පාරදත්ත වෙත අමතර වෙනස්කම් අවශ්‍ය වේ fallocate(), නමුත් මෙම බලපෑමේ විශාලත්වය වෙනස් විය හැක. හොඳම කාර්ය සාධනය සඳහා, ඇමතීමට මම නිර්දේශ කරමි fallocate() අවශ්ය ඉඩ කලින් වෙන් කිරීමට. එවිට මෙම අවකාශය පැහැදිලිවම ශුන්‍ය වලින් පුරවා කැඳවිය යුතුය fsync(). ගොනු පද්ධතියේ අනුරූප බ්ලොක් "නොකැඩී" වෙනුවට "වෙන් කළ" ලෙස සලකුණු කර ඇති බව මෙය සහතික කරයි. මෙය කුඩා (2% ක් පමණ) කාර්ය සාධන වැඩිදියුණු කිරීමක් ලබා දෙයි. මීට අමතරව, සමහර තැටි අනෙක් ඒවාට වඩා බ්ලොක් එකකට පළමු ප්‍රවේශය මන්දගාමී විය හැක. මෙයින් අදහස් කරන්නේ ශුන්‍ය වලින් අවකාශය පිරවීමෙන් කාර්ය සාධනයේ සැලකිය යුතු (100% ක් පමණ) දියුණුවක් ඇති විය හැකි බවයි. විශේෂයෙන්ම, මෙය තැටි සමඟ සිදු විය හැක AWS EBS (මෙය නිල නොවන දත්ත, මට එය තහවුරු කළ නොහැකි විය). ගබඩා කිරීම සඳහා ද එය එසේම වේ GCP Persistent Disk (මෙය දැනටමත් නිල තොරතුරු, පරීක්ෂණ මගින් තහවුරු කර ඇත). අනෙකුත් විශේෂඥයින් ද එයම කර ඇත නිරීක්ෂණ, විවිධ තැටි සම්බන්ධ.
  2. පද්ධති ඇමතුම් අඩු වන තරමට කාර්ය සාධනය වැඩි වේ (ලාභ 5% පමණ විය හැක). අභියෝගයක් වගේ open() කොඩිය සමඟ O_DSYNC හෝ අමතන්න pwritev2() කොඩිය සමඟ RWF_SYNC ඇමතුමකට වඩා වේගවත් fdatasync(). එකම ගැටළුව විසඳීමට (එක ඇමතුමක් වෙනුවට එක් ඇමතුමක්) අඩු පද්ධති ඇමතුම් ප්‍රමාණයක් සිදු කළ යුතු බවට මෙම ප්‍රවේශය කාර්යභාරයක් ඉටු කරන බව මම සැක කරමි. නමුත් කාර්ය සාධනයේ වෙනස ඉතා කුඩා වේ, එබැවින් ඔබට එය සම්පූර්ණයෙන්ම නොසලකා හැර එහි තර්කනය සංකීර්ණ නොවන යෙදුමේ යමක් භාවිතා කළ හැකිය.

ඔබ තිරසාර දත්ත ගබඩා කිරීමේ මාතෘකාව ගැන උනන්දුවක් දක්වන්නේ නම්, මෙන්න ප්‍රයෝජනවත් ද්‍රව්‍ය කිහිපයක්:

  • I/O ප්‍රවේශ ක්‍රම - ආදාන/ප්‍රතිදාන යාන්ත්‍රණවල මූලික කරුණු පිළිබඳ දළ විශ්ලේෂණය.
  • දත්ත තැටිය වෙත ළඟා වීම සහතික කිරීම — යෙදුමේ සිට තැටියට යන ගමනේදී දත්ත වලට සිදුවන්නේ කුමක්ද යන්න පිළිබඳ කතාවකි.
  • ඔබ අඩංගු බහලුම fsync කළ යුත්තේ කවදාද? - භාවිතා කළ යුත්තේ කවදාද යන ප්රශ්නයට පිළිතුර fsync() නාමාවලි සඳහා. මෙය කෙටියෙන් කිවහොත්, නව ගොනුවක් සෑදීමේදී ඔබ මෙය කළ යුතු බව පෙනී යන අතර, මෙම නිර්දේශයට හේතුව ලිනක්ස් හි එකම ගොනුව සඳහා බොහෝ යොමු කිරීම් තිබිය හැකිය.
  • ලිනක්ස් හි SQL සේවාදායකය: FUA අභ්‍යන්තර — Linux වේදිකාවේ SQL Server තුළ ස්ථීර දත්ත ගබඩා කිරීම ක්‍රියාත්මක කරන ආකාරය පිළිබඳ විස්තරයක් මෙන්න. මෙහි Windows සහ Linux පද්ධති ඇමතුම් අතර රසවත් සැසඳීම් කිහිපයක් තිබේ. XFS හි FUA ප්‍රශස්තකරණය ගැන මම ඉගෙන ගත්තේ මෙම ද්‍රව්‍යයට ස්තූතිවන්ත වන බව මට බොහෝ දුරට විශ්වාසයි.

තැටියක ආරක්ෂිතව ගබඩා කර ඇතැයි ඔබ සිතූ දත්ත ඔබට අහිමි වී තිබේද?

කල් පවතින දත්ත ගබඩාව සහ Linux ගොනු API

කල් පවතින දත්ත ගබඩාව සහ Linux ගොනු API

මූලාශ්රය: www.habr.com