[Elasticsearch] Indexes groeperen per tabel

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • ZeroXT
  • Registratie: December 2007
  • Laatst online: 00:40
Ik ben op zoek wat de best practice is met betrekking tot het gebruik van indexes in Elasticsearch.

Situatie: Mysql database met daarin onder andere de volgende tabellen:
  • products
  • suppliers
  • contacts
  • customers
  • orders
  • ...
  • ...
Elke tabel heeft een `company_id` die refereert naar een company table. De bovenstaande data wordt tevens naar Elasticsearch gesynct. Nu vroeg ik mij af wat hierin de beste optie zou zijn met betrekking tot het gebruik van indexes in Elasticsearch:

Optie 1:
Elke tabel krijgt een eigen index in Elasticsearch en wanneer bijvoorbeeld alle producten doorzocht moeten worden van een `company_id` zal dit toegevoegd moeten worden in de query voor Elasticsearch:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
GET products/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "description": "debitis natus debitis omnis"
          }
        }
      ],
      "filter": [
        {
          "term": {
            "company_id": "pdbywhyroa5hqs"
          }
        }
      ]
    }
  }
}


Optie 2:
Elke tabel krijgt in combinatie met de `company_id` een eigen index in Elasticsearch. Hierdoor hoeft er niet meer gefilterd te worden op de `company_id` in de query voor Elasticsearch:
code:
1
2
3
4
5
6
7
8
GET pdbywhyroa5hqs_products/_search
{
  "query": {
    "match": {
      "description": "debitis natus debitis omnis"
    }
  }
}


Optie één heeft als voordeel dat onderhoud makkelijker zal zijn en is meer overzichtelijk. Optie twee heeft als voordeel dat er niet meer per query gefilterd hoeft te worden op de `company_id` en mijn gevoel zegt (dit heb ik nog niet getest) dat dit de performance ten goede komt. Echter heb ik mijn twijfels over het aantal indexes in Elasticsearch. Als er namelijk 1000 `company_id` zijn, dan zijn er een veelvoud indexes in Elasticsearch voor elke tabel in Mysql.

Ik heb hier en hier het een en ander gelezen, maar dit lijkt alweer achterhaalt te zijn.

Uiteraard begrijp ik dat dit af hangt van een hoop variabele zoals server capaciteit, nodes, etc. Maar wellicht dat iemand mij kan vertellen of optie één of twee überhaupt een goed idee is. En misschien dat er zelfs een optie drie is? :)

Beste antwoord (via ZeroXT op 21-09-2022 16:58)


  • Salandur
  • Registratie: Mei 2003
  • Laatst online: 22-05 08:44

Salandur

Software Engineer

Optie 1 is zeker de beste keuze, het bijhouden van alle indexen gaat een hoop werk opleveren.

Overigens heeft Elasticsearch de optie om alle data op basis van een routing key in 1 shard te stoppen. Op mijn werk gebruiken we de `company_id` als routing key, zodat alle data voor 1 klant in 1 shard terecht komt. Als je dan op dezelfde manier de routing key doorgeeft bij een zoekopdracht, wordt alleen de relevante shard doorzocht. Zie https://www.elastic.co/gu...apping-routing-field.html en https://www.elastic.co/gu...uting.html#search-routing.
Je moet in dit geval wel nog steeds de `company_id` opgeven, aangezien data van meerdere klanten in dezelfde shard aanwezig kan zijn.

Door meerdere shards per index te definieren krijg je voordeel dat de data segmenten kleiner zijn en dus sneller doorzocht kan worden.

[ Voor 8% gewijzigd door Salandur op 21-09-2022 07:25 ]

Assumptions are the mother of all fuck ups | iRacing Profiel

Alle reacties


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Hele simpele tegenvraag; waarom maak je in MySQL wel gebruik van een enkele index ipv dat je voor elke company een aparte tabel aanmaakt met de producten?

Acties:
  • 0 Henk 'm!

  • ZeroXT
  • Registratie: December 2007
  • Laatst online: 00:40
Cartman! schreef op dinsdag 20 september 2022 @ 12:43:
Hele simpele tegenvraag; waarom maak je in MySQL wel gebruik van een enkele index ipv dat je voor elke company een aparte tabel aanmaakt met de producten?
Omdat ik niet van plan ben om in Mysql data te doorzoeken. Daar is Elasticsearch voor bedoeld in dit project. Mysql is in dit geval (met de bovenstaande tabellen) "single source of truth", puur om Elasticsearch te seeden/feeden voor data persistence.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
ZeroXT schreef op dinsdag 20 september 2022 @ 12:55:
Omdat ik niet van plan ben om in Mysql data te doorzoeken. Daar is Elasticsearch voor bedoeld in dit project. Mysql is in dit geval (met de bovenstaande tabellen) "single source of truth", puur om Elasticsearch te seeden/feeden voor data persistence.
Maar het komt op hetzelfde neer, dat is wat ik probeer te vertellen ;)

