Ṣiṣayẹwo 25TB ni lilo AWK ati R

Ṣiṣayẹwo 25TB ni lilo AWK ati R
Bawo ni lati ka nkan yii: Mo tọrọ gafara fun ọrọ ti o gun ati rudurudu. Lati fi akoko pamọ, Mo bẹrẹ ori kọọkan pẹlu ifihan “Ohun ti Mo Kọ”, eyiti o ṣe akopọ ohun pataki ti ipin naa ni awọn gbolohun ọrọ kan tabi meji.

"O kan fi ojutu han mi!" Ti o ba kan fẹ lati rii ibiti mo ti wa, lẹhinna foju si ori “Didi Inventive Die,” ṣugbọn Mo ro pe o nifẹ diẹ sii ati wulo lati ka nipa ikuna.

Laipẹ mi ni iṣẹ ṣiṣe lati ṣeto ilana kan fun sisẹ iwọn didun nla ti awọn ilana DNA aise (imọ-ẹrọ ni chirún SNP kan). Iwulo ni lati yara gba data nipa ipo jiini ti a fun (ti a pe ni SNP) fun awoṣe atẹle ati awọn iṣẹ ṣiṣe miiran. Lilo R ati AWK, Mo ni anfani lati sọ di mimọ ati ṣeto data ni ọna adayeba, yiyara sisẹ ibeere pupọ. Eyi ko rọrun fun mi ati pe o nilo ọpọlọpọ awọn iterations. Nkan yii yoo ran ọ lọwọ lati yago fun diẹ ninu awọn aṣiṣe mi ati ṣafihan ohun ti Mo pari pẹlu rẹ.

Ni akọkọ, diẹ ninu awọn alaye iforo.

Data

Ile-iṣẹ iṣelọpọ alaye jiini ti ile-ẹkọ giga wa fun wa ni data ni irisi 25 TB TSV. Mo gba wọn pin si awọn akopọ 5, ti fisinuirindigbindigbin nipasẹ Gzip, ọkọọkan ninu eyiti o ni awọn faili gigagabyte mẹrin 240 ninu. Lara kọọkan ni data ninu fun SNP kan lati ọdọ ẹni kọọkan. Ni apapọ, data lori ~ 2,5 milionu SNPs ati ~ 60 ẹgbẹrun eniyan ni a gbejade. Ni afikun si alaye SNP, awọn faili ni ọpọlọpọ awọn ọwọn pẹlu awọn nọmba ti n ṣe afihan ọpọlọpọ awọn abuda, gẹgẹbi kikankikan, igbohunsafẹfẹ ti awọn oriṣiriṣi alleles, ati bẹbẹ lọ. Ni apapọ o wa nipa awọn ọwọn 30 pẹlu awọn iye alailẹgbẹ.

Ero

Gẹgẹbi pẹlu eyikeyi iṣẹ akanṣe iṣakoso data, ohun pataki julọ ni lati pinnu bi a ṣe le lo data naa. Fun idi eyi a yoo yan awọn awoṣe pupọ julọ ati ṣiṣan iṣẹ fun SNP da lori SNP. Iyẹn ni, a yoo nilo data nikan lori SNP kan ni akoko kan. Mo ni lati kọ bi a ṣe le gba gbogbo awọn igbasilẹ ti o ni nkan ṣe pẹlu ọkan ninu awọn 2,5 milionu SNP ni irọrun, ni iyara ati ni olowo poku bi o ti ṣee.

Bii o ṣe le ṣe eyi

Lati sọ cliché ti o yẹ:

Emi ko kuna ni ẹgbẹrun igba, Mo kan ṣe awari awọn ọna ẹgbẹrun lati yago fun sisọ opo data ni ọna kika ore-ibeere kan.

Akọkọ gbiyanju

Kini mo ti kọ: Ko si ọna olowo poku lati ṣe itupalẹ 25 TB ni akoko kan.

Lehin ti o ti gba ẹkọ naa “Awọn ọna To ti ni ilọsiwaju fun Ṣiṣeto Data Nla” ni Ile-ẹkọ giga Vanderbilt, Mo ni idaniloju pe ẹtan naa wa ninu apo naa. Yoo gba to wakati kan tabi meji lati ṣeto olupin Hive lati ṣiṣẹ nipasẹ gbogbo data naa ki o jabo abajade. Niwọn igba ti data wa ti wa ni ipamọ ni AWS S3, Mo lo iṣẹ naa Athena, eyiti o fun ọ laaye lati lo awọn ibeere Hive SQL si data S3. O ko nilo lati ṣeto / gbe iṣupọ Ile-iwe kan, ati pe o tun sanwo fun data ti o n wa nikan.

Lẹhin ti Mo fihan data mi Athena ati ọna kika rẹ, Mo sare diẹ ninu awọn idanwo pẹlu awọn ibeere bii eyi:

select * from intensityData limit 10;

Ati ni kiakia gba awọn abajade ti iṣeto daradara. Ṣetan.

Titi a fi gbiyanju lati lo data naa ninu iṣẹ wa…

A beere lọwọ mi lati fa gbogbo alaye SNP jade lati ṣe idanwo awoṣe lori. Mo ran ibeere naa:


select * from intensityData 
where snp = 'rs123456';

