AWK සහ R භාවිතයෙන් 25TB විග්‍රහ කිරීම

AWK සහ R භාවිතයෙන් 25TB විග්‍රහ කිරීම
මෙම ලිපිය කියවන්නේ කෙසේද: පෙළ මෙතරම් දිග සහ අවුල් සහගත වීම ගැන මම සමාව අයදිමි. ඔබේ කාලය ඉතිරි කර ගැනීම සඳහා, මම සෑම පරිච්ඡේදයක්ම ආරම්භ කරන්නේ “මා ඉගෙන ගත් දේ” හැඳින්වීමෙනි, එය වාක්‍ය එකකින් හෝ දෙකකින් පරිච්ඡේදයේ සාරය සාරාංශ කරයි.

"මට විසඳුම පෙන්වන්න!" ඔබට මා පැමිණියේ කොහෙන්දැයි බැලීමට අවශ්‍ය නම්, “වඩාත් නව නිපැයුම් කරුවෙකු වීම” යන පරිච්ඡේදයට යන්න, නමුත් අසාර්ථකත්වය ගැන කියවීම වඩාත් රසවත් හා ප්‍රයෝජනවත් යැයි මම සිතමි.

අමු DNA අනුපිළිවෙලවල් (තාක්ෂණිකව SNP චිපයක්) විශාල පරිමාවක් සැකසීම සඳහා ක්‍රියාවලියක් සැකසීමට මට මෑතකදී පැවරී ඇත. අවශ්‍යතාවය වූයේ පසුකාලීන ආකෘතිකරණය සහ අනෙකුත් කාර්යයන් සඳහා ලබා දී ඇති ජානමය පිහිටීමක් (SNP ලෙස හැඳින්වේ) පිළිබඳ දත්ත ඉක්මනින් ලබා ගැනීමයි. R සහ AWK භාවිතා කරමින්, විමසුම් සැකසීම බෙහෙවින් වේගවත් කරමින්, ස්වභාවික ආකාරයෙන් දත්ත පිරිසිදු කිරීමට සහ සංවිධානය කිරීමට මට හැකි විය. මෙය මට පහසු නොවූ අතර පුනරාවර්තන ගණනාවක් අවශ්‍ය විය. මෙම ලිපිය ඔබට මගේ සමහර වැරදි වළක්වා ගැනීමට සහ මා අවසන් කළ දේ ඔබට පෙන්වීමට උපකාරී වනු ඇත.

පළමුව, හඳුන්වාදීමේ පැහැදිලි කිරීම් කිහිපයක්.

දත්ත

අපගේ විශ්ව විද්‍යාල ජාන තොරතුරු සැකසුම් මධ්‍යස්ථානය අපට 25 TB TSV ආකාරයෙන් දත්ත ලබා දුන්නේය. Gzip මගින් සම්පීඩිත පැකේජ 5 කට බෙදා මට ඒවා ලැබුණි, ඒ සෑම එකක්ම ගිගාබයිට් හතරක ගොනු 240 ක් පමණ අඩංගු විය. සෑම පේළියකම එක් පුද්ගලයෙකුගෙන් එක් SNP සඳහා දත්ත අඩංගු විය. සමස්තයක් වශයෙන්, SNP මිලියන 2,5 ක් සහ පුද්ගලයින් ~ 60 දහසක් පිළිබඳ දත්ත සම්ප්‍රේෂණය කරන ලදී. SNP තොරතුරු වලට අමතරව, ලිපිගොනු වල කියවීමේ තීව්‍රතාවය, විවිධ ඇලිලවල සංඛ්‍යාතය යනාදී විවිධ ලක්ෂණ පිළිබිඹු කරන සංඛ්‍යා සහිත තීරු රාශියක් අඩංගු විය. සමස්තයක් වශයෙන් අද්විතීය අගයන් සහිත තීරු 30 ක් පමණ විය.

ඉලක්කය

ඕනෑම දත්ත කළමනාකරණ ව්‍යාපෘතියක් මෙන්, වඩාත්ම වැදගත් දෙය වූයේ දත්ත භාවිතා කරන්නේ කෙසේද යන්න තීරණය කිරීමයි. මේ අවස්ථාවේ දී අපි බොහෝ දුරට SNP මත පදනම්ව SNP සඳහා ආකෘති සහ වැඩ ප්‍රවාහයන් තෝරා ගනිමු. එනම්, අපට වරකට එක් SNP එකක දත්ත පමණක් අවශ්‍ය වනු ඇත. SNP මිලියන 2,5කින් එකක් හා සම්බන්ධ සියලුම වාර්තා හැකිතාක් පහසුවෙන්, ඉක්මනින් සහ ලාභදායි ලෙස ලබා ගන්නේ කෙසේදැයි මට ඉගෙන ගැනීමට සිදු විය.

මෙය නොකරන්නේ කෙසේද

සුදුසු ක්ලිචයක් උපුටා දැක්වීමට:

මම දහස් වාරයක් අසමත් නොවෙමි, විමසුම්-හිතකාමී ආකෘතියකින් දත්ත පොකුරක් විග්‍රහ කිරීම වළක්වා ගැනීමට ක්‍රම දහසක් සොයා ගතිමි.

පළමු උත්සාහය

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: වරකට 25 TB විග්‍රහ කිරීමට ලාභදායී ක්‍රමයක් නොමැත.

වැන්ඩර්බිල්ට් විශ්ව විද්‍යාලයේ “විශාල දත්ත සැකසීම සඳහා උසස් ක්‍රම” යන පා course මාලාව හැදෑරූ මට, උපක්‍රමය බෑගයේ ඇති බව මට විශ්වාසයි. සියලුම දත්ත හරහා ධාවනය කර ප්‍රතිඵලය වාර්තා කිරීමට Hive සේවාදායකය සැකසීමට බොහෝ විට පැයක් හෝ දෙකක් ගතවනු ඇත. අපගේ දත්ත AWS S3 හි ගබඩා කර ඇති බැවින්, මම සේවාව භාවිතා කළෙමි ඇතීනා, S3 දත්ත සඳහා Hive SQL විමසුම් යෙදීමට ඔබට ඉඩ සලසයි. ඔබට Hive පොකුරක් පිහිටුවීමට/එසවීමට අවශ්‍ය නොවන අතර, ඔබ සොයන දත්ත සඳහා පමණක් ගෙවන්න.

මම ඇතීනාට මගේ දත්ත සහ එහි ආකෘතිය පෙන්වූ පසු, මම මෙවැනි විමසුම් සමඟ පරීක්ෂණ කිහිපයක් සිදු කළෙමි:

select * from intensityData limit 10;

සහ ඉක්මනින් හොඳින් ව්‍යුහගත ප්‍රතිඵල ලැබිණි. සූදානම්.

අපි අපේ කාර්යයේ දත්ත භාවිතා කිරීමට උත්සාහ කරන තුරු ...

ආකෘතිය පරීක්ෂා කිරීම සඳහා සියලුම SNP තොරතුරු ලබා ගැනීමට මගෙන් ඉල්ලා සිටියේය. මම විමසුම ක්‍රියාත්මක කළෙමි:


select * from intensityData 
where snp = 'rs123456';

... බලා සිටින්නට විය. මිනිත්තු අටක් සහ 4 TB ට වඩා ඉල්ලූ දත්ත වලට පසුව, මට ප්‍රතිඵලය ලැබුණි. සොයාගත් දත්ත පරිමාව අනුව ඇතීනා ගාස්තු, ටෙරාබයිට් එකකට ඩොලර් 5 කි. එබැවින් මෙම තනි ඉල්ලීමට ඩොලර් 20 ක් සහ විනාඩි අටක් රැඳී සිටීමට වැය වේ. සියලුම දත්ත මත ආකෘතිය ධාවනය කිරීමට, අපට වසර 38 ක් බලා සිට ඩොලර් මිලියන 50 ක් ගෙවීමට සිදු විය.පැහැදිලිවම, මෙය අපට සුදුසු නොවේ.

