Category Archives: estonian

valimised

Eile toimusid riigikogu valimised ja tegu oli juba teiste valimistega, kus valimiskommisioni leht mingil hetkel loobus värske info edastamisest.

Helmes, kes antud tarkvara teinud on tuli täna välja huvitava patuoinaga – jamades olevat süüdi avatud lähtekoodiga andmebaasimootor PostgreSQL, nende poolt tehtud tarkvara töötas perfektselt ja adekvaatset jõudlustesti ei tehtud kuna see olla võimatu.

Esiteks tundub siin äärmiselt kohatu PostgreSQLi süüdistamine, selle peal käib maailmas väga palju süsteeme, mille andmemahud ja koormused on võrratult suuremad sellest, mida see valimissüsteem oleks pidanud kannatama (no kasvõi näiteks Skypei kasutajate baas on PostgreSQLi peal). Mulle isiklikult tundub, et antud juhul oli Postgresi süüdistada lihtsalt palju mugavam, kui öelda, et me ei testinud ega seadistanud asja piisavalt, sest näiteks erinevalt Oraclest ei ole siin taga kedagi kes sind siinkohal laimu eest kohtusse kaebaks.

Teiseks öelda, et meie tarkvara töötas ideaalselt, ikaldus vahend X mida me kasutasime on üsna kohatu, kuna arendaja vastutab üldiselt ikka terviku eest. PostgreSQL on ennast maailmas piisavalt tõestanud, küsimus tundub olevat puhtalt rakenduse arhitektuuris ja/või serveri seadistustes. Siinkohal oleks tore kuulata Hannu Krosingu või mõne teise postgresi guru kommentaari.

No ja viimaseks jutt, et “Omalt poolt olime kõik ära testinud ja kontrollinud ning enam midagi teha ei saanud” – antud rakenduse testimine peaks täiesti reaalse koormuse juures olema üsna lihtne. Eesti oma ~600 000 häälega on ikka imepisike asi simuleerimiseks. Hiinlastel oleks ehk sutsu raskem 😛

Aga, et see ei jääks tühjaks targutamiseks, siis viskasin hommikul rongis tööle sõites kokku naiivse valimise rakenduse, et vaadata palju sellise baasi täitmine ja hilisem võitjate selgitamine sellise baasi pealt aega võtaks suvalisel desktop masinal.

Kõigepealt tuleb teha mõned eeldused:

Teen ainult häälte (votes) ja kandidaatide (candidates) tabelid. Tegelikult peaks tabeleid olema muidugi rohkem – valimisnimekirjad, erakonnad, ringkonnad, valimisjaoskonnad ja ilmselt veel mõned, mis esimese hooga pähe ei tule. Neid tabeleid võib aga rahus ignoreerida, kuna väljaarvatud häälte tabel peaks muu olema üsna konstantne ja eeltäidetud.

Teen eelduse, et iga hääl on eraldi kirje votes tabelis. Ilmselt praktikas nii ei ole ja pigem teatab valimisjaoskond häälte arvu ühe kirjena kandidaadi kohta a’la kandidaat_X sai 1000 häält. See oleks jõudluse mõttes oluliselt lihtsam, kuna 600 000 inserdi asemel oleks neid pigem kuskil 50 000 ringi. Teen sihilikult jõudluse mõttes oluliselt hullema variandi, et näha palju see aega võtaks.

Teen eelduse, et valimisjaoskond teatab kõik oma hääled korraga. St. iga hääle sisestamine ei ole omaette transaktsioon vaid pigem on seda kõigi ühe valimisjaoskonna häälte sisestamine.

Eeldan, et veebis kasutajale graafikute ja statsi näitamist ei tehta otse andmebaasi pealt vaid pigem genereeritakse staatiline leht näiteks kord minutis. Ei tundu olevat põhjust, miks peaks kasutajale näidatav leht üldse andmebaasi vastu käima ja ilmselt nii oligi tehtud sest probleemide ajal tuli leht endiselt kiirelt ette, lihtsalt vanade andmetega. See tähendab, et mul pole vaja emuleerida kuidas paarsada tuhat erinevat select päringut sekundis baasi pihta käivad.