... o si bẹrẹ lati duro. Lẹhin iṣẹju mẹjọ ati diẹ sii ju 4 TB ti data ti o beere, Mo gba abajade naa. Awọn idiyele Athena nipasẹ iwọn data ti a rii, $ 5 fun terabyte. Nitorinaa ibeere ẹyọkan yii jẹ $20 ati iṣẹju mẹjọ ti iduro. Lati ṣiṣe awoṣe lori gbogbo awọn data, a ni lati duro 38 ọdun ati san $ 50 milionu. O han ni, eyi ko dara fun wa.

O jẹ pataki lati lo Parquet ...

Kini mo ti kọ: Ṣọra pẹlu iwọn awọn faili Parquet rẹ ati agbari wọn.

Mo kọkọ gbiyanju lati ṣatunṣe ipo naa nipa yiyipada gbogbo awọn TSV si Awọn faili Parquet. Wọn rọrun fun ṣiṣẹ pẹlu awọn eto data nla nitori alaye ti o wa ninu wọn ti wa ni ipamọ ni fọọmu ọwọn: iwe kọọkan wa ni apakan iranti / disk tirẹ, ni idakeji si awọn faili ọrọ, ninu eyiti awọn ori ila ni awọn eroja ti iwe kọọkan. Ati pe ti o ba nilo lati wa nkan kan, lẹhinna kan ka iwe ti o nilo. Ni afikun, faili kọọkan tọju ọpọlọpọ awọn iye sinu iwe kan, nitorinaa ti iye ti o n wa ko ba si ni sakani iwe, Spark kii yoo padanu akoko ọlọjẹ gbogbo faili naa.

Mo ran iṣẹ ti o rọrun AWS lẹ pọ lati ṣe iyipada awọn TSV wa si Parquet ati sọ awọn faili tuntun silẹ sinu Athena. O gba to wakati 5. Ṣugbọn nigbati mo ran ibeere naa, o gba nipa iye akoko kanna ati owo kekere diẹ lati pari. Otitọ ni pe Spark, ngbiyanju lati mu iṣẹ-ṣiṣe naa pọ si, nirọrun ṣiṣi silẹ ṣoki TSV kan ki o fi sii sinu chunk Parquet tirẹ. Ati nitori pe chunk kọọkan tobi to lati mu gbogbo awọn igbasilẹ ti ọpọlọpọ eniyan, faili kọọkan ni gbogbo awọn SNPs, nitorina Spark ni lati ṣii gbogbo awọn faili lati yọ alaye ti o nilo.

O yanilenu, aiyipada Parquet (ati iṣeduro) iru funmorawon, snappy, kii ṣe pipin. Nitorinaa, alaṣẹ kọọkan ti di lori iṣẹ ṣiṣe ti ṣiṣi silẹ ati ṣe igbasilẹ data 3,5 GB ni kikun.

Ṣiṣayẹwo 25TB ni lilo AWK ati R

Jẹ ki a loye iṣoro naa

Kini mo ti kọ: Tito lẹsẹsẹ jẹ nira, paapaa ti data ba pin.

Ó dàbí ẹni pé ní báyìí mo lóye kókó ìṣòro náà. Mo nilo lati to awọn data nikan nipasẹ iwe SNP, kii ṣe nipasẹ eniyan. Lẹhinna ọpọlọpọ awọn SNPs yoo wa ni ipamọ ni ṣoki data ọtọtọ, ati lẹhinna iṣẹ "ọlọgbọn" ti Parquet "ṣii nikan ti iye ba wa ni ibiti" yoo fi ara rẹ han ni gbogbo ogo rẹ. Laanu, tito lẹsẹsẹ nipasẹ awọn ọkẹ àìmọye awọn ori ila ti o tuka kaakiri iṣupọ kan fihan pe o jẹ iṣẹ ṣiṣe ti o nira.

Ni pato AWS ko fẹ lati funni ni agbapada nitori idi “Mo jẹ ọmọ ile-iwe ti o ni idamu”. Lẹhin ti Mo ran lẹsẹsẹ lori Amazon Glue, o ṣiṣẹ fun awọn ọjọ 2 ati kọlu.

Kini nipa ipinpin?

Kini mo ti kọ: Awọn ipin ni Spark gbọdọ jẹ iwọntunwọnsi.

Lẹhinna Mo wa pẹlu imọran ti pinpin data ni awọn chromosomes. O wa 23 ninu wọn (ati pupọ diẹ sii ti o ba ṣe akiyesi DNA mitochondrial ati awọn agbegbe ti ko ni aworan).
Eyi yoo gba ọ laaye lati pin data si awọn ege kekere. Ti o ba ṣafikun laini kan si iṣẹ okeere sipaki ni iwe afọwọkọ Lẹ pọ partition_by = "chr", lẹhinna data yẹ ki o pin si awọn buckets.

Ṣiṣayẹwo 25TB ni lilo AWK ati R
Jinomisi ni ọpọlọpọ awọn ajẹkù ti a npe ni chromosomes.

Laanu, ko ṣiṣẹ. Awọn chromosomes ni awọn titobi oriṣiriṣi, eyiti o tumọ si iye alaye ti o yatọ. Eyi tumọ si pe awọn iṣẹ-ṣiṣe ti Spark fi ranṣẹ si awọn oṣiṣẹ ko ni iwọntunwọnsi ati pari laiyara nitori diẹ ninu awọn apa ti pari ni kutukutu ati pe wọn ko ṣiṣẹ. Sibẹsibẹ, awọn iṣẹ-ṣiṣe ti pari. Ṣugbọn nigbati o ba beere fun SNP kan, aiṣedeede naa tun fa awọn iṣoro. Iye owo sisẹ awọn SNP lori awọn chromosomes nla (iyẹn ni, nibiti a fẹ lati gba data) ti dinku nikan nipa iwọn 10. Pupọ, ṣugbọn ko to.

