aidiss / opendatagovlt

For open data in Lithuania
2 stars 1 forks source link

Duomenų saugykla #13

Open sirex opened 10 years ago

sirex commented 10 years ago

Ši užduotis yra sudedamoji atvirų duomenų portalo dalis aprašyta skyrelyje Duomenų saugykla.

Terminas Duomenų saugykla plačiau aprašytas terminų žodynėlyje.

Esminė duomenų saugyklos paskirtis - galimybė greitai įrašyt ir nuskaityti didelį kiekį laisvos struktūros duomenų. Rašymas ir skaitymas gali būti tęstinis, pavyzdžiui, turi būti galimybė nuskaityti visus duomenis saugykloje, pradedant nuo 1000-ojo įrašo. Tęstinio skaitymo atveju, saugykla turi greitai peršokti ties 1000-uoju įrašu ir skaityti visus duomenis iki duomenų saugyklos failo pabaigos.

Duomenų saugyklos glaudžiai susijusius su robotais, kurie siunčia didelius kiekius neapdorotų duomenų, ir vieną po kito saugo į saugyklą, pasiųstus duomenis struktūruoja ir struktūruotą rezultatą rašo į kitą saugyklą. Galiausiai saugyklos duomenys gali būti sinchronizuojami tarp skirtingų serverių, todėl sinchronizavimo metu, atliekant duomenų nuskaitymą, duomenys skaitomi nuo failo pradžios iki pabaigos. Tačiau esant tęstinio nuskaitymo atveju, duomenys turi būti skaitomi nuo tos vietos, kur buvo baigtas skaitymas paskutinį kartą.

Būtent šiam tikslui esu sukūręs duomenų saugyklą, kurios kodą galima rasti čia: https://bitbucket.org/sirex/databot/src/7f575cb071d0b19e9bcafae42d047444680ccf2a/src/databot/storage.py?at=default

Kita alternatyva yra Apache Avro.

Reikia apsispręsti, ar naudosime vieną iš esamų duomenų saugyklų, ar kursime savo.

sirex commented 10 years ago

Hm, radau vieną galimai gerą variantą, kurį galima naudoti duomenų saugyklai: http://labs.codernity.com/codernitydb/design.html

Tai grynai Python kalba rašyta biblioteka, kuri remiasi CouchDB principais. Privalumas yra tas, kad nėra jokių sudėtingų išorinių priklausomybių duomenų robotams. Taip pat ši saugykla yra append only, tai reiškia, kad duomenų srautus galima skaityti pakankamai greitai.

aidiss commented 10 years ago

Dėl duomenų saugyklos pasirinkimo tikrai neturiu ką pasakyti. Priimki sprendimą ir tęskime.

sirex commented 10 years ago

Bandžiau pasitestuoti, kaip veikia skirtingos duomenų bazės. Štai rezultatai:

postgresql: insert: inserted 100 rows in 1.1240 seconds, 88 inserts per seconds.
postgresql: bulk insert: inserted 100000 rows in 16.8026 seconds, 5951 inserts per seconds.
postgresql: selected 100100 rows in 0.4027 seconds, 248545 rows per seconds.
postgresql: from 100100 rows found 100 duplicates in 0.0896 seconds, 1116975 rows per seconds.
postgresql: delete: deleted 100 rows in 1.1191 seconds, 89 deletes per seconds.
postgresql: bulk delete: deleted 10000 rows in 0.7466 seconds, 13394 deletes per seconds.

mysql: insert: inserted 100 rows in 3.7062 seconds, 26 inserts per seconds.
mysql: bulk insert: inserted 100000 rows in 4.2648 seconds, 23447 inserts per seconds.
mysql: selected 100100 rows in 0.6086 seconds, 164466 rows per seconds.
mysql: from 100100 rows found 100 duplicates in 0.0562 seconds, 1782181 rows per seconds.
mysql: delete: deleted 100 rows in 4.1385 seconds, 24 deletes per seconds.
mysql: bulk delete: deleted 10000 rows in 1.0244 seconds, 9762 deletes per seconds.

sqlite: insert: inserted 100 rows in 16.8564 seconds, 5 inserts per seconds.
sqlite: bulk insert: inserted 100000 rows in 2.5665 seconds, 38963 inserts per seconds.
sqlite: selected 100100 rows in 0.4909 seconds, 203923 rows per seconds.
sqlite: from 100100 rows found 100 duplicates in 0.1891 seconds, 529274 rows per seconds.
sqlite: delete: deleted 100 rows in 15.7655 seconds, 6 deletes per seconds.
sqlite: bulk delete: deleted 10000 rows in 0.7821 seconds, 12786 deletes per seconds.

+------------+--------+-------------+--------+---------+--------+-------------+------+
| db         | insert | bulk insert |   read |     agg | delete | bulk delete | size |
+------------+--------+-------------+--------+---------+--------+-------------+------+
| postgresql |     88 |        5951 | 248545 | 1116975 |     89 |       13394 | 9.3M |
| mysql      |     26 |       23447 | 164466 | 1782181 |     24 |        9762 | 7.0M |
| sqlite     |      5 |       38963 | 203923 |  529274 |      6 |       12786 | 3.5M |
+------------+--------+-------------+--------+---------+--------+-------------+------+

Visi skaičiai lentelėje (išskyrus size), yra operacijų skaičius per sekundę. insert ir delete yra operacijų skaičius per sekundę, kai kiekvienam įrašui įrašyti/ištrinti siunčiama nauja užklausa.

Testavimui, iš viso buvo naudojamas vienas milijonas įrašų.

aidiss commented 9 years ago

Manau, kad mums svarbu greitas informacijos skaitymas. Dažnesni įrašymai vyks tik projekto pradžioje. Aišku, būtų smagu sukurti simuliaciją, kuri pageneruotų užklausų srautus. Diskusijos vardan: ką manai apie mongodb ir pan. variantus?

sirex commented 9 years ago

Greitas duomenų įrašymas yra labai svarbus ne tik projekto pradžioje. Greitas rašymas reikalingas šiose vietose:

Žodžiu, bent remiantis algoritmu, kurį esu sugalvojęs duomenimis saugoti, greitas įrašymas yra labai svarbus.

Dėl mongodb, neturiu nuomonės. Žinoma būtų įdomu su juo paeksperimentuoti ir palyginti rezultatus, bet tai reikalauja papildomo laiko. Pavyzdžiui šiuo metu, visos lentelėje surašytos duomenų bazės, naudoja sqlalchemy, todėl joms visoms veikia tas pats kodas. Tuo tarpu su mongodb, visą tai reikėtų perrašinėti būtent specifiškai mongodb duomenų bazei.

Kitą vertus, dabartinis duomenų saugojimo algoritmas yra gan primityvus ir viso naudoja tik keturias operacijas:

  1. bulk insert
  2. read
  3. aggregate duplicates
  4. bulk delete duplicates

Tai teoriškai, būtų galima prijungti ir kitas duomenų bazes, kurios neveikia su sqlalchemy, tokias, kaip mongodb.

Dar vienas argumentas dėl relecinių duomenų bazių yra tas, kad jos yra labai paplitusios. Todėl gan didelė tikimybė, kad pastačius robotą kokioje nors valstybinėje įstaigoje, ten bus viena iš reliacinių duomenų bazių. O tuo atveju, jei nebus jokios reliacinės duomenų bazės, tada visada galima naudoti sqlite, kadangi jį yra standartinėje Python bibliotekoje.