Üldiselt nende selgitust lugedes jääb mulje, et küsimus oli selles et query planner tegi otsuseid vana tabeli statistika pealt (VACUUM ANALYZE’i polnud vahepeal käivitatud) mistõttu eelistati ebaefektiivsemat käivitusplaani. Näiteks, kui tabelis on mõnisada kirjet võib igati mõistlik olla kasutada tabeli käigi ridade läbikäimist (full scan) indeksi poole pöördumise asemel. Artiklist jääb mulje, et hetkel kui jama tekkis vaatasid adminid käimasolevaid päringuid ja nende execution plani ja andsid VACUUM ANALYZE ja siis ootasid tunnikese, et päringu käitusplaan muutuks. Selleks, peab andmebaasi IO ikka ülimalt ülekoormatud olema, et VACUUM ANALYZE sellise aja võtaks. Näiteks minu 600 000 kirjega häälte tabelil võttis tavalisel desktop masinal ~2s.

Schema niisiis selline:

CREATE TABLE candidates(
    candidate_id INT PRIMARY KEY, 
    name text
)
 
CREATE TABLE votes(
    electoral_district_id INT NOT NULL, 
    candidate_id INT NOT NULL REFERENCES candidates(candidate_id)
)
 
CREATE INDEX idx_candidate_id ON votes(candidate_id)

Ja script, mis “valimistulemusi” sisestab on siin.

Ja aega võtab sellega 600 000 hääle sisestamine veidi alla 4 minuti:

hadara@hadara-desktop:~$ python elections.py 
        candidates inserted
        votes inserted
tables filled in: 211.85s

Tegu niisiis tavalisel desktop masinal suht vaike seadistustega jooksva PostgreSQLiga (shared_buffers keeratud 256MB peale, reaalsetes serverites ilmselt pigem 4+GB).

Sellise baasi pealt võitjate pärimine võiks välja näha näiteks nii:

elections=# SELECT votes.candidate_id, COUNT(*) AS votecount,(SELECT name FROM candidates WHERE candidates.candidate_id=votes.candidate_id) AS candidate_name FROM votes GROUP BY votes.candidate_id ORDER BY votecount LIMIT 10; candidate_id | votecount | candidate_name 
--------------+-----------+----------------
          106 |       600 | candidate_106
          120 |       600 | candidate_120
          285 |       600 | candidate_285
          681 |       600 | candidate_681
          866 |       600 | candidate_866
          264 |       600 | candidate_264
          887 |       600 | candidate_887
          601 |       600 | candidate_601
          664 |       600 | candidate_664
          251 |       600 | candidate_251
(10 ROWS)

See päring võtab 146ms ja execution plan on selline:

elections=# EXPLAIN analyze SELECT votes.candidate_id, COUNT(*) AS votecount,(SELECT name FROM candidates WHERE candidates.candidate_id=votes.candidate_id) AS candidate_name FROM votes GROUP BY votes.candidate_id ORDER BY votecount DESC LIMIT 10;
                                                                     QUERY PLAN                                                                     
----------------------------------------------------------------------------------------------------------------------------------------------------
 LIMIT  (cost=19956.81..19956.83 ROWS=10 width=4) (actual TIME=146.603..146.605 ROWS=10 loops=1)
   ->  Sort  (cost=19956.81..19959.31 ROWS=1000 width=4) (actual TIME=146.602..146.603 ROWS=10 loops=1)
         Sort KEY: (COUNT(*))
         Sort Method:  top-N heapsort  Memory: 25kB
         ->  HashAggregate  (cost=11655.00..19935.20 ROWS=1000 width=4) (actual TIME=144.690..146.393 ROWS=1000 loops=1)
               ->  Seq Scan ON votes  (cost=0.00..8655.00 ROWS=600000 width=4) (actual TIME=0.005..36.190 ROWS=600000 loops=1)
               SubPlan 1
                 ->  INDEX Scan USING candidates_pkey ON candidates  (cost=0.00..8.27 ROWS=1 width=13) (actual TIME=0.001..0.001 ROWS=1 loops=1000)
                       INDEX Cond: (candidate_id = $0)
 Total runtime: 146.651 ms
(10 ROWS)

Valimistega ma kuidagi seotud pole ja PostgreSQLi näpisin viimati umbes 8 aastat tagasi. Seega üsna puusalt tulistamine.

Uuendus: Martin Rebane, kellele on antud minust oluliselt rohkem kirjanikuannet, on ka samal teemal kirjutanud.

ekoolist

Juba mitu nädalat on meedias kõneaineks eKooliga seonduvad teemad. Seda nii puht tehniliselt (ei tööta, on aeglane, arusaamatu) kui ka puht olemuslikult – kas ikka on vaja kõike raamidesse suruda ja kirja panna?