Ti a ba pin si awọn ẹya kekere paapaa?

Kini mo ti kọ: Maṣe gbiyanju lati ṣe awọn ipin miliọnu 2,5 rara.

Mo pinnu lati jade gbogbo rẹ ati pin SNP kọọkan. Eyi ṣe idaniloju pe awọn ipin jẹ iwọn dogba. ORO BURUKU NI. Mo lo Lẹ pọ ati fikun laini alaiṣẹ kan partition_by = 'snp'. Iṣẹ naa bẹrẹ ati bẹrẹ lati ṣiṣẹ. Ni ọjọ kan Mo ṣayẹwo ati rii pe ko si nkankan ti a kọ si S3, nitorinaa Mo pa iṣẹ naa. O dabi pe Glue n kọ awọn faili agbedemeji si ipo ti o farapamọ ni S3, ọpọlọpọ awọn faili, boya miliọnu meji. Bi abajade, aṣiṣe mi jẹ diẹ sii ju ẹgbẹrun dọla ati pe ko ṣe itẹlọrun olutọtọ mi.

Pipin + yiyan

Kini mo ti kọ: Tito lẹsẹsẹ jẹ ṣi nira, bi tun ṣe Spark.

Igbiyanju ikẹhin mi ni pipin jẹ pẹlu mi pin awọn chromosomes ati lẹhinna tito ipin kọọkan. Ni imọran, eyi yoo yara ibeere kọọkan nitori pe data SNP ti o fẹ ni lati wa laarin awọn chunks Parquet diẹ laarin iwọn ti a fun. Laanu, tito lẹsẹsẹ paapaa data ipin tan jade lati jẹ iṣẹ-ṣiṣe ti o nira. Bi abajade, Mo yipada si EMR fun iṣupọ aṣa ati lo awọn igba agbara mẹjọ (C5.4xl) ati Sparklyr lati ṣẹda iṣan-iṣẹ ti o ni irọrun diẹ sii…

# 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')
  )

... sibẹsibẹ, iṣẹ naa ko ti pari. Mo tunto rẹ ni awọn ọna oriṣiriṣi: pọ si ipin iranti iranti fun oluṣakoso ibeere kọọkan, awọn apa ti a lo pẹlu iye iranti nla, lo awọn oniyipada igbohunsafefe (awọn oniyipada igbohunsafefe), ṣugbọn ni gbogbo igba ti awọn wọnyi yipada lati jẹ awọn iwọn idaji, ati ni diėdiė awọn alaṣẹ bẹrẹ. lati kuna titi ohun gbogbo yoo duro.

Mo n di ẹda diẹ sii

Kini mo ti kọ: Nigba miiran data pataki nilo awọn solusan pataki.

Kọọkan SNP ni iye ipo kan. Eyi jẹ nọmba ti o baamu si nọmba awọn ipilẹ pẹlu chromosome rẹ. Eyi jẹ ọna ti o wuyi ati adayeba lati ṣeto data wa. Ni akọkọ Mo fẹ lati pin nipasẹ awọn agbegbe ti chromosome kọọkan. Fun apẹẹrẹ, awọn ipo 1 - 2000, 2001 - 4000, ati bẹbẹ lọ. Ṣugbọn iṣoro naa ni pe awọn SNP ko ni pinpin ni deede kọja awọn chromosomes, nitorinaa awọn iwọn ẹgbẹ yoo yatọ pupọ.

Ṣiṣayẹwo 25TB ni lilo AWK ati R

Bi abajade, Mo wa si idinku awọn ipo si awọn ẹka (ipo). Lilo data ti o ti gba tẹlẹ, Mo ran ibeere kan lati gba atokọ ti awọn SNP alailẹgbẹ, awọn ipo wọn ati awọn chromosomes. Lẹhinna Mo ṣeto data naa laarin chromosome kọọkan ati gba awọn SNP sinu awọn ẹgbẹ (bin) ti iwọn ti a fun. Jẹ ki a sọ 1000 SNP kọọkan. Eyi fun mi ni ibatan SNP-si-ẹgbẹ-fun-chromosome.

Ni ipari, Mo ṣe awọn ẹgbẹ (bin) ti 75 SNPs, idi naa yoo ṣe alaye ni isalẹ.

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

Akọkọ gbiyanju pẹlu Spark

Kini mo ti kọ: Sipaki alaropo ni sare, ṣugbọn ipin jẹ ṣi gbowolori.

Mo fẹ lati ka fireemu data kekere yii (awọn ori ila miliọnu 2,5) sinu Spark, darapọ pẹlu data aise, lẹhinna pin si nipasẹ ọwọn tuntun ti a ṣafikun 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')
  )

Mo lo sdf_broadcast(), nitorina Spark mọ pe o yẹ ki o fi aaye data ranṣẹ si gbogbo awọn apa. Eyi wulo ti data ba kere ni iwọn ati pe o nilo fun gbogbo awọn iṣẹ ṣiṣe. Bibẹẹkọ, Spark n gbiyanju lati jẹ ọlọgbọn ati pinpin data bi o ṣe nilo, eyiti o le fa idinku.