Parquet භාවිතා කිරීමට අවශ්ය විය ...

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: ඔබේ Parquet ගොනු වල ප්‍රමාණය සහ ඒවායේ සංවිධානය ගැන සැලකිලිමත් වන්න.

මම මුලින්ම උත්සාහ කළේ සියලුම TSV බවට පරිවර්තනය කිරීමෙන් තත්වය නිවැරදි කිරීමටයි පාකට් ගොනු. විශාල දත්ත කට්ටල සමඟ වැඩ කිරීම සඳහා ඒවා පහසු වේ, මන්ද ඒවායේ තොරතුරු තීරු ආකාරයෙන් ගබඩා කර ඇත: සෑම තීරුවක්ම එහිම මතකය/තැටි කොටසක පිහිටා ඇත, පෙළ ගොනු වලට ප්‍රතිවිරුද්ධව, පේළිවල එක් එක් තීරුවේ මූලද්‍රව්‍ය අඩංගු වේ. ඔබට යමක් සොයා ගැනීමට අවශ්‍ය නම්, අවශ්‍ය තීරුව කියවන්න. මීට අමතරව, සෑම ගොනුවක්ම තීරුවක අගයන් පරාසයක් ගබඩා කරයි, එබැවින් ඔබ සොයන අගය තීරු පරාසයේ නොමැති නම්, Spark විසින් සම්පූර්ණ ගොනුව පරිලෝකනය කිරීමට කාලය නාස්ති නොකරයි.

මම සරල කාර්යයක් ඉටු කළා AWS මැලියම් අපගේ TSVs Parquet බවට පරිවර්තනය කිරීමට සහ නව ගොනු Athena බවට පත් කිරීමට. පැය 5ක් විතර ගියා. නමුත් මම ඉල්ලීම ක්‍රියාත්මක කරන විට, එය සම්පූර්ණ කිරීමට සමාන කාලයක් සහ ටිකක් අඩු මුදලක් ගත විය. කාරණය නම්, ස්පාර්ක්, කාර්යය ප්‍රශස්ත කිරීමට උත්සාහ කරමින්, එක් TSV කුට්ටියක් ගලවා එහිම පාකට් කුට්ටියක තැබීමයි. තවද බොහෝ පුද්ගලයින්ගේ සම්පූර්ණ වාර්තා අඩංගු වන පරිදි සෑම කුට්ටියක්ම විශාල වූ නිසා, සෑම ගොනුවකටම සියලුම SNPs අඩංගු විය, එබැවින් Spark හට අවශ්‍ය තොරතුරු ලබා ගැනීම සඳහා සියලුම ගොනු විවෘත කිරීමට සිදු විය.

සිත්ගන්නා කරුණ නම්, Parquet හි පෙරනිමි (සහ නිර්දේශිත) සම්පීඩන වර්ගය, snappy, බෙදිය නොහැක. එමනිසා, එක් එක් ක්‍රියාත්මක කරන්නා සම්පූර්ණ 3,5 GB දත්ත කට්ටලය ඉවත් කර බාගත කිරීමේ කාර්යයේ රැඳී සිටියේය.

AWK සහ R භාවිතයෙන් 25TB විග්‍රහ කිරීම

ගැටලුව තේරුම් ගනිමු

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: විශේෂයෙන් දත්ත බෙදා හැරියහොත් වර්ග කිරීම අපහසු වේ.

ගැටලුවේ හරය දැන් මට වැටහුණු බව මට පෙනුණි. මට අවශ්‍ය වූයේ මිනිසුන් විසින් නොව SNP තීරුවෙන් දත්ත වර්ග කිරීමට පමණි. එවිට SNP කිහිපයක් වෙනම දත්ත කුට්ටියක ගබඩා කරනු ඇත, පසුව Parquet හි "ස්මාර්ට්" ශ්රිතය "අගය පරාසයේ තිබේ නම් පමණක් විවෘත කරන්න" එහි සියලු මහිමයෙන් පෙන්වනු ඇත. අවාසනාවකට මෙන්, පොකුරක් පුරා විසිරී ඇති පේළි බිලියන ගණනක් හරහා වර්ග කිරීම දුෂ්කර කාර්යයක් විය.

"මම අවධානය වෙනතකට යොමු වූ ශිෂ්‍යයෙක්" හේතුව නිසා AWS හට මුදල් ආපසු ගෙවීමට අනිවාර්යයෙන්ම අවශ්‍ය නැත. මම Amazon Glue මත වර්ග කිරීමට දිව ගිය පසු, එය දින 2 ක් ධාවනය කර බිඳ වැටුණි.

කොටස් කිරීම ගැන කුමක් කිව හැකිද?

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: Spark හි කොටස් සමතුලිත විය යුතුය.

එවිට මම වර්ණදේහවල දත්ත කොටස් කිරීම පිළිබඳ අදහස ඉදිරිපත් කළෙමි. ඒවායින් 23 ක් ඇත (ඔබ මයිටොකොන්ඩ්‍රියල් ඩීඑන්ඒ සහ සිතියම්ගත නොකළ කලාප සැලකිල්ලට ගන්නේ නම් තවත් කිහිපයක්).
මෙය ඔබට දත්ත කුඩා කොටස් වලට බෙදීමට ඉඩ සලසයි. ඔබ Glue ස්ක්‍රිප්ටයේ Spark අපනයන කාර්යයට එක් පේළියක් පමණක් එක් කරන්නේ නම් partition_by = "chr", එවිට දත්ත බකට් වලට බෙදිය යුතුය.

AWK සහ R භාවිතයෙන් 25TB විග්‍රහ කිරීම
ජෙනෝමය වර්ණදේහ ලෙස හැඳින්වෙන කොටස් රාශියකින් සමන්විත වේ.

අවාසනාවට, එය වැඩ කළේ නැත. වර්ණදේහවල විවිධ ප්‍රමාණ ඇත, එයින් අදහස් කරන්නේ විවිධ තොරතුරු ප්‍රමාණයයි. මෙයින් අදහස් කරන්නේ සමහර නෝඩ් කලින් අවසන් වී ක්‍රියා විරහිත වූ නිසා ස්පාර්ක් කම්කරුවන්ට යවන කාර්යයන් සමතුලිත නොවී සෙමෙන් අවසන් වූ බවයි. කෙසේ වෙතත්, කාර්යයන් අවසන් විය. නමුත් එක් SNP එකක් ඉල්ලා සිටින විට, අසමතුලිතතාවය නැවතත් ගැටළු ඇති විය. විශාල වර්ණදේහ මත SNP සැකසීමේ පිරිවැය (එනම්, අපට දත්ත ලබා ගැනීමට අවශ්‍ය තැන) 10 ගුණයකින් පමණ අඩු වී ඇත. ගොඩක්, නමුත් ප්රමාණවත් නොවේ.

අපි එය කුඩා කොටස් වලට බෙදුවහොත් කුමක් කළ යුතුද?

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: කවදාවත් මිලියන 2,5ක් පාටිෂන් කරන්න හදන්න එපා.

මම සියල්ල පිටතට යාමට තීරණය කර එක් එක් SNP කොටස් කළෙමි. මෙම කොටස් සමාන ප්රමාණයේ බව සහතික විය. එය නරක අදහසක් විය. මම Glue භාවිතා කර අහිංසක රේඛාවක් එකතු කළා partition_by = 'snp'. කාර්යය ආරම්භ වූ අතර එය ක්රියාත්මක කිරීමට පටන් ගත්තේය. දවසකට පස්සේ මම චෙක් කරලා බැලුවා තාම S3 එකට ලියපු දෙයක් නැති බව, ඒ නිසා මම වැඩේ මරලා දැම්මා. Glue S3 හි සැඟවුණු ස්ථානයකට අතරමැදි ගොනු ලියන බව පෙනේ, බොහෝ ගොනු, සමහර විට මිලියන කිහිපයක්. ප්රතිඵලයක් වශයෙන්, මගේ වැරැද්ද ඩොලර් දහසකට වඩා වැඩි මුදලක් වැය වූ අතර මගේ උපදේශකයා සතුටු කළේ නැත.