Isiklik kokkupuude ekooliga mul puudub ja seega avaldan arvamust puht internetist loetu ja tuttavate kirjeldatu põhjal.

Probleemid tunduvad saavat alguse sellest, et eKooli, mis on oma turul sisuliselt monopoolne tegija, haldab ja arendab Koolitööde AS, mis on erafirma.
Turumajanduses on üldiselt iga firma primaarne eesmärk teenida oma omanikele võimalikult suurt kasumit. Toimiva konkurentsiga turul ollakse sunnitud selle eesmärgi täitmiseks arvestama ka tarbija ootuste ja soovidega, sest muidu läheb tarbija lihtsalt konkurendi juurde. E-kool on Eesti turul monopolses olukorras ja on äärmiselt ebatõenäoline, et sellise väikse turu pärast ka keegi konkureerima hakkaks. Seega ei ole neil ilmselt ka erilist põhjust oma klientide soosingu pärast väga vaeva näha.

Koolide jaoks on valik hetkel seega põhimõtteliselt kas ekooli kasutada ja loota et ajakirjanduse kaudu survet avaldades tehakse midagi siiski nende seisukohalt paremaks, mitte kasutada või luua oma süsteem (mida ka osad koolid teevad).

Praegusest mudelist tunduks oluliselt loogilisem, kui kõik koolid kes on oma süsteemi arendamise peale juba välja läinud ei ponnistaks omaette vaid ühendaksid jõud MTÜ või SA moodustamisega, mis siis hakkaks uut eKooli looma.
– Kuna arendaja kuuluks sellisel juhul koolidele endile oleks neil ka motivatsioon luua töövahend, mis on võimalikult mugav, kiire ja tööd lihtsustav.
– Langeb ära vajadus maksta kinni omanike kasumit, seega peaks lahendus tulema odavam kui praegune.
– Peaks tulema ka oluliselt odavam, kui igaühel oma süsteemi teha.

Ideaalis võiks sellise süsteemi disain olla võimalikult hajus ja modulaarne.
Keskne server tegeleks ainult kasutajate autoriseerimisega aga soovi korral võiks iga kool reaalse rakenduse paigaldada ka kuhugi mujale (tekiks hostingupakkujate vahel konkurents, mis hinda alla suruks). Iga kool saaks seega teatud piirides otsustada, mis versiooni ja mis moodulite, väljanägemisega (skin) ta kasutab. MTÜ tegeleks kasutajatelt tagasiside kogumisega, olulisemate moodulite arendamise ja tsentraalse autentimissüsteemi haldamisega. Rakendus võiks olla avatud lähtekoodiga, nii et kõik asjaosalised saaksid lihtsa vaevaga teha parandusi ja luua soovi korral lisa mooduleid, mis on just neile olulised.

Võibolla ei tule isegi tühjalt kohalt alustada, kuna enamvähem analoogsete eesmärkidega avatud lähtekoodiga rakendusi on üle maailma mitmeid (näiteks Schooltool, Moodle).
Osad neist võimaldaksid suht lihtsa vaevaga liikuda e-hinnetelehe funktsionaalsusest reaalse e-kooli funktsionaalsuseni.

Arvestades, et praeguse eKooli puhul on mitmed asjad pikalt olnud ingliskeelsed tekib kahtlus, et ka nemad on selle lahenduse teinud millegi olemasoleva kohandamise teel.

PS. huvitav kellele see Koolitööde AS tegelikult kuulub? Ilmselt küsimus mu oskamatuses aga poole tunniga ma ammendavat vastust leida ei suutnud.

swedbank ja KMyMoney

Kunagi sai kirjutatud pisikesest scriptist millega ma Hansapanga konto väljavõtteid KMyMoney’sse importisin. Vahepeal on aeg veidi edasi läinud, Hansapangast on saanud Swedbank ja ka nende konto väljavõtte CSV formaat veidi muutunud.

Sai ühesõnaga eelpoolmainitud scripti veidi uuendatud. Lisatud sai võimalus kasutada -c võtit mis võimaldab kontrollida kas mapingu listis (payee_map) on kõigi maksjate kohta defineeritud regexpid. Ühtlasi saab scripti confida nüüd ka QIF formaadi profiili input filtriks.

Script ise siin.

Mõned pildid QIF Swedbanki jaoks QIF profiili confimisest:

kmm1

kmm2

kmm3

kmm4

kmm5

kmm6

kmm7

kmm8