Vorgurakendused 2 prax 1 variant b 2012

Allikas: Lambda
kloonid

Ülesandeks on ehitada masspäringute hajutamise rakendus, mis jaotab suure hulga võrgupäringuid mitme iseenda klooni vahel ja kogub kloonidelt saadud päringuvastused kokku.


Näitestsenaarium

Minu programm X soovib teha 1000000 erinevat google või foursquare või twitteri vms otsingut ja nende otsingutulemustega siis edasi töötada. Tüüpnäidete jaoks vaata

 https://developers.google.com/custom-search/v1/using_rest
 https://developers.google.com/places/documentation/search
 https://developer.foursquare.com/docs/venues/explore
 https://dev.twitter.com/docs/api/1/get/search

ja väikese konkreetse näitena, mis ei taha autenti:

 curl 'http://search.twitter.com/search.json?q=blue%20angels&rpp=5&include_entities=true&result_type=mixed'


Siin tekib mul mitu probleemi:

1) Google ja mitmed teised API-d lubavad ühelt IP-lt piiratud arvu päringuid mingis ajaühikus, seega võtaks 1000000 päringu tegemine väga palju aega: kui teen päringuid liiga suure tempoga, saab mu kvoot mõneks ajaks täis ja google mõnda aega enam ei vasta.

2) Mõned API-d nõuavad kasutaja registeerimist ja kasutaja ID (ja vbl ka parooli) andmist päringus. Igale kasutajale on siis eraldi tõmbamiste kvoot mingis ajaühikus. Kui tahta kvooti ületada, tuleb teha hulga kasutajaid ja hajutada päringud nii, et tõmbamised oleks ühtlaselt jaotatud kõigi kasutajate vahel (konkreetselt siis eri päringutel on erinevad identifitseerivad osad a la ..&user=u1&pwd=p1 ... jne).

3) Üks protsess ei jõua korraga väga kiiresti päringuid teha (andme-api vastab aeglaselt), seega oleks hea kasutada mitut klooni ka juhul, kui päringute arvu limiit ei ole probleemiks.

4) Minu võrguühendus võib lõpuks ummistuda (ainult väga kiire andme-api ja suurte vastuste korral), mistõttu oleks hea hajutada - võimaluse korral - päringud mitme eri kohtvõrgus masina vahel.

Funktsionaalsus

Mida ma kasutajana päringute hajutamise rakendusest ootan:

1) Teda peab olema lihtne panna käima eri laptoppidesse või serveritesse: soovitavalt lihtsalt kopeerida masinasse ja otse käivitada. Seega peaks ta töötama nii Windowsi kui Linuxi all ja ei tohiks vajada keerukat "installeerimist" ja keerukaid lisa-eelduspakette. Kindlasti ei tohi ta eeldada, et masinas töötab ntx veebiserver (ja kui töötab, siis tuleks seda veebiserverit mitte kasutada).

Kogu konf ühele kloonile peaks olema antud ühes tekstifailis, mida konkreetselt see kloon loeb. Klooni käivitades annan tekstifaili talle käsurea argumendina ette.

Programeerimiskeeleks sobivad samadel põhjustel

  • C (kompileerida Linuxi ja windowsi versioon ja anda source kaasa)
  • Java (eeldame, et masinas on harilik jdk või jre)
  • Python (pythonit on lihtne installida nii Linuxi kui Windowsi alla, linuxites reeglina juba olemas).

Selleks, et samas masinas saaks töötada mitu klooni, peab iga kloon olema identifitseeritud IP ja pordiga: ta peab konfifailist sisse lugema, et mis pordi peal ta ise töötama peab ning konfifailides peab jällegi iga kloon olema määratud IP ja pordiga. Üks võimalik IP peaks olema localhost, et oma arvutisse kloone paigutades ei peaks ma iga korda seadma, et mis mu IP parasjagu jälle on.

Samuti peab konf olema tehtav ühest tekstifailist lihtsa süntaksiga (a la kus on fail, kuhu tulemusi ajutiselt salvestatakse, mis IP-delt ja portidelt leian teisi kloone).

2) Kõik kloonid on täpselt ühesugused, st minu programm võib võtta ühendust millise klooniga iganes, kes siis omakorda hakkab hajutama ja koordineerima tööd teistel kloonidele. Ehk, ei ole eraldi "serverivarianti" ja "tõmbamisvarianti" kloonidest.

Iga konkreetse päringuhulga hajutamisel on samas muidugi mõistlik kasutada ühte neist kloonidest koordinaatorina ja teisi tõmbajatena, lihtsalt et võin ise valida, millist klooni koordinaatorina kasutan.

3) Minu päringud ehk ülesanded mida tahan anda, on kas

  • Lihtsalt URL-id, st GET päringud
  • Või URLid pluss päringu kehad (stringid mistahes formaadis), st POST päringud.

4) See kloon, kellele ma ülesandeid saadan, peab tööd ise ära hajutama teiste kloonide vahel ja koguma neilt kokku päringutulemusi

Seega peab kloon salvestama kõik saadud päringuvastused ja seostama nad originaalpäringuga, salvestades nad mõlemad faili. Failil võiks olla selline formaat, et on öeldud, kus hakkab originaalpäring ja kus kohe tema järel tuleb vastus. Kõik saadud vastused võiks olla salvestatud ühte suurde faili.