කොටස් කිරීම + වර්ග කිරීම

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: Spark සුසර කිරීම මෙන්ම වර්ග කිරීම තවමත් අපහසුය.

කොටස් කිරීමට මගේ අවසන් උත්සාහය මා සම්බන්ධ වූයේ වර්ණදේහ කොටස් කිරීම සහ පසුව එක් එක් කොටස් වර්ග කිරීමයි. න්‍යායාත්මකව, මෙය එක් එක් විමසුම වේගවත් කරනු ඇත, මන්ද අපේක්ෂිත SNP දත්ත ලබා දී ඇති පරාසයක් තුළ Parquet කුට්ටි කිහිපයක් තුළ තිබිය යුතු බැවිනි. අවාසනාවකට, කොටස් කළ දත්ත පවා වර්ග කිරීම දුෂ්කර කාර්යයක් විය. එහි ප්‍රතිඵලයක් වශයෙන්, මම අභිරුචි පොකුරක් සඳහා EMR වෙත මාරු වූ අතර වඩාත් නම්‍යශීලී කාර්ය ප්‍රවාහයක් නිර්මාණය කිරීමට බලවත් අවස්ථා අටක් (C5.4xl) සහ Sparklyr භාවිතා කළෙමි...

# Sparklyr snippet to partition by chr and sort w/in partition
# Join the raw data with the snp bins
raw_data
  group_by(chr) %>%
  arrange(Position) %>% 
  Spark_write_Parquet(
    path = DUMP_LOC,
    mode = 'overwrite',
    partition_by = c('chr')
  )

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

මම වඩාත් නිර්මාණශීලී වෙමින් සිටිමි

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: සමහර විට විශේෂ දත්ත සඳහා විශේෂ විසඳුම් අවශ්ය වේ.

සෑම SNP එකකටම ස්ථාන අගයක් ඇත. මෙය එහි වර්ණදේහය දිගේ ඇති භෂ්ම ගණනට අනුරූප අංකයකි. මෙය අපගේ දත්ත සංවිධානය කිරීමට කදිම සහ ස්වභාවික ක්‍රමයකි. මුලදී මට අවශ්‍ය වූයේ එක් එක් වර්ණදේහවල ප්‍රදේශ අනුව කොටස් කිරීමටයි. උදාහරණයක් ලෙස, තනතුරු 1 - 2000, 2001 - 4000, ආදිය. නමුත් ගැටළුව වන්නේ SNP වර්ණදේහ හරහා ඒකාකාරව බෙදා නොහැරීමයි, එබැවින් කණ්ඩායම් ප්‍රමාණයන් විශාල වශයෙන් වෙනස් වේ.

AWK සහ R භාවිතයෙන් 25TB විග්‍රහ කිරීම

එහි ප්‍රතිඵලයක් වශයෙන්, මම තනතුරු කාණ්ඩවලට (ශ්‍රේණිගතව) බිඳ වැටීමකට පැමිණියෙමි. දැනටමත් බාගත කර ඇති දත්ත භාවිතා කරමින්, මම අද්විතීය SNP ලැයිස්තුවක්, ඒවායේ පිහිටීම් සහ වර්ණදේහ ලබා ගැනීමට ඉල්ලීමක් ඉදිරිපත් කළෙමි. පසුව මම එක් එක් වර්ණදේහය තුළ දත්ත වර්ග කර SNPs දී ඇති ප්‍රමාණයේ කණ්ඩායම් (බින්) වලට එකතු කළෙමි. අපි හිතමු SNP 1000 බැගින්. මෙය මට SNP-to-group-per-chromosome සම්බන්ධතාවය ලබා දුන්නේය.

අවසානයේදී, මම SNP 75 ක කණ්ඩායම් (බින්) සෑදුවෙමි, හේතුව පහත විස්තර කෙරේ.

snp_to_bin <- unique_snps %>% 
  group_by(chr) %>% 
  arrange(position) %>% 
  mutate(
    rank = 1:n()
    bin = floor(rank/snps_per_bin)
  ) %>% 
  ungroup()

මුලින්ම Spark සමඟ උත්සාහ කරන්න

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: Spark aggregation වේගවත්, නමුත් කොටස් කිරීම තවමත් මිල අධිකයි.

මට මෙම කුඩා (පේළි මිලියන 2,5) දත්ත රාමුව Spark වෙත කියවා, එය අමු දත්ත සමඟ ඒකාබද්ධ කර, පසුව අලුතින් එකතු කරන ලද තීරුවෙන් කොටස් කිරීමට අවශ්‍ය විය. bin.


# Join the raw data with the snp bins
data_w_bin <- raw_data %>%
  left_join(sdf_broadcast(snp_to_bin), by ='snp_name') %>%
  group_by(chr_bin) %>%
  arrange(Position) %>% 
  Spark_write_Parquet(
    path = DUMP_LOC,
    mode = 'overwrite',
    partition_by = c('chr_bin')
  )

මම පාවිච්චි කළා sdf_broadcast(), ඒ නිසා ස්පාර්ක් දන්නවා එය දත්ත රාමුව සියලුම නෝඩ් වලට යැවිය යුතු බව. දත්ත ප්‍රමාණයෙන් කුඩා නම් සහ සියලු කාර්යයන් සඳහා අවශ්‍ය නම් මෙය ප්‍රයෝජනවත් වේ. එසේ නොමැතිනම්, Spark බුද්ධිමත් වීමට උත්සාහ කරන අතර අවශ්‍ය පරිදි දත්ත බෙදා හැරීම මන්දගාමී වීමට හේතු විය හැක.

නැවතත්, මගේ අදහස ක්‍රියාත්මක වූයේ නැත: කාර්යයන් ටික කලක් ක්‍රියාත්මක විය, සමිතිය සම්පූර්ණ කරන ලද අතර පසුව, කොටස් කිරීම මගින් දියත් කරන ලද විධායකයින් මෙන් අසාර්ථක වීමට පටන් ගත්තේය.

AWK එකතු කිරීම

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: ඔබට මූලික දේ උගන්වන විට නිදා නොගන්න. නිසැකවම 1980 ගණන්වලදී යමෙකු දැනටමත් ඔබේ ගැටලුව විසඳා ඇත.

මේ මොහොත දක්වා, ස්පාර්ක් සමඟ මගේ සියලු අසාර්ථකත්වයට හේතුව පොකුරේ දත්ත අවුල් වීමයි. සමහර විට පූර්ව ප්‍රතිකාර මගින් තත්වය වැඩිදියුණු කළ හැකිය. අමු පෙළ දත්ත වර්ණදේහවල තීරුවලට බෙදීමට උත්සාහ කිරීමට මම තීරණය කළෙමි, එබැවින් මම ස්පාර්ක් වෙත “පූර්‍ව කොටස් කළ” දත්ත ලබා දීමට බලාපොරොත්තු වෙමි.

තීරු අගයන් අනුව බෙදන්නේ කෙසේද යන්න මම StackOverflow හි සෙවූ අතර සොයා ගන්නා ලදී එවැනි විශිෂ්ට පිළිතුරක්. AWK සමඟින් ඔබට ප්‍රතිඵල යැවීමට වඩා ස්ක්‍රිප්ට් එකක ලිවීමෙන් තීරු අගයන් අනුව පෙළ ගොනුවක් බෙදිය හැක. stdout.

මම එය අත්හදා බැලීමට Bash පිටපතක් ලිව්වෙමි. ඇසුරුම් කළ TSV වලින් එකක් බාගත කර, එය භාවිතයෙන් ඉවත් කරන ලදී gzip වෙත යවා ඇත awk.