Ati lẹẹkansi, ero mi ko ṣiṣẹ: awọn iṣẹ-ṣiṣe ti ṣiṣẹ fun igba diẹ, pari iṣọkan, ati lẹhinna, gẹgẹbi awọn alaṣẹ ti a ṣe ifilọlẹ nipasẹ pipin, wọn bẹrẹ si kuna.

Nfi AWK

Kini mo ti kọ: Maṣe sun nigba ti a nkọ ọ ni awọn ipilẹ. Dajudaju ẹnikan ti yanju iṣoro rẹ tẹlẹ ni awọn ọdun 1980.

Titi di aaye yii, idi fun gbogbo awọn ikuna mi pẹlu Spark ni jumble ti data ninu iṣupọ. Boya ipo naa le ni ilọsiwaju pẹlu iṣaaju-itọju. Mo pinnu lati gbiyanju pipin data ọrọ aise sinu awọn ọwọn ti chromosomes ni ireti lati pese Spark pẹlu data “ti a ti pin tẹlẹ”.

Mo wa lori StackOverflow fun bii o ṣe le pin nipasẹ awọn iye ọwọn ati rii iru kan nla idahun. Pẹlu AWK o le pin faili ọrọ nipasẹ awọn iye ọwọn nipa kikọ ni iwe afọwọkọ dipo fifiranṣẹ awọn abajade si stdout.

Mo kọ iwe afọwọkọ Bash kan lati gbiyanju rẹ. Ṣe igbasilẹ ọkan ninu awọn TSV ti a ṣajọ, lẹhinna ṣi silẹ ni lilo gzip o si ranṣẹ si awk.

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

O ṣiṣẹ!

Àgbáye awọn ohun kohun

Kini mo ti kọ: gnu parallel - o jẹ ohun idan, gbogbo eniyan yẹ ki o lo.

Iyapa naa lọra pupọ ati nigbati mo bẹrẹ htoplati ṣayẹwo awọn lilo ti a alagbara (ati ki o gbowolori) EC2 apeere, o wa ni jade wipe mo ti a lilo nikan kan mojuto ati nipa 200 MB iranti. Lati yanju iṣoro naa ati pe ko padanu owo pupọ, a ni lati ṣawari bi a ṣe le ṣe afiwe iṣẹ naa. Da, ni ohun Egba iyanu iwe Imọ-ẹrọ data ni Laini aṣẹ Mo ti ri a ipin nipa Jeron Janssens lori parallelization. Lati inu rẹ ni mo ti kọ nipa gnu parallel, ọna irọrun pupọ fun imuse multithreading ni Unix.

Ṣiṣayẹwo 25TB ni lilo AWK ati R
Nigbati mo bẹrẹ ipin ni lilo ilana tuntun, ohun gbogbo dara, ṣugbọn igo tun wa - gbigba awọn nkan S3 si disk ko yara pupọ ati pe ko ni afiwe ni kikun. Lati ṣatunṣe eyi, Mo ṣe eyi:

  1. Mo rii pe o ṣee ṣe lati ṣe ipele igbasilẹ S3 taara ni opo gigun ti epo, imukuro ibi ipamọ agbedemeji lori disiki patapata. Eyi tumọ si pe MO le yago fun kikọ data aise si disk ati lo paapaa kere, ati nitorinaa din owo, ibi ipamọ lori AWS.
  2. egbe aws configure set default.s3.max_concurrent_requests 50 pọsi nọmba awọn okun ti AWS CLI nlo (nipa aiyipada 10 wa).
  3. Mo yipada si apẹẹrẹ EC2 iṣapeye fun iyara nẹtiwọọki, pẹlu lẹta n ni orukọ. Mo ti rii pe isonu ti agbara sisẹ nigba lilo awọn apẹẹrẹ n jẹ diẹ sii ju isanpada nipasẹ ilosoke iyara ikojọpọ. Fun ọpọlọpọ awọn iṣẹ-ṣiṣe Mo lo c5n.4xl.
  4. Yipada gzip on pigz, Eyi jẹ ohun elo gzip kan ti o le ṣe awọn ohun tutu lati ṣe afiwe iṣẹ-ṣiṣe akọkọ ti kii ṣe afiwera ti idinku awọn faili (eyi ṣe iranlọwọ fun o kere julọ).

# 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

Awọn igbesẹ wọnyi ni idapo pẹlu ara wọn lati jẹ ki ohun gbogbo ṣiṣẹ ni yarayara. Nipa jijẹ awọn iyara igbasilẹ ati imukuro awọn kikọ disiki, Mo le ṣe ilana package terabyte 5 ni awọn wakati diẹ.

Tweet yii yẹ ki o ti mẹnuba 'TSV'. Alas.

Lilo data tuntun ti a ti sọ tẹlẹ

Kini mo ti kọ: Sipaki fẹran data ti a ko tẹ ati pe ko fẹran apapọ awọn ipin.