5) Kloon peab need päringutulemsed (suure faili) mulle edastama. Edastamine peab välja nägema nii, et ma kas

  • annan kloonile lihtsa GET eripäringu (formaat mõtle ise välja) mille peale pakitakse tulemusfail kokku ja saadetakse GET eripäringu vastusena mulle
  • või login lihtsalt klooni masinasse sisse ja kopeeri endale vastuste faili.

6) Ma pean saama koordineerivalt kloonilt küsida, et mitu vastust on juba saadud ja mitu on veel saamata. Selleks peaks olema lihtne GET eripäring, mis annab vastuseks kaks numbrit (näiteks jsoni list).

7) Koordineeriv kloon peab arvestama võimalusega, et mõnele päringule vastust ei saagi, st tulemusena tuleks salvestada eriväärtus, mis ütleb, et vastust ei tulnud.

8) Iga kloon peaks olema võimeline ebaõnnestunud päringut mingi aja järel üks või paar korda kordama (võrk võib olla korraks maas või vastav server ei vasta vms). Kui mitu kordamist mõningase ajavahega ikka tulemust ei anna, siis tuleb eeldada, et sellele päringule lihtsalt ei vastata, salvestada tulemus "mittelaekunud" eriväärtusena ja minna edasi järgmisi päringuid tegema.

9) Koordineev kloon peab tuvastama, kui mõni tõmbav kloon enam ei vasta (näiteks lülitati masin välja) ja talle antud tööd tuleks ümber suunata mõnele teisele kloonile.

10) Ma pean saama öelda koordineerivale kloonile, et katkestame kõik tõmbamised ja tühjendame (ajutised) tulemusfailid. Seepeale peab koordineeriv kloon omakorda teatama teistele kloonidele, et jätame kõik tõmbamised katki ja tühjendame (ajutised) tulemusfailid.

11) Vajalik oleks teha selline funktsionaalsus, kus ma saan päringutele määrata mitu erinevat kasutajat identifitseerivat stringijuppi (a la ..&user=u1&pwd=p1&.. ja ..&user=u2&pwd=p2&..) millega automaatselt asendatakse erimärgiga osa minu originaalpäringust (a la ..&IDENTIFICATION& ..). Mõte selles, et mitmed APId nõuavad registreeritud kasutajat ja panevad päringutele ajalise kvoodi kasutajapõhiselt. Sel juhul on päringute läbilaske suurendamiseks kasulik teha mitu kasutajat ja hajutada kasutajad jällegi päringute vahel ära. Seda hajutamist peaks koordineeriv kloon automaatselt tegema.

12) Kui tõmbaja teeb päringut välisele API-le, siis tekib küsimus, et mida http headeritesse panna ja mida mitte. Seda võiks saada konfifailist määrata, a la konfifailis on jupp, mis kopeeritakse headeritesse.

13) Koordineeriv kloon võiks püüda töid ühtlaselt hajutada, arvestades, et mõni tõmbav kloon võib osutuda aeglasemaks, kui teised: seega ei ole tingimata hea mõte jagada kõigile täpselt võrdselt.

14) Kui tahad erivinget funktsionaalsust teha, siis oleks abiks (aga ei ole üldse kohustuslik) teha teiste kloonide leidmine P2P meetodil analoogiliselt esimesele praksivariandile. Vaikimisi standardviis on lihtsam: kloonidel on teiste kloonide IP-d ja pordid lihtsalt konfifailis kirjas.

Turvalisus

Https ei ole otseselt nõutud, kuigi ta oleks sisuliselt juhtimiseks hea mõte.

Samuti oleks hea mõte mõelda välja mingi paroolisüsteem, kus kloonidel oleks konfis kõigil seesama parool ja iga juhtpäring sisaldab selle parooli hashi, kuhu on ntx hetke kuupäev ja tund sisse hashitud, nii et kõrvalt mõnda päringu nähes ei õnnestuks mul hakata neid kloone enda huvides lihtsalt kuritarvitama.


Tehnoloogiast

Lisaks keelevalikule (C, java, python) tuleks teha kõik juhtprotokollid ja käsud lihtsate GET päringutena, et neid saaks anda minu programmist aga ka brauserist ja curliga käsurealt jne.

Vastused oleks

  • kas lihtsalt infotekstid jsonis
  • või kodeeritud vastusfail (viimase formaat mõtle ise välja, aga lihtsuse mõttes on tungivalt soovitav teha reapõhine kodeering, st iga päringu algust ja vastuse algust markeerib spetsiaalne rida, mis tõenäoliselt mujal tekstides ei kordu.

Koordinaatorile päringute saatmise, vastuse tõmbamise ja kloonide omavahelise suhtluse protokoll mõtle ise välja. Peaasi, et

  • päringutes ja vastustes oleks olemas vajalikud infoväljad
  • fikseeritud arvu väljade korral eelista alati GET-i ja harilikku nimedega cgi formaati (a la prog?a=1&b2=2 jne)
  • vastustes kasuta jsonit, v.a. suure tulemusfaili saatmine, kus json ei pruugi olla kõige parem valik, ja eelistada tasuks vaheridadega kodeeringut, nagu eelnevalt kirjas

Soovitusi süsteemi ehitamiseks

Esimese etapina on sul mõistlik realiseerida nö "baasrakendus", mis sisaldab nii http klienti kui serverit (mitte siis suurt veebiserverit) ja suudab

  • vastu võtta GET ja POST päringuid ja neile midagigi vastata
  • ise teha mingeid GET ja POST päringuid

Selle "baasrakenduse" ehitamise näiteid ja soovitusi leiad praktikumi p2p chativariandi lehelt.