Hei ystävät! Foorumeillemme osallistuu ihmisiä, joilla on eritasoista kokemusta - ja se on hienoa! Mutta juuri nyt etsin todellisia Ruby titaaneja!
Elasticsearch on hakukone, joka perustuu luotettavaan ja kypsään kirjastoon - Apache Luceneen. Valtavaa toimintaa gitissä projekti arkisto ja sen toteuttaminen sellaisissa projekteissa kuin GitHub, SoundCloud, Stack Overflow ja LinkedIn ovat osoitus sen suuresta suosiosta. Osa "Elastic" kertoo kaiken järjestelmän luonteesta, jonka ominaisuudet ovat valtavat: yksinkertaisesta tiedostohauista pienessä mittakaavassa tiedonhaun kautta ison datan reaaliaikaiseen analyysiin. kilpailijoitaan tehokkaampi Elastic on joukko oletuskonfiguraatioita ja -käyttäytymismalleja, joiden avulla klusterin voi luoda ja aloittaa dokumenttien lisäämisen indeksiin muutamassa minuutissa. Elastic konfiguroi klusterin puolestasi, määrittelee indeksin ja määrittelee kenttätyypit ensimmäiselle saadulle dokumentille, ja kun lisäät toisen palvelimen, se hoitaa automaattisesti indeksin tietojen jakamisen palvelimien välillä. valitettavasti edellä mainittu automaatio tekee meille epäselväksi, mitä oletusasetukset tarkoittavat, ja se osoittautuu usein harhaanjohtavaksi. Tämä artikkeli aloittaa sarjan, jossa käsittelen yleisimpiä ongelmia, joihin saatat törmätä Elastic-pohjaisen sovelluksen luomisprosessin aikana.
Sirpaleiden lukumäärää ei voi muuttaa
Indeksoidaan ensimmäinen dokumentti käyttämällä indeksi API:
$ curl -XPUT 'http://localhost:9200/myindex/employee/1' -d '{
"etunimi" : "Jane",
"sukunimi" : "Smith",
"steet_number": 12
}'
Tällä hetkellä Elastic luo meille indeksin, jonka nimi on myindex. Tässä ei näy indeksille määritettyjen shardien määrä. Shardit voidaan ymmärtää yksittäisiksi prosesseiksi, jotka vastaavat indeksoinnista, tallentamisesta ja etsinnästä koko indeksin asiakirjojen jossakin osassa. Asiakirjojen indeksointiprosessin aikana elastic päättää, mistä shardista asiakirja löytyy. Tämä perustuu seuraavaan kaavaan:
shard = hash(document_id) % number_of_primary_shards
Nyt on selvää, että asiakirjoja sisältävän indeksin ensisijaisten shardien määrää ei voi muuttaa. Luo siis aina ennen ensimmäisen asiakirjan indeksointia indeksi manuaalisesti ja anna indeksin määrä, jonka uskot olevan riittävä indeksoitavalle tietomäärälle:
$ curl -XPUT 'http://localhost:9200/myindex/' -d '{ {
"settings" : {
"number_of_shards" : 10
}
}'
Oletusarvo arvolle sirpaleiden määrä
on 5. Tämä tarkoittaa, että indeksi voidaan skaalata enintään 5 palvelimelle, jotka keräävät tietoja indeksoinnin aikana. Tuotantoympäristössä sirpaleiden arvo olisi asetettava indeksoinnin odotetun tiheyden ja asiakirjojen koon mukaan. Kehitys- ja testausympäristöihin suosittelen asettamaan arvon 1 - miksi näin? Se selitetään tämän artikkelin seuraavassa kappaleessa.
Tekstihakutulosten lajittelu suhteellisen pienellä määrällä asiakirjoja.
Kun etsimme asiakirjaa lauseella:
$ curl -XGET 'http://localhost:9200/myindex/my_type/_search' -d
'{
"query": {
"match": {
"title": "The quick brown fox"
}
}
}'
Elastic käsittelee tekstihakua muutamassa vaiheessa, yksinkertaisesti sanottuna:
- pyynnön lause muunnetaan samaan identtiseen muotoon kuin asiakirja indeksoitiin, meidän tapauksessamme se on joukko termejä:
["quick", "brown", "fox"]
("the" on poistettu, koska se on merkityksetön),
- hakemistoa selataan sellaisten asiakirjojen etsimistä varten, jotka sisältävät vähintään yhden haetuista sanoista,
- jokainen asiakirja, joka vastaa hakusanaa, arvioidaan sen kannalta, onko se hakulausekkeen kannalta merkityksellinen,
- tulokset lajitellaan lasketun relevanssin mukaan ja käyttäjälle palautetaan ensimmäinen tulossivu.
Kolmannessa vaiheessa otetaan huomioon muun muassa seuraavat arvot:
- kuinka monta hakulausekkeen sanaa asiakirjassa on.
- kuinka usein tietty sana esiintyy asiakirjassa (TF - termifrekvenssi).
- esiintyvätkö vastaavat sanat muissa asiakirjoissa ja kuinka usein (IDF - käänteinen asiakirjan frekvenssi) - mitä suositumpi sana on muissa asiakirjoissa, sitä vähemmän merkitystä sillä on.
- kuinka pitkä asiakirja on
IDF:n toiminta on meille tärkeää. Elastic ei suorituskykysyistä laske tätä arvoa jokaisen indeksissä olevan asiakirjan osalta - sen sijaan jokainen shard (indeksityöntekijä) laskee paikallisen IDF:nsä ja käyttää sitä lajitteluun. Siksi indeksin haun aikana, kun asiakirjojen määrä on pieni, saatamme saada huomattavasti erilaisia tuloksia indeksin shardien määrästä ja asiakirjojen jakautumisesta riippuen.
Kuvitellaan, että indeksissä on kaksi lohkoa; ensimmäisessä on 8 dokumenttia, jotka on indeksoitu sanalla "kettu", ja toisessa vain 2 dokumenttia, joissa on sama sana. Tämän seurauksena sana "kettu" eroaa merkittävästi molemmissa osissa, mikä voi tuottaa virheellisiä tuloksia. Siksi kehittämistarkoituksiin olisi luotava indeksi, joka koostuu vain yhdestä ensisijaisesta osasta:
$ curl -XPUT 'http://localhost:9200/myindex/' -d
'{"settings" : { "number_of_shards" : 1 } }'
"Kaukana" olevien hakusivujen tulosten tarkastelu tappaa klusterisi.
Kuten olen kirjoittanut aiemmissa kappaleissa, indeksin sisältämät asiakirjat jaetaan täysin yksittäisten indeksiprosessien - shardien - kesken. Jokainen prosessi on täysin itsenäinen ja käsittelee vain sille osoitettuja asiakirjoja.
Kun etsimme miljoonia asiakirjoja sisältävää hakemistoa ja odotamme 10 parasta tulosta, jokaisen sirpaleen on palautettava 10 parhaiten vastaavaa tulosta klusterin klusteriin. solmu, joka käynnisti etsinnät. Tämän jälkeen jokaisen sirpaleen vastaukset yhdistetään ja valitaan 10 parasta hakutulosta (koko indeksistä). Tällainen lähestymistapa mahdollistaa hakuprosessin tehokkaan jakamisen useiden palvelimien kesken.
Kuvitellaan, että sovelluksemme sallii 50 tuloksen tarkastelun sivua kohti ilman rajoituksia, jotka koskevat käyttäjän tarkastelemien sivujen määrää. Muista, että indeksimme koostuu 10 ensisijaisesta shardista (1 per palvelin).
Katsotaanpa, miltä hakutulosten hankkiminen näyttää 1. ja 100. sivulla:
Hakutulosten sivu nro 1:
- Kyselyn vastaanottava solmu (ohjain) välittää kyselyn eteenpäin 10:lle sirpaleelle.
- Jokainen sirpale palauttaa 50 parhaiten vastaavaa asiakirjaa merkityksellisyyden mukaan lajiteltuna.
- Kun vastaukset on saatu jokaiselta sirpaleelta, valvoja yhdistää tulokset (500 asiakirjaa).
- Tuloksemme ovat edellisen vaiheen 50 parasta asiakirjaa.
Hakutulosten sivu nro 100:
- Kyselyn vastaanottava solmu (ohjain) välittää kyselyn eteenpäin 10:lle sirpaleelle.
- Jokainen sirpale palauttaa 5000 parhaiten vastaavaa asiakirjaa merkityksellisyyden mukaan lajiteltuna.
- Kun ohjain on saanut vastaukset jokaiselta sirpaleelta, se yhdistää tulokset (50000 asiakirjaa).
- Tuloksemme ovat edellisen vaiheen asiakirjat, jotka on sijoitettu 4901 - 5000.
Jos oletetaan, että yhden asiakirjan koko on 1 kilotavua, toisessa tapauksessa se tarkoittaa, että klusterissa on lähetettävä ja käsiteltävä ~50 Mt dataa, jotta voidaan tarkastella 100 tulosta yhdelle käyttäjälle.
Ei ole vaikea huomata, että verkkoliikenne ja indeksin kuormitus lisääntyvät merkittävästi jokaisen peräkkäisen tulossivun myötä. Siksi ei ole suositeltavaa asettaa "kaukaisia" hakusivuja käyttäjän saataville. Jos indeksimme on hyvin konfiguroitu, käyttäjän pitäisi löytää haluamansa tulos ensimmäisillä hakusivuilla, ja suojaudumme klusterimme tarpeettomalta kuormitukselta. Voit todistaa tämän säännön tarkistamalla, kuinka monta hakutulossivua suosituimmat verkkohakukoneet sallivat tarkastella.
Mielenkiintoista on myös selaimen vasteaikaa koskeva havainto peräkkäisten hakutulossivujen osalta. Alla on esimerkiksi Google Searchin yksittäisten hakutulossivujen vasteajat (hakusana oli "search engine"):
| Hakutulossivu (10 asiakirjaa sivulla) | Vastausaika |
|——————————————–|—————|
| 1 | 250ms |
| 10 | 290ms |
| 20 | 350ms |
| 30 | 380ms |
| 38 (viimeinen saatavilla oleva) | | |
Seuraavassa osassa tarkastelen tarkemmin asiakirjojen indeksointiin liittyviä ongelmia.