gzip -dc path/to/chunk/file.gz |
awk -F 't' 
'{print $1",..."$30">"chunked/"$chr"_chr"$15".csv"}'

එය වැඩ කළා!

හරය පිරවීම

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: gnu parallel - එය මැජික් දෙයක්, සෑම කෙනෙකුම එය භාවිතා කළ යුතුය.

වෙන්වීම තරමක් මන්දගාමී වූ අතර මම ආරම්භ කරන විට htopප්‍රබල (හා මිල අධික) EC2 අවස්ථාවක් භාවිතා කිරීම පරීක්ෂා කිරීමට, මම භාවිතා කරන්නේ එක් හරයක් සහ 200 MB පමණ මතකයක් පමණක් බව පෙනී ගියේය. ගැටලුව විසඳීමට සහ විශාල මුදලක් අහිමි නොකිරීමට, කාර්යය සමාන්තරගත කරන්නේ කෙසේදැයි සොයා බැලීමට සිදු විය. වාසනාවකට මෙන්, සම්පූර්ණයෙන්ම පුදුම පොතක විධාන රේඛාවේ දත්ත විද්‍යාව සමාන්තරකරණය පිළිබඳ ජෙරොන් ජැන්සන්ස්ගේ පරිච්ඡේදයක් මට හමු විය. ඒකෙන් මම ඉගෙන ගත්තා gnu parallel, යුනික්ස් හි බහු නූල් ක්‍රියාත්මක කිරීම සඳහා ඉතා නම්‍යශීලී ක්‍රමයකි.

AWK සහ R භාවිතයෙන් 25TB විග්‍රහ කිරීම
මම නව ක්‍රියාවලිය භාවිතා කරමින් කොටස් කිරීම ආරම්භ කරන විට, සියල්ල හොඳින් සිදු විය, නමුත් තවමත් බාධකයක් විය - S3 වස්තු තැටියට බාගත කිරීම ඉතා වේගවත් නොවූ අතර සම්පූර්ණයෙන්ම සමාන්තරගත නොවීය. මෙය නිවැරදි කිරීමට, මම මෙය කළෙමි:

  1. තැටියේ ඇති අතරමැදි ගබඩාව සම්පූර්ණයෙන්ම ඉවත් කරමින් නල මාර්ගයේ S3 බාගත කිරීමේ අදියර සෘජුවම ක්රියාත්මක කිරීමට හැකි බව මම සොයාගත්තා. මෙයින් අදහස් කරන්නේ මට තැටියට අමු දත්ත ලිවීමෙන් වැළකිය හැකි අතර ඊටත් වඩා කුඩා, එබැවින් මිල අඩු, AWS මත ගබඩා කිරීම භාවිතා කළ හැකිය.
  2. කණ්ඩායම aws configure set default.s3.max_concurrent_requests 50 AWS CLI භාවිතා කරන නූල් ගණන විශාල ලෙස වැඩි කර ඇත (පෙරනිමියෙන් 10 ක් ඇත).
  3. මම නමේ n අකුර සමඟ ජාල වේගය සඳහා ප්‍රශස්ත කළ EC2 අවස්ථාවක් වෙත මාරු වුණෙමි. n-උදාහරණ භාවිතා කරන විට සැකසුම් බලය අහිමි වීම පැටවීමේ වේගය වැඩි වීමෙන් වන්දි ගෙවීමට වඩා වැඩි බව මම සොයාගෙන ඇත. බොහෝ කාර්යයන් සඳහා මම c5n.4xl භාවිතා කළෙමි.
  4. වෙනස් කළා gzip මත pigz, මෙය gzip මෙවලමක් වන අතර එය මුලින් සමාන්තර නොවන ගොනු විසංයෝජනය කිරීමේ කාර්යය සමාන්තර කිරීමට සිසිල් දේවල් කළ හැකිය (මෙය අවම වශයෙන් උපකාරී විය).

# Let S3 use as many threads as it wants
aws configure set default.s3.max_concurrent_requests 50