Bayi data wa ni S3 ni ṣiṣi silẹ (ka: pinpin) ati ọna kika ologbele-ṣeto, ati pe Mo le pada si Spark lẹẹkansi. Iyalẹnu kan n duro de mi: Mo tun kuna lati ṣaṣeyọri ohun ti Mo fẹ! O nira pupọ lati sọ fun Spark ni pato bi a ti pin data naa. Ati paapaa nigbati mo ṣe eyi, o wa ni pe ọpọlọpọ awọn ipin (95 ẹgbẹrun), ati nigbati mo lo coalesce dinku wọn nọmba to reasonable ifilelẹ, yi run mi ipin. Mo da mi loju pe eyi le ṣe atunṣe, ṣugbọn lẹhin ọjọ meji ti wiwa Emi ko le rii ojutu kan. Nikẹhin Mo pari gbogbo awọn iṣẹ-ṣiṣe ni Spark, botilẹjẹpe o gba igba diẹ ati awọn faili Parquet pipin mi ko kere pupọ (~ 200 KB). Sibẹsibẹ, data naa wa nibiti o ti nilo.

Ṣiṣayẹwo 25TB ni lilo AWK ati R
O kere pupọ ati aiṣedeede, iyalẹnu!

Idanwo awọn ibeere Spark agbegbe

Kini mo ti kọ: Sipaki ni o pọju pupọ nigbati o ba yanju awọn iṣoro ti o rọrun.

Nipa gbigba data naa ni ọna kika onilàkaye, Mo ni anfani lati ṣe idanwo iyara naa. Ṣeto iwe afọwọkọ R kan lati ṣiṣẹ olupin Spark agbegbe kan, ati lẹhinna kojọpọ fireemu data Spark kan lati ibi ipamọ ẹgbẹ Parquet ti a sọ pato (bin). Mo gbiyanju lati fifuye gbogbo awọn data, sugbon ko le gba Sparklyr lati da awọn ipin.

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)

Ipaniyan naa gba awọn aaya 29,415. Pupọ dara julọ, ṣugbọn ko dara pupọ fun idanwo ibi-ti ohunkohun. Ni afikun, Emi ko le yara awọn nkan soke pẹlu caching nitori nigbati Mo gbiyanju lati kaṣe fireemu data kan ni iranti, Spark nigbagbogbo kọlu, paapaa nigbati Mo pin diẹ sii ju 50 GB ti iranti si dataset ti o wọn kere ju 15.

Pada si AWK

Kini mo ti kọ: Associative orunkun ni AWK jẹ gidigidi daradara.

Mo rii pe MO le ṣaṣeyọri awọn iyara to ga julọ. Mo ranti pe ni iyanu AWK ikẹkọ nipa Bruce Barnett Mo ka nipa ẹya itura kan ti a pe ni "associative orun" Ni pataki, iwọnyi jẹ awọn orisii iye bọtini, eyiti o fun idi kan ni a pe ni oriṣiriṣi ni AWK, ati nitorinaa Emi ko ronu pupọ nipa wọn. Roman Cheplyaka ranti pe ọrọ naa “awọn akojọpọ alajọṣepọ” ti dagba pupọ ju ọrọ naa “bata-iye-bọtini”. Paapa ti o ba wo iye bọtini ni Google Ngram, iwọ kii yoo rii ọrọ yii nibẹ, ṣugbọn iwọ yoo wa awọn akojọpọ associative! Ni afikun, “bata-iye bọtini” ni igbagbogbo ni nkan ṣe pẹlu awọn apoti isura data, nitorinaa o jẹ oye diẹ sii lati ṣe afiwe rẹ pẹlu hashmap kan. Mo rii pe MO le lo awọn akojọpọ alajọṣepọ wọnyi lati ṣepọ awọn SNP mi pẹlu tabili bin ati data aise laisi lilo Spark.

Lati ṣe eyi, ni AWK iwe afọwọkọ Mo ti lo awọn Àkọsílẹ BEGIN. Eyi jẹ nkan ti koodu ti o ṣiṣẹ ṣaaju ki ila akọkọ ti data kọja si ara akọkọ ti iwe afọwọkọ naa.

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"
}

Egbe while(getline...) ti kojọpọ gbogbo awọn ori ila lati ẹgbẹ CSV (bin), ṣeto iwe akọkọ (orukọ SNP) bi bọtini fun akojọpọ associative bin ati awọn keji iye (ẹgbẹ) bi iye. Lẹhinna ninu bulọki { }, eyiti o ṣiṣẹ lori gbogbo awọn laini ti faili akọkọ, laini kọọkan ni a firanṣẹ si faili ti o wu jade, eyiti o gba orukọ alailẹgbẹ kan ti o da lori ẹgbẹ rẹ (bin): ..._bin_"bin[$1]"_....

Awọn oniyipada batch_num и chunk_id baamu data ti a pese nipasẹ opo gigun ti epo, yago fun ipo ere-ije, ati okun ipaniyan kọọkan nṣiṣẹ parallel, kowe si awọn oniwe-ara oto faili.

Niwọn bi Mo ti tuka gbogbo data aise sinu awọn folda lori awọn krómósómù ti o kù lati inu idanwo iṣaaju mi ​​pẹlu AWK, ni bayi Mo le kọ iwe afọwọkọ Bash miiran lati ṣe ilana chromosome kan ni akoko kan ati firanṣẹ data ipin jinle si S3.

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/*

Awọn akosile ni o ni meji ruju parallel.

Ni apakan akọkọ, a ka data lati gbogbo awọn faili ti o ni alaye lori chromosome ti o fẹ, lẹhinna data yii ti pin kaakiri awọn okun, eyiti o pin awọn faili sinu awọn ẹgbẹ ti o yẹ (bin). Lati yago fun awọn ipo ere-ije nigbati ọpọlọpọ awọn okun kọ si faili kanna, AWK kọja awọn orukọ faili lati kọ data si awọn aaye oriṣiriṣi, fun apẹẹrẹ. chr_10_bin_52_batch_2_aa.csv. Bi abajade, ọpọlọpọ awọn faili kekere ni a ṣẹda lori disiki (fun eyi Mo lo awọn iwọn terabyte EBS).

Gbigbe lati apakan keji parallel lọ nipasẹ awọn ẹgbẹ (bin) ati ki o daapọ wọn olukuluku awọn faili sinu wọpọ CSV c catati ki o si rán wọn fun okeere.

Igbohunsafẹfẹ ni R?

Kini mo ti kọ: O le kan si stdin и stdout lati ẹya R akosile, ati nitorina lo o ni opo.

O le ti ṣe akiyesi laini yii ninu iwe afọwọkọ Bash rẹ: ...cat chunked/*_bin_{}_*.csv | ./upload_as_rds.R.... O tumọ gbogbo awọn faili ẹgbẹ concatenated (bin) sinu iwe afọwọkọ R ni isalẹ. {} jẹ ilana pataki kan parallel, eyiti o fi data eyikeyi ti o fi ranṣẹ si ṣiṣan ti a ti sọtọ taara sinu aṣẹ funrararẹ. Aṣayan {#} pese a oto o tẹle ID, ati {%} duro nọmba Iho ise (tun, ṣugbọn kò ni nigbakannaa). Atokọ ti gbogbo awọn aṣayan le ṣee ri ninu iwe aṣẹ.

#!/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
)

Nigba ti a ayípadà file("stdin") zqwq si readr::read_csv, data ti a tumọ sinu iwe afọwọkọ R ti wa ni ti kojọpọ sinu fireemu kan, eyiti o wa lẹhinna ni fọọmu naa .rds- faili lilo aws.s3 kọ taara si S3.

RDS jẹ nkan bi ẹya junior ti Parquet, laisi awọn frills ti ibi ipamọ agbọrọsọ.

Lẹhin ipari iwe afọwọkọ Bash Mo ni lapapo kan .rds-awọn faili ti o wa ni S3, eyiti o fun mi laaye lati lo funmorawon daradara ati awọn iru ti a ṣe sinu.

Pelu lilo idaduro R, ohun gbogbo ṣiṣẹ ni kiakia. Kii ṣe iyalẹnu, awọn apakan ti R ti o ka ati kọ data jẹ iṣapeye gaan. Lẹhin idanwo lori chromosome alabọde kan, iṣẹ naa pari lori apẹẹrẹ C5n.4xl ni bii wakati meji.

S3 Awọn idiwọn

Kini mo ti kọ: Ṣeun si imuse ọna ọlọgbọn, S3 le mu ọpọlọpọ awọn faili mu.

Mo ṣe aniyan boya S3 yoo ni anfani lati mu ọpọlọpọ awọn faili ti a gbe si. Mo le jẹ ki awọn orukọ faili jẹ oye, ṣugbọn bawo ni S3 yoo ṣe wa wọn?

Ṣiṣayẹwo 25TB ni lilo AWK ati R
Awọn folda ni S3 wa fun ifihan nikan, ni otitọ eto naa ko nifẹ si aami naa /. Lati oju-iwe FAQ S3.

O han pe S3 ṣe aṣoju ọna si faili kan pato bi bọtini ti o rọrun ni iru tabili hash tabi aaye data ti o da lori iwe-ipamọ. A le ro garawa bi tabili, ati pe awọn faili le jẹ igbasilẹ ni tabili yẹn.

Niwọn igba ti iyara ati ṣiṣe ṣe pataki lati ṣe ere ni Amazon, kii ṣe iyalẹnu pe ọna-ọna-ọna-ọna-faili-faili yii jẹ iṣapeye freaking. Mo gbiyanju lati wa iwọntunwọnsi: ki Emi ko ni lati ṣe ọpọlọpọ awọn ibeere, ṣugbọn pe awọn ibeere naa ni kiakia. O wa ni jade wipe o jẹ ti o dara ju lati ṣe nipa 20 ẹgbẹrun bin awọn faili. Mo ro pe ti a ba tesiwaju lati je ki, a le se aseyori ilosoke ninu iyara (fun apẹẹrẹ, ṣiṣe kan pataki garawa kan fun data, bayi atehinwa awọn iwọn ti awọn jade tabili). Ṣugbọn ko si akoko tabi owo fun awọn idanwo siwaju sii.

Kini nipa ibamu agbelebu?

Ohun ti Mo Kọ: Idi akọkọ ti akoko isọnu jẹ jijẹ ọna ibi ipamọ rẹ laipẹ.

Ni aaye yii, o ṣe pataki pupọ lati beere lọwọ ararẹ: “Kini idi ti o lo ọna kika faili ohun-ini?” Idi naa wa ni iyara ikojọpọ (awọn faili CSV gzipped mu awọn akoko 7 to gun lati fifuye) ati ibamu pẹlu ṣiṣan iṣẹ wa. Mo ti le tun ro ti o ba ti R le awọn iṣọrọ fifuye Parquet (tabi Arrow) awọn faili lai sipaki fifuye. Gbogbo eniyan ti o wa ninu laabu wa nlo R, ati pe ti MO ba nilo lati yi data pada si ọna kika miiran, Mo tun ni data ọrọ atilẹba, nitorinaa MO le tun mu opo gigun ti epo lẹẹkansi.

Pipin iṣẹ

Kini mo ti kọ: Ma ṣe gbiyanju lati mu awọn iṣẹ ṣiṣẹ pẹlu ọwọ, jẹ ki kọmputa naa ṣe.

Mo ti ṣatunṣe ṣiṣiṣẹsẹhin lori chromosome kan, ni bayi Mo nilo lati ṣe ilana gbogbo data miiran.
Mo fẹ lati gbe ọpọlọpọ awọn iṣẹlẹ EC2 soke fun iyipada, ṣugbọn ni akoko kanna Mo bẹru lati gba ẹru ti ko ni iwọntunwọnsi kọja awọn iṣẹ ṣiṣe ti o yatọ (gẹgẹbi Spark ti jiya lati awọn ipin ti ko ni iwọn). Ni afikun, Emi ko nifẹ si igbega apẹẹrẹ kan fun chromosome, nitori fun awọn akọọlẹ AWS ni opin aiyipada ti awọn iṣẹlẹ 10.

Lẹhinna Mo pinnu lati kọ iwe afọwọkọ kan ni R lati mu awọn iṣẹ ṣiṣe dara si.

Ni akọkọ, Mo beere S3 lati ṣe iṣiro iye aaye ibi-itọju ti chromosome kọọkan ti tẹdo.

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

Lẹhinna Mo kọ iṣẹ kan ti o gba iwọn lapapọ, dapọ aṣẹ ti awọn chromosomes, pin wọn si awọn ẹgbẹ num_jobs ati sọ fun ọ bi o ṣe yatọ si awọn iwọn ti gbogbo awọn iṣẹ ṣiṣe.

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]>

Nigbana ni mo ran nipasẹ a ẹgbẹrun shuffles lilo purrr ati ki o yan awọn ti o dara ju.

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

Nitorinaa Mo pari pẹlu ṣeto awọn iṣẹ ṣiṣe ti o jọra pupọ ni iwọn. Lẹhinna gbogbo ohun ti o ku ni lati fi ipari si iwe afọwọkọ Bash iṣaaju mi ​​ni lupu nla kan for. Imudara yii gba to iṣẹju mẹwa 10 lati kọ. Ati pe eyi kere pupọ ju Emi yoo lo lori ṣiṣẹda awọn iṣẹ ṣiṣe ti wọn ba jẹ aiṣedeede. Nitorinaa, Mo ro pe Mo tọ pẹlu iṣapeye alakoko yii.

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

Ni ipari Mo ṣafikun aṣẹ tiipa:

sudo shutdown -h now

... ati ohun gbogbo sise jade! Lilo AWS CLI, Mo gbe awọn apẹẹrẹ soke ni lilo aṣayan user_data fun wọn ni awọn iwe afọwọkọ Bash ti awọn iṣẹ-ṣiṣe wọn fun sisẹ. Wọn sare ati tiipa laifọwọyi, nitorinaa Emi ko sanwo fun agbara sisẹ afikun.

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

Jẹ ki a kojọpọ!

Kini mo ti kọ: API yẹ ki o rọrun fun irọrun ati irọrun ti lilo.

Níkẹyìn Mo ni awọn data ni ọtun ibi ati fọọmu. Gbogbo ohun ti o ku ni lati rọrun ilana lilo data bi o ti ṣee ṣe lati jẹ ki o rọrun fun awọn ẹlẹgbẹ mi. Mo fẹ lati ṣe API ti o rọrun fun ṣiṣẹda awọn ibeere. Ti o ba wa ni ojo iwaju Mo pinnu lati yipada lati .rds si awọn faili Parquet, lẹhinna eyi yẹ ki o jẹ iṣoro fun mi, kii ṣe fun awọn ẹlẹgbẹ mi. Fun eyi Mo pinnu lati ṣe package R ti inu.

Kọ ati ṣe igbasilẹ package ti o rọrun pupọ ti o ni awọn iṣẹ iraye si data diẹ ti a ṣeto ni ayika iṣẹ kan get_snp. Mo tun ṣe oju opo wẹẹbu kan fun awọn ẹlẹgbẹ mi pkgdown, ki nwọn ki o le awọn iṣọrọ ri apeere ati iwe.

Ṣiṣayẹwo 25TB ni lilo AWK ati R

Smart caching

Kini mo ti kọ: Ti data rẹ ba ti pese silẹ daradara, caching yoo rọrun!

Niwọn bi ọkan ninu awọn ṣiṣan iṣẹ akọkọ ti lo awoṣe itupalẹ kanna si package SNP, Mo pinnu lati lo binning si anfani mi. Nigbati o ba n tan data nipasẹ SNP, gbogbo alaye lati ẹgbẹ (bin) ni a so mọ nkan ti o pada. Iyẹn ni, awọn ibeere atijọ le (ni imọran) ṣe iyara sisẹ awọn ibeere tuntun.

# 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
  }
...

Nigbati o ba n kọ idii naa, Mo ran ọpọlọpọ awọn aṣepari lati ṣe afiwe iyara nigba lilo awọn ọna oriṣiriṣi. Mo ṣeduro lati maṣe gbagbe eyi, nitori nigbami awọn abajade jẹ airotẹlẹ. Fun apere, dplyr::filter Iyara pupọ ju yiya awọn ori ila nipa lilo sisẹ ti o da lori atọka, ati gbigba iwe kan nikan lati inu fireemu data ti a yan jẹ yiyara pupọ ju lilo sintasi atọka lọ.

Jọwọ ṣe akiyesi pe nkan naa prev_snp_results ni awọn bọtini snps_in_bin. Eyi jẹ titobi ti gbogbo awọn SNP alailẹgbẹ ni ẹgbẹ kan (bin), gbigba ọ laaye lati yara ṣayẹwo boya o ti ni data tẹlẹ lati ibeere iṣaaju. O tun jẹ ki o rọrun lati yipo nipasẹ gbogbo awọn SNP ni ẹgbẹ kan (bin) pẹlu koodu yii:

# 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 
}

Результаты

Bayi a le (ati pe o ti bẹrẹ si ni pataki) ṣiṣe awọn awoṣe ati awọn oju iṣẹlẹ ti ko ni iraye si wa tẹlẹ. Ohun ti o dara julọ ni pe awọn ẹlẹgbẹ lab mi ko ni lati ronu nipa eyikeyi awọn ilolu. Wọn kan ni iṣẹ kan ti o ṣiṣẹ.

Ati pe botilẹjẹpe package naa da awọn alaye naa pamọ si wọn, Mo gbiyanju lati jẹ ki ọna kika data rọrun to ki wọn le rii ti MO ba padanu lojiji ni ọla…

Iyara naa ti pọ si ni akiyesi. Nigbagbogbo a ṣayẹwo awọn ajẹkù jiomeji pataki ti iṣẹ ṣiṣe. Ni iṣaaju, a ko le ṣe eyi (o yipada lati jẹ gbowolori pupọ), ṣugbọn ni bayi, o ṣeun si eto ẹgbẹ (bin) ati caching, ibeere fun SNP kan gba ni apapọ kere ju awọn aaya 0,1, ati pe lilo data jẹ bẹ bẹ. kekere pe awọn idiyele fun S3 jẹ epa.

ipari

Nkan yii kii ṣe itọsọna rara. Ojutu naa ti jade lati jẹ ẹni kọọkan, ati pe o fẹrẹ jẹ pe ko dara julọ. Kàkà bẹ́ẹ̀, ìwé ìròyìn ìrìn àjò ni. Mo fẹ ki awọn ẹlomiran ni oye pe iru awọn ipinnu bẹẹ ko han ni kikun ni ori, wọn jẹ abajade ti idanwo ati aṣiṣe. Paapaa, ti o ba n wa onimọ-jinlẹ data, ni lokan pe lilo awọn irinṣẹ wọnyi ni imunadoko nilo iriri, ati idiyele idiyele iriri. Inu mi dun pe mo ni ọna lati sanwo, ṣugbọn ọpọlọpọ awọn miiran ti wọn le ṣe iṣẹ kanna ti o dara ju mi ​​lọ kii yoo ni anfani lae nitori aini owo lati gbiyanju paapaa.

Awọn irinṣẹ data nla wapọ. Ti o ba ni akoko naa, o le dajudaju kọ ojutu iyara kan nipa lilo mimọ data ọlọgbọn, ibi ipamọ, ati awọn ilana isediwon. Nikẹhin o wa si isalẹ si itupalẹ iye owo-anfaani.

Ohun ti Mo kọ:

  • ko si ọna olowo poku lati ṣe itupalẹ TB 25 ni akoko kan;
  • ṣọra pẹlu iwọn awọn faili Parquet rẹ ati agbari wọn;
  • Awọn ipin ni Spark gbọdọ jẹ iwọntunwọnsi;
  • Ni gbogbogbo, maṣe gbiyanju lati ṣe awọn ipin 2,5 milionu;
  • Tito lẹsẹẹsẹ ṣi nira, gẹgẹ bi eto Spark;
  • nigba miiran data pataki nilo awọn solusan pataki;
  • Sipaki alaropo ni sare, ṣugbọn ipin jẹ ṣi gbowolori;
  • maṣe sun nigbati wọn kọ ọ ni awọn ipilẹ, ẹnikan le ti yanju iṣoro rẹ tẹlẹ ni awọn ọdun 1980;
  • gnu parallel - Eyi jẹ ohun idan, gbogbo eniyan yẹ ki o lo;
  • Sipaki fẹran data ti a ko fi kun ati pe ko fẹran apapọ awọn ipin;
  • Sipaki ni o pọju pupọ nigbati o ba yanju awọn iṣoro ti o rọrun;
  • AWK's associative orunkun ni o wa gidigidi daradara;
  • o le kan si stdin и stdout lati ẹya R akosile, ati nitorina lo o ni opo;
  • Ṣeun si imuse ọna ọlọgbọn, S3 le ṣe ilana ọpọlọpọ awọn faili;
  • Idi akọkọ fun sisọnu akoko jẹ iṣapeye ọna ipamọ rẹ laipẹ;
  • maṣe gbiyanju lati mu awọn iṣẹ-ṣiṣe dara pẹlu ọwọ, jẹ ki kọmputa naa ṣe;
  • API yẹ ki o rọrun fun irọrun ati irọrun ti lilo;
  • Ti data rẹ ba ti pese sile daradara, caching yoo rọrun!

orisun: www.habr.com

Fi ọrọìwòye kun