Acties:
  • 0 Henk 'm!

  • ZeroXT
  • Registratie: December 2007
  • Laatst online: 00:40
Cartman! schreef op dinsdag 20 september 2022 @ 13:04:
[...]

Maar het komt op hetzelfde neer, dat is wat ik probeer te vertellen ;)
Ik begreep je doel. Alleen denk ik niet dat dit op hetzelfde neerkomt aangezien beide databases voor totaal andere doeleinden worden gebruikt. Desalniettemin, kan hier vanuit gaan dat je hint op dat er enkel 1 index gebruikt hoeft te worden per tabel in Elasticsearch? ;)

En zo ja, waarom denk je dat?

[ Voor 3% gewijzigd door ZeroXT op 21-09-2022 15:59 ]


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
ZeroXT schreef op dinsdag 20 september 2022 @ 13:10:
Ik begreep je doel. Alleen denk ik niet dat dit op hetzelfde neerkomt aangezien beide databases voor totaal andere doeleinden wordt gebruikt.
Maar ze zijn beiden ontworpen om precies dat te doen wat jij ervan vraagt.
Desalniettemin, kan hier vanuit gaan dat je hint op dat er enkel 1 index gebruikt hoeft te worden per tabel in Elasticsearch? ;)
Zeker ;)

Acties:
  • +1 Henk 'm!

  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 21-05 22:29
Ik denk dat optie 2 geen goede optie is als je te maken hebt met veel customers. Wat je namelijk gaat krijgen is dat je per customer voor iedere tabel een index moet aanmaken. Als je gebruik gaat maken van replication, dan heb je per index minimaal één primary shard + één replica shard nodig.

Als je inderdaad te maken hebt met 1000 customers, dan ga je onnodig veel shards aanmaken, waarvan mogelijk een groot deel nauwelijks gevuld gaan worden, omdat de ene customer minder data genereert dan de andere. In jouw geval zal dat dan 1000 customers * 5 tabellen * 2 shards = 10.000 shards opleveren. Te veel shards geeft een hoop overhead, en voor zover ik weet is het aantal shards per node standaard gelimiteerd op 1000. Dit aantal kan opgerekt worden, maar je gaat geheid issues krijgen qua memorygebruik etc. Been there, done that. Je kunt dit mogelijk oplossen door meer datanodes te plaatsen in je cluster, maar dat is meer een lapmiddel voor een initieel verkeerde keuze. Zie overigens https://www.elastic.co/bl...-my-elasticsearch-cluster voor meer informatie.

Ik denk dat in jouw geval optie 1 de beste keuze is. Je hebt dan zelf het aantal indexen in de hand, en bij het overschrijden van een bepaalde hoeveelheid data per index kun je handmatig of geautomatiseerd een nieuwe index aanmaken. Ik weet niet waar en hoe je je elastic queries gaat genereren, maar je kunt de filter op customer prima verstoppen in een abstractielaag. Dan heb je gegarandeerd je filter op iedere query staan. Qua performance denk ik ook niet dat optie 1 en optie 2 iets uitmaakt. Elastic is erg goed in zoeken en volgens mij kan Elasticsearch zelfs multithreaded in meerdere shards zoeken.

[ Voor 14% gewijzigd door JeroenTheStig op 20-09-2022 20:37 ]


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • Salandur
  • Registratie: Mei 2003
  • Laatst online: 22-05 08:44

Salandur

Software Engineer

Optie 1 is zeker de beste keuze, het bijhouden van alle indexen gaat een hoop werk opleveren.

Overigens heeft Elasticsearch de optie om alle data op basis van een routing key in 1 shard te stoppen. Op mijn werk gebruiken we de `company_id` als routing key, zodat alle data voor 1 klant in 1 shard terecht komt. Als je dan op dezelfde manier de routing key doorgeeft bij een zoekopdracht, wordt alleen de relevante shard doorzocht. Zie https://www.elastic.co/gu...apping-routing-field.html en https://www.elastic.co/gu...uting.html#search-routing.
Je moet in dit geval wel nog steeds de `company_id` opgeven, aangezien data van meerdere klanten in dezelfde shard aanwezig kan zijn.

Door meerdere shards per index te definieren krijg je voordeel dat de data segmenten kleiner zijn en dus sneller doorzocht kan worden.

[ Voor 8% gewijzigd door Salandur op 21-09-2022 07:25 ]

Assumptions are the mother of all fuck ups | iRacing Profiel

Pagina: 1