for chunk_file in $(aws s3 ls $DATA_LOC | awk '{print $4}' | grep 'chr'$DESIRED_CHR'.csv') ; do

        aws s3 cp s3://$batch_loc$chunk_file - |
        pigz -dc |
        parallel --block 100M --pipe  
        "awk -F 't' '{print $1",..."$30">"chunked/{#}_chr"$15".csv"}'"

       # Combine all the parallel process chunks to single files
        ls chunked/ |
        cut -d '_' -f 2 |
        sort -u |
        parallel 'cat chunked/*_{} | sort -k5 -n -S 80% -t, | aws s3 cp - '$s3_dest'/batch_'$batch_num'_{}'
        
         # Clean up intermediate data
       rm chunked/*
done

සෑම දෙයක්ම ඉතා ඉක්මනින් වැඩ කිරීමට මෙම පියවර එකිනෙකා සමඟ ඒකාබද්ධ වේ. බාගත කිරීමේ වේගය වැඩි කිරීමෙන් සහ තැටි ලිවීම් ඉවත් කිරීමෙන්, මට දැන් පැය කිහිපයකින් ටෙරාබයිට් 5 පැකේජයක් සැකසීමට හැකි විය.

මෙම ට්වීට් එක 'TSV' යනුවෙන් සඳහන් කළ යුතුව තිබුණි. අහෝ.

අලුතින් විග්‍රහ කළ දත්ත භාවිතා කිරීම

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: Spark සම්පීඩිත නොකළ දත්ත වලට කැමති අතර කොටස් ඒකාබද්ධ කිරීමට කැමති නැත.

දැන් දත්ත S3 හි ඇසුරුම් නොකළ (කියවීම: බෙදාගත්) සහ අර්ධ-ඇණවුම් කළ ආකෘතියේ තිබූ අතර, මට නැවත Spark වෙත ආපසු යා හැක. පුදුමයක් මා බලා සිටියේය: මට අවශ්‍ය දේ සාක්ෂාත් කර ගැනීමට මම නැවතත් අසමත් විය! දත්ත කොටස් කරන ආකාරය හරියටම ස්පාර්ක්ට පැවසීම ඉතා අපහසු විය. මම මෙය කළ විට පවා, බොහෝ කොටස් (95 දහසක්) ඇති බවත්, මම භාවිතා කළ විටත් පෙනී ගියේය coalesce ඔවුන්ගේ සංඛ්‍යාව සාධාරණ සීමාවන්ට අඩු කළා, මෙය මගේ කොටස් කිරීම විනාශ කළා. මෙය නිවැරදි කළ හැකි බව මට විශ්වාසයි, නමුත් දින කිහිපයක් සෙවීමෙන් පසුව මට විසඳුමක් සොයාගත නොහැකි විය. මම අවසානයේ Spark හි සියලු කාර්යයන් අවසන් කළෙමි, එය ටික වේලාවක් ගත වුවද සහ මගේ බෙදුණු Parquet ගොනු ඉතා කුඩා නොවීය (~200 KB). කෙසේ වෙතත්, දත්ත අවශ්ය වූ තැන විය.

AWK සහ R භාවිතයෙන් 25TB විග්‍රහ කිරීම
ඉතා කුඩා හා අසමාන, අපූරුයි!

දේශීය Spark විමසුම් පරීක්ෂා කිරීම

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: සරල ගැටළු විසඳන විට Spark හි වැඩි කාර්ය භාරයක් ඇත.

දක්ෂ ආකෘතියකින් දත්ත බාගත කිරීමෙන්, වේගය පරීක්ෂා කිරීමට මට හැකි විය. දේශීය Spark සේවාදායකයක් ක්‍රියාත්මක කිරීමට R ස්ක්‍රිප්ට් එකක් සකසන්න, පසුව නිශ්චිත Parquet කණ්ඩායම් ගබඩාවෙන් (bin) Spark දත්ත රාමුවක් පූරණය කරන්න. මම සියලු දත්ත පූරණය කිරීමට උත්සාහ කළ නමුත් කොටස් කිරීම හඳුනා ගැනීමට Sparklyr ලබා ගැනීමට නොහැකි විය.

sc <- Spark_connect(master = "local")

desired_snp <- 'rs34771739'

# Start a timer
start_time <- Sys.time()

# Load the desired bin into Spark
intensity_data <- sc %>% 
  Spark_read_Parquet(
    name = 'intensity_data', 
    path = get_snp_location(desired_snp),
    memory = FALSE )

# Subset bin to snp and then collect to local
test_subset <- intensity_data %>% 
  filter(SNP_Name == desired_snp) %>% 
  collect()

print(Sys.time() - start_time)

ක්රියාත්මක කිරීම තත්පර 29,415 කි. වඩා හොඳයි, නමුත් ඕනෑම දෙයක් මහා පරිමාණයෙන් පරීක්ෂා කිරීම සඳහා හොඳ නැත. මීට අමතරව, මට හැඹිලිය සමඟ දේවල් වේගවත් කිරීමට නොහැකි විය, මන්ද මම මතකයේ දත්ත රාමුවක් හැඹිලි කිරීමට උත්සාහ කරන විට, 50 ට අඩු දත්ත කට්ටලයකට 15 GB වඩා වැඩි මතකයක් වෙන් කළ විට පවා Spark සෑම විටම බිඳ වැටුණි.

AWK වෙත නැවත යන්න

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: AWK හි ආශ්‍රිත අරා ඉතා කාර්යක්ෂම වේ.

මට වැඩි වේගයක් ලබා ගත හැකි බව මට වැටහුණා. මට ඒක මතක් උනේ පුදුම විදියට AWK නිබන්ධනය Bruce Barnett විසිනි මම කියෙව්වා " නම් වූ අපූරු විශේෂාංගයක් ගැනආශ්රිත අරා" අත්‍යවශ්‍යයෙන්ම, මේවා ප්‍රධාන වටිනාකම් යුගල වන අතර, ඒවා කිසියම් හේතුවක් නිසා AWK හි වෙනස් ලෙස හැඳින්වූ අතර, එබැවින් මම කෙසේ හෝ ඒවා ගැන එතරම් සිතුවේ නැත. රෝමන් චෙප්ලියාකා "ආශ්‍රිත අරා" යන යෙදුම "ප්‍රධාන අගය යුගල" යන යෙදුමට වඩා බොහෝ පැරණි බව සිහිපත් කළේය. ඔබ වුවද Google Ngram හි යතුරු අගය බලන්න, ඔබ මෙම යෙදුම එහි නොදකිනු ඇත, නමුත් ඔබට ආශ්‍රිත අරාවන් හමුවනු ඇත! ඊට අමතරව, “ප්‍රධාන අගය යුගලය” බොහෝ විට දත්ත සමුදායන් සමඟ සම්බන්ධ වේ, එබැවින් එය හැෂ්මැප් එකක් සමඟ සංසන්දනය කිරීම වඩාත් අර්ථවත් කරයි. Spark භාවිතා නොකර මගේ SNPs bin table සහ raw data සමඟ සම්බන්ධ කිරීමට මෙම ආශ්‍රිත අරාවන් භාවිතා කළ හැකි බව මට වැටහුණා.

මෙය සිදු කිරීම සඳහා, AWK පිටපතෙහි මම බ්ලොක් එක භාවිතා කළෙමි BEGIN. මෙය පළමු දත්ත පේළිය ස්ක්‍රිප්ට් එකේ ප්‍රධාන කොටස වෙත යැවීමට පෙර ක්‍රියාත්මක වන කේත කොටසකි.

join_data.awk
BEGIN {
  FS=",";
  batch_num=substr(chunk,7,1);
  chunk_id=substr(chunk,15,2);
  while(getline < "snp_to_bin.csv") {bin[$1] = $2}
}
{
  print $0 > "chunked/chr_"chr"_bin_"bin[$1]"_"batch_num"_"chunk_id".csv"
}

කණ්ඩායම while(getline...) CSV කණ්ඩායම (බින්) වෙතින් සියලුම පේළි පූරණය කර, ආශ්‍රිත අරාව සඳහා යතුර ලෙස පළමු තීරුව (SNP නම) සකසන්න bin සහ දෙවන අගය (කණ්ඩායම) අගය ලෙස. එවිට බ්ලොක් එකේ { }, ප්‍රධාන ගොනුවේ සියලුම පේළි මත ක්‍රියාත්මක වන අතර, සෑම පේළියක්ම ප්‍රතිදාන ගොනුව වෙත යවනු ලැබේ, එයට එහි කණ්ඩායම (බින්) අනුව අද්විතීය නමක් ලැබේ: ..._bin_"bin[$1]"_....

විචල්යයන් batch_num и chunk_id ධාවන තත්ත්වය මගහැර නල මාර්ගයෙන් සපයන ලද දත්ත හා එක් එක් ක්‍රියාත්මක නූල් ක්‍රියාත්මක වේ parallel, එහිම අද්විතීය ගොනුවකට ලිවීය.

මම AWK සමඟ මගේ පෙර අත්හදා බැලීමෙන් ඉතිරි වූ සියලුම අමු දත්ත වර්ණදේහවල ෆෝල්ඩරවලට විසිරී ගිය බැවින්, දැන් මට වරකට එක් වර්ණදේහයක් සැකසීමට සහ S3 වෙත ගැඹුරු කොටස් කළ දත්ත යැවීමට තවත් Bash ස්ක්‍රිප්ට් එකක් ලිවිය හැකිය.

DESIRED_CHR='13'

# Download chromosome data from s3 and split into bins
aws s3 ls $DATA_LOC |
awk '{print $4}' |
grep 'chr'$DESIRED_CHR'.csv' |
parallel "echo 'reading {}'; aws s3 cp "$DATA_LOC"{} - | awk -v chr=""$DESIRED_CHR"" -v chunk="{}" -f split_on_chr_bin.awk"

# Combine all the parallel process chunks to single files and upload to rds using R
ls chunked/ |
cut -d '_' -f 4 |
sort -u |
parallel "echo 'zipping bin {}'; cat chunked/*_bin_{}_*.csv | ./upload_as_rds.R '$S3_DEST'/chr_'$DESIRED_CHR'_bin_{}.rds"
rm chunked/*

පිටපත කොටස් දෙකකින් සමන්විත වේ parallel.

පළමු කොටසේදී, අපේක්ෂිත වර්ණදේහයේ තොරතුරු අඩංගු සියලුම ගොනු වලින් දත්ත කියවනු ලැබේ, පසුව මෙම දත්ත නූල් හරහා බෙදා හරිනු ලැබේ, එමඟින් ගොනු සුදුසු කණ්ඩායම් (බින්) වෙත බෙදා හරිනු ලැබේ. එකම ගොනුවකට පොටවල් කිහිපයක් ලියන විට ධාවන තත්ත්වයන් මඟහරවා ගැනීමට, විවිධ ස්ථානවලට දත්ත ලිවීමට AWK ගොනු නාම ලබා දෙයි, උදා. chr_10_bin_52_batch_2_aa.csv. එහි ප්රතිඵලයක් වශයෙන්, තැටියේ බොහෝ කුඩා ගොනු නිර්මාණය වේ (මේ සඳහා මම ටෙරාබයිට් EBS වෙළුම් භාවිතා කළෙමි).

දෙවන කොටසේ සිට වාහකය parallel කණ්ඩායම් (බින්) හරහා ගොස් ඔවුන්ගේ තනි ගොනු පොදු CSV c බවට ඒකාබද්ධ කරයි catඉන්පසු ඒවා අපනයනය සඳහා යවයි.

R හි විකාශනය කරනවාද?

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: ඔබට සම්බන්ධ විය හැක stdin и stdout R ස්ක්‍රිප්ට් එකකින්, එබැවින් එය නල මාර්ගයේ භාවිතා කරන්න.

ඔබ ඔබේ Bash පිටපතේ මෙම පේළිය දැක ඇති: ...cat chunked/*_bin_{}_*.csv | ./upload_as_rds.R.... එය පහතින් ඇති R ස්ක්‍රිප්ට් එකට සියලුම සම්මිශ්‍රිත සමූහ ගොනු (බින්) පරිවර්තනය කරයි. {} විශේෂ තාක්ෂණික ක්රමයකි parallel, එය නිශ්චිත ප්‍රවාහයට යවන ඕනෑම දත්තයක් කෙලින්ම විධානයටම ඇතුල් කරයි. විකල්පය {#} අද්විතීය නූල් හැඳුනුම්පතක් සපයයි, සහ {%} රැකියා ස්ථාන අංකය නියෝජනය කරයි (නැවත නැවතත්, නමුත් කිසි විටෙක එකවර නොවේ). සියලු විකල්ප ලැයිස්තුවක් සොයාගත හැකිය ලේඛනගත කිරීම.

#!/usr/bin/env Rscript
library(readr)
library(aws.s3)

# Read first command line argument
data_destination <- commandArgs(trailingOnly = TRUE)[1]

data_cols <- list(SNP_Name = 'c', ...)

s3saveRDS(
  read_csv(
        file("stdin"), 
        col_names = names(data_cols),
        col_types = data_cols 
    ),
  object = data_destination
)

විචල්‍යයක් වූ විට file("stdin") වෙත සම්ප්රේෂණය වේ readr::read_csv, R ස්ක්‍රිප්ටයට පරිවර්තනය කරන ලද දත්ත රාමුවකට පටවනු ලැබේ, එය පෝරමයේ ඇත .rds- ගොනුව භාවිතා කරයි aws.s3 S3 වෙත කෙලින්ම ලියා ඇත.

RDS යනු ස්පීකර් ආචයනයේ අලංකාරයකින් තොරව Parquet හි කනිෂ්ඨ අනුවාදයක් වැනි දෙයකි.

Bash පිටපත ඉවර කළාට පස්සේ මට බණ්ඩල් එකක් ලැබුණා .rds-S3 හි පිහිටා ඇති ගොනු, මට කාර්යක්ෂම සම්පීඩනය සහ බිල්ට් වර්ග භාවිතා කිරීමට ඉඩ ලබා දුන්නේය.

තිරිංග R භාවිතය තිබියදීත්, සෑම දෙයක්ම ඉතා ඉක්මනින් ක්රියාත්මක විය. R හි දත්ත කියවීමට සහ ලිවීමට ඇති කොටස් ඉතා ප්‍රශස්ත වීම පුදුමයක් නොවේ. එක් මධ්‍යම ප්‍රමාණයේ වර්ණදේහයක් පරීක්ෂා කිරීමෙන් පසුව, කාර්යය C5n.4xl අවස්ථාවක පැය දෙකකින් පමණ සම්පූර්ණ විය.

S3 සීමාවන්

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: ස්මාර්ට් පාත් ක්‍රියාවට නැංවීමට ස්තූතියි, S3 බොහෝ ගොනු හැසිරවිය හැක.

S3 එකට මාරු කරපු ගොඩක් ෆයිල් හසුරුවන්න පුළුවන් වෙයිද කියලා මම බය වුණා. මට ගොනු නාම අර්ථවත් කළ හැකිය, නමුත් S3 ඒවා සොයන්නේ කෙසේද?

AWK සහ R භාවිතයෙන් 25TB විග්‍රහ කිරීම
S3 හි ඇති ෆෝල්ඩර ප්‍රදර්ශනය සඳහා පමණි, ඇත්ත වශයෙන්ම පද්ධතිය සංකේතය ගැන උනන්දුවක් නොදක්වයි /. S3 FAQ පිටුවෙන්.

යම් ආකාරයක හෑෂ් වගුවක හෝ ලේඛන පාදක දත්ත ගබඩාවක සරල යතුරක් ලෙස S3 යම් ගොනුවකට යන මාර්ගය නියෝජනය කරන බව පෙනේ. බාල්දියක් මේසයක් ලෙස සැලකිය හැකි අතර, ගොනු එම වගුවේ වාර්තා ලෙස සැලකිය හැකිය.

Amazon හි ලාභ ඉපැයීමට වේගය සහ කාර්යක්ෂමතාව වැදගත් වන බැවින්, මෙම key-as-a-file-path පද්ධතිය ප්‍රශස්ත ලෙස ප්‍රශස්ත කිරීම පුදුමයක් නොවේ. මම ශේෂයක් සොයා ගැනීමට උත්සාහ කළෙමි: එවිට මට බොහෝ ලබා ගැනීමේ ඉල්ලීම් කිරීමට අවශ්‍ය නොවීය, නමුත් ඉල්ලීම් ඉක්මනින් ක්‍රියාත්මක විය. බින් ගොනු 20 ක් පමණ සෑදීම වඩාත් සුදුසු බව පෙනී ගියේය. මම හිතන්නේ අපි දිගටම ප්‍රශස්තිකරණය කළහොත්, අපට වේගයේ වැඩි වීමක් ලබා ගත හැකිය (උදාහරණයක් ලෙස, දත්ත සඳහා විශේෂ බාල්දියක් සෑදීම, එමඟින් බැලීමේ වගුවේ ප්‍රමාණය අඩු වේ). නමුත් වැඩිදුර අත්හදා බැලීම් සඳහා කාලය හෝ මුදල් තිබුණේ නැත.

හරස් ගැළපුම ගැන කුමක් කිව හැකිද?

මා ඉගෙන ගත් දේ: කාලය නාස්ති වීමට අංක එක හේතුව ඔබේ ගබඩා ක්‍රමය අකාලයේ ප්‍රශස්ත කිරීමයි.

මෙම අවස්ථාවේදී, ඔබෙන්ම මෙසේ ඇසීම ඉතා වැදගත් වේ: "අයිතිකාර ගොනු ආකෘතියක් භාවිතා කරන්නේ ඇයි?" හේතුව පැටවීමේ වේගය (gzipped CSV ගොනු පූරණය වීමට 7 ගුණයක් වැඩි කාලයක් ගත විය) සහ අපගේ කාර්ය ප්‍රවාහයන් සමඟ ගැළපීමයි. Spark load නොමැතිව R හට පහසුවෙන් Parquet (හෝ Arrow) ගොනු පූරණය කළ හැකිද යන්න මම නැවත සලකා බැලිය හැක. අපගේ විද්‍යාගාරයේ සිටින සියලුම දෙනා R භාවිතා කරන අතර, මට දත්ත වෙනත් ආකෘතියකට පරිවර්තනය කිරීමට අවශ්‍ය නම්, මා සතුව තවමත් මුල් පෙළ දත්ත තිබේ, එබැවින් මට නැවත නල මාර්ගය ධාවනය කළ හැක.

වැඩ බෙදීම

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: රැකියා අතින් ප්‍රශස්ත කිරීමට උත්සාහ නොකරන්න, පරිගණකයට එය කිරීමට ඉඩ දෙන්න.

මම එක් වර්ණදේහයක කාර්ය ප්‍රවාහය නිදොස් කර ඇත, දැන් මට අනෙක් සියලුම දත්ත සැකසීමට අවශ්‍යයි.
මට පරිවර්තනය සඳහා EC2 අවස්ථා කිහිපයක් මතු කිරීමට අවශ්‍ය විය, නමුත් ඒ සමඟම විවිධ සැකසුම් රැකියා හරහා ඉතා අසමතුලිත බරක් ලබා ගැනීමට මම බිය විය (Spark අසමතුලිත කොටස් වලින් පීඩා වින්දා සේම). ඊට අමතරව, AWS ගිණුම් සඳහා අවස්ථා 10ක පෙරනිමි සීමාවක් ඇති නිසා, එක් වර්ණදේහයකට එක් අවස්ථාවක් වැඩි කිරීමට මා උනන්දු වූයේ නැත.

පසුව මම සැකසුම් රැකියා ප්‍රශස්ත කිරීම සඳහා R හි පිටපතක් ලිවීමට තීරණය කළෙමි.

පළමුව, එක් එක් වර්ණදේහයේ ගබඩා ඉඩ ප්‍රමාණය ගණනය කිරීමට මම S3 ගෙන් ඉල්ලා සිටියෙමි.

library(aws.s3)
library(tidyverse)

chr_sizes <- get_bucket_df(
  bucket = '...', prefix = '...', max = Inf
) %>% 
  mutate(Size = as.numeric(Size)) %>% 
  filter(Size != 0) %>% 
  mutate(
    # Extract chromosome from the file name 
    chr = str_extract(Key, 'chr.{1,4}.csv') %>%
             str_remove_all('chr|.csv')
  ) %>% 
  group_by(chr) %>% 
  summarise(total_size = sum(Size)/1e+9) # Divide to get value in GB



# A tibble: 27 x 2
   chr   total_size
   <chr>      <dbl>
 1 0           163.
 2 1           967.
 3 10          541.
 4 11          611.
 5 12          542.
 6 13          364.
 7 14          375.
 8 15          372.
 9 16          434.
10 17          443.
# … with 17 more rows

ඊට පස්සේ මම සම්පූර්ණ ප්‍රමාණය ගන්නා, වර්ණදේහවල අනුපිළිවෙල වෙනස් කරන, ඒවා කණ්ඩායම් වලට බෙදන ශ්‍රිතයක් ලිව්වා. num_jobs සහ සියලු සැකසුම් රැකියා වල ප්‍රමාණයන් කෙතරම් වෙනස් දැයි ඔබට කියයි.

num_jobs <- 7
# How big would each job be if perfectly split?
job_size <- sum(chr_sizes$total_size)/7

shuffle_job <- function(i){
  chr_sizes %>%
    sample_frac() %>% 
    mutate(
      cum_size = cumsum(total_size),
      job_num = ceiling(cum_size/job_size)
    ) %>% 
    group_by(job_num) %>% 
    summarise(
      job_chrs = paste(chr, collapse = ','),
      total_job_size = sum(total_size)
    ) %>% 
    mutate(sd = sd(total_job_size)) %>% 
    nest(-sd)
}

shuffle_job(1)



# A tibble: 1 x 2
     sd data            
  <dbl> <list>          
1  153. <tibble [7 × 3]>

ඊට පස්සේ මම purrr භාවිතා කර shuffles දහසක් හරහා දිව ගොස් හොඳම දේ තෝරා ගත්තා.

1:1000 %>% 
  map_df(shuffle_job) %>% 
  filter(sd == min(sd)) %>% 
  pull(data) %>% 
  pluck(1)

ඉතින් මම ප්‍රමාණයෙන් බොහෝ සමාන කාර්යයන් සමූහයක් සමඟ අවසන් කළෙමි. එතකොට ඉතුරු උනේ මගේ කලින් කරපු Bash script එක ලොකු loop එකක දවටන එක විතරයි for. මෙම ප්‍රශස්තකරණය ලිවීමට මිනිත්තු 10ක් පමණ ගත විය. තවද මෙය අසමතුලිත නම් කාර්යයන් අතින් නිර්මාණය කිරීමට මා වැය කරන මුදලට වඩා බෙහෙවින් අඩුය. එබැවින්, මෙම මූලික ප්‍රශස්තිකරණය සමඟ මා නිවැරදි යැයි මම සිතමි.

for DESIRED_CHR in "16" "9" "7" "21" "MT"
do
# Code for processing a single chromosome
fi

අවසානයේ මම වසා දැමීමේ විධානය එකතු කරමි:

sudo shutdown -h now

... සහ සියල්ල සාර්ථක විය! AWS CLI භාවිතා කරමින්, මම විකල්පය භාවිතා කරමින් අවස්ථා මතු කළෙමි user_data සැකසීම සඳහා ඔවුන්ගේ කාර්යයන් පිළිබඳ Bash ස්ක්‍රිප්ට් ලබා දුන්නේය. ඒවා ක්‍රියාත්මක වී ස්වයංක්‍රීයව ක්‍රියා විරහිත විය, එබැවින් මම අමතර සැකසුම් බලයක් සඳහා නොගෙවමි.

aws ec2 run-instances ...
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=<<job_name>>}]" 
--user-data file://<<job_script_loc>>

අපි ඇසුරුම් කරමු!

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: API භාවිතයේ පහසුව සහ නම්‍යශීලී බව සඳහා සරල විය යුතුය.

අන්තිමට මම දත්ත නියම තැනට සහ පෝරමයට ගත්තා. ඉතිරිව තිබුණේ මගේ සගයන්ට පහසු වන පරිදි දත්ත භාවිතා කිරීමේ ක්‍රියාවලිය හැකිතාක් සරල කිරීම පමණි. මට ඉල්ලීම් සෑදීම සඳහා සරල API එකක් සෑදීමට අවශ්‍ය විය. අනාගතයේදී මම මාරු වීමට තීරණය කරන්නේ නම් .rds Parquet ගොනු සඳහා, මෙය මට ගැටලුවක් විය යුතුය, මගේ සගයන්ට නොවේ. මේ සඳහා මම අභ්යන්තර R පැකේජයක් සෑදීමට තීරණය කළා.

කාර්යයක් වටා සංවිධානය කරන ලද දත්ත ප්‍රවේශ ශ්‍රිත කිහිපයක් පමණක් අඩංගු ඉතා සරල පැකේජයක් ගොඩනඟා ලේඛනගත කරන්න get_snp. මමත් මගේ සගයන් වෙනුවෙන් වෙබ් අඩවියක් හැදුවා pkgdown, එබැවින් ඔවුන්ට පහසුවෙන් උදාහරණ සහ ලේඛන දැකිය හැකිය.

AWK සහ R භාවිතයෙන් 25TB විග්‍රහ කිරීම

ස්මාර්ට් හැඹිලිගත කිරීම

මම මොනවද ඉගෙන ගෙන තියෙන්නේ: ඔබේ දත්ත හොඳින් සූදානම් නම්, හැඹිලිගත කිරීම පහසු වනු ඇත!

එක් ප්‍රධාන කාර්ය ප්‍රවාහයක් SNP පැකේජයට එකම විශ්ලේෂණ ආකෘතිය යෙදූ බැවින්, මම මගේ වාසියට binning භාවිතා කිරීමට තීරණය කළෙමි. SNP හරහා දත්ත සම්ප්‍රේෂණය කරන විට, සමූහයේ (බින්) සියලුම තොරතුරු ආපසු ලබා දුන් වස්තුවට අමුණා ඇත. එනම් පැරණි විමසුම් (න්‍යාය වශයෙන්) නව විමසුම් සැකසීම වේගවත් කළ හැක.

# Part of get_snp()
...
  # Test if our current snp data has the desired snp.
  already_have_snp <- desired_snp %in% prev_snp_results$snps_in_bin

  if(!already_have_snp){
    # Grab info on the bin of the desired snp
    snp_results <- get_snp_bin(desired_snp)

    # Download the snp's bin data
    snp_results$bin_data <- aws.s3::s3readRDS(object = snp_results$data_loc)
  } else {
    # The previous snp data contained the right bin so just use it
    snp_results <- prev_snp_results
  }
...

පැකේජය තැනීමේදී, විවිධ ක්‍රම භාවිතා කරන විට වේගය සංසන්දනය කිරීමට මම බොහෝ මිණුම් සලකුණු ක්‍රියාත්මක කළෙමි. සමහර අවස්ථාවලදී ප්රතිඵල අනපේක්ෂිත බැවින් මෙය නොසලකා හරින ලෙස මම නිර්දේශ කරමි. උදාහරණ වශයෙන්, dplyr::filter සුචිගත කිරීම මත පදනම් වූ පෙරහන භාවිතයෙන් පේළි ග්‍රහණය කර ගැනීමට වඩා ඉතා වේගවත් වූ අතර, පෙරූ දත්ත රාමුවකින් තනි තීරුවක් ලබා ගැනීම සුචිගත කිරීමේ වාක්‍ය ඛණ්ඩ භාවිතා කිරීමට වඩා වේගවත් විය.

වස්තුව බව කරුණාවෙන් සලකන්න prev_snp_results යතුර අඩංගු වේ snps_in_bin. මෙය සමූහයක (බින්) සියලුම අද්විතීය SNP වල අරාවකි, ඔබට දැනටමත් පෙර විමසුමකින් දත්ත තිබේදැයි ඉක්මනින් පරීක්ෂා කිරීමට ඉඩ සලසයි. මෙම කේතය සමඟ සමූහයක (බින්) සියලුම SNP හරහා ලූප් කිරීම ද එය පහසු කරයි:

# Get bin-mates
snps_in_bin <- my_snp_results$snps_in_bin

for(current_snp in snps_in_bin){
  my_snp_results <- get_snp(current_snp, my_snp_results)
  # Do something with results 
}

ප්රතිඵල

දැන් අපට (සහ බැරෑරුම් ලෙස ආරම්භ කර ඇත) අපට කලින් ප්‍රවේශ විය නොහැකි වූ ආකෘති සහ අවස්ථා ධාවනය කළ හැකිය. හොඳම දෙය නම් මගේ රසායනාගාර සගයන්ට කිසිදු සංකූලතාවයක් ගැන සිතීමට අවශ්‍ය නොවීමයි. ඔවුන්ට ඇත්තේ වැඩ කරන කාර්යයක් පමණි.

පැකේජය ඔවුන්ට විස්තර ඉතිරි කළත්, මම හෙට හදිසියේම අතුරුදහන් වුවහොත් ඔවුන්ට එය තේරුම් ගත හැකි තරම් දත්ත ආකෘතිය සරල කිරීමට මම උත්සාහ කළෙමි.

වේගය සැලකිය යුතු ලෙස වැඩි වී ඇත. අපි සාමාන්‍යයෙන් ක්‍රියාකාරීව සැලකිය යුතු ජෙනෝම කොටස් පරිලෝකනය කරමු. මීට පෙර, අපට මෙය කළ නොහැකි විය (එය ඉතා මිල අධික විය), නමුත් දැන්, කණ්ඩායම් (බින්) ව්‍යුහය සහ හැඹිලිය සඳහා ස්තූතිවන්ත වන අතර, එක් SNP සඳහා ඉල්ලීමක් සාමාන්‍යයෙන් තත්පර 0,1 කට වඩා අඩු කාලයක් ගත වන අතර දත්ත භාවිතය එසේ වේ. S3 සඳහා මිල රටකජු වලට වඩා අඩුය.

නිගමනය

මෙම ලිපිය කිසිසේත්ම මාර්ගෝපදේශයක් නොවේ. විසඳුම තනි පුද්ගලයෙකු බවට පත් වූ අතර, නිසැකවම ප්රශස්ත නොවේ. ඒ වෙනුවට එය සංචාරක සටහනකි. එවැනි තීරණ සම්පූර්ණයෙන්ම හිස තුළ නොපෙන්වන බවත්, ඒවා අත්හදා බැලීමේ සහ දෝෂයේ ප්‍රති result ලයක් බවත් අන් අය තේරුම් ගැනීමට මට අවශ්‍යය. එසේම, ඔබ දත්ත විද්යාඥයෙකු සොයන්නේ නම්, මෙම මෙවලම් ඵලදායී ලෙස භාවිතා කිරීම සඳහා අත්දැකීම් අවශ්ය වන අතර, අත්දැකීම් සඳහා මුදල් වැය වන බව මතක තබා ගන්න. මට ගෙවීමට හැකියාවක් තිබීම ගැන මම සතුටු වෙමි, නමුත් මට වඩා හොඳින් එකම රැකියාව කළ හැකි තවත් බොහෝ දෙනෙකුට මුදල් නොමැතිකම නිසා උත්සාහ කිරීමට පවා අවස්ථාවක් නොලැබෙනු ඇත.

විශාල දත්ත මෙවලම් බහුකාර්ය වේ. ඔබට කාලය තිබේ නම්, ස්මාර්ට් දත්ත පිරිසිදු කිරීම, ගබඩා කිරීම සහ නිස්සාරණය කිරීමේ ක්‍රම භාවිතයෙන් ඔබට නිසැකවම වේගවත් විසඳුමක් ලිවිය හැකිය. අවසානයේ එය පිරිවැය-ප්‍රතිලාභ විශ්ලේෂණයකට පැමිණේ.

මම ඉගෙන ගත් දේ:

  • වරකට 25 TB විග්‍රහ කිරීමට ලාභදායී ක්‍රමයක් නොමැත;
  • ඔබගේ Parquet ගොනු වල ප්‍රමාණය සහ ඒවායේ සංවිධානය ගැන සැලකිලිමත් වන්න;
  • Spark හි කොටස් සමතුලිත විය යුතුය;
  • පොදුවේ ගත් කල, කොටස් මිලියන 2,5 ක් සෑදීමට උත්සාහ නොකරන්න;
  • Spark පිහිටුවීම මෙන්ම වර්ග කිරීම තවමත් අපහසුය;
  • සමහර විට විශේෂ දත්ත සඳහා විශේෂ විසඳුම් අවශ්ය වේ;
  • Spark aggregation වේගවත්, නමුත් කොටස් කිරීම තවමත් මිල අධිකයි;
  • ඔවුන් ඔබට මූලික කරුණු උගන්වන විට නිදා නොගන්න, 1980 ගණන්වලදී යමෙකු දැනටමත් ඔබේ ගැටලුව විසඳා ඇත;
  • gnu parallel - මෙය ඉන්ද්‍රජාලික දෙයක්, සෑම කෙනෙකුම එය භාවිතා කළ යුතුය;
  • Spark සම්පීඩිත නොකළ දත්ත වලට කැමති අතර කොටස් ඒකාබද්ධ කිරීමට කැමති නැත;
  • සරල ගැටළු විසඳන විට Spark හි වැඩි කාර්ය භාරයක් ඇත;
  • AWK හි ආශ්‍රිත අරා ඉතා කාර්යක්ෂම වේ;
  • ඔබට සම්බන්ධ විය හැක stdin и stdout R ස්ක්‍රිප්ට් එකකින්, එබැවින් එය නල මාර්ගයේ භාවිතා කරන්න;
  • ස්මාර්ට් මාර්ගය ක්‍රියාත්මක කිරීමට ස්තූතියි, S3 බොහෝ ගොනු සැකසීමට හැකිය;
  • කාලය නාස්ති කිරීමට ප්‍රධාන හේතුව අකාලයේ ඔබේ ගබඩා ක්‍රමය ප්‍රශස්ත කිරීමයි;
  • කාර්යයන් අතින් ප්‍රශස්ත කිරීමට උත්සාහ නොකරන්න, පරිගණකයට එය කිරීමට ඉඩ දෙන්න;
  • භාවිතයේ පහසුව සහ නම්‍යශීලී බව සඳහා API සරල විය යුතුය;
  • ඔබගේ දත්ත හොඳින් සකස් කර ඇත්නම්, හැඹිලිගත කිරීම පහසු වනු ඇත!

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

අදහස් එක් කරන්න