Partajarea nivelului aplicatiei pentru bazele de date relationale traditionale. Apache licentiat

Logica sfaramatoare

Principiu: Distribuiti uniform datele, indiferent de numarul real de fragmente fizice alese de proprietarii aplicatiei.

Strategie:

  • Alegeti un algoritm de hash cu caracteristici bune de distributie pentru majoritatea intrarilor.
  • Alegeti o galeata mare. Cheia de fragmentare va fi hashata la una dintre aceste galeti ca prim pas.
  • Utilizarea unei dimensiuni mari a cupei este de asteptat sa distribuie cheile destul de uniform. Galeatele sunt grupate impreuna pentru a forma intervale cu fiecare mapare a intervalelor intr-un fragment fizic. Aceasta mapare bucket to shard este creata la momentul pornirii aplicatiei.

Cartografierea fragmentelor la cupe

  • Pentru distribuirea uniforma a datelor, se utilizeaza un algoritm de hash pentru a hashia o cheie a unuia dintre un numar mare de galeti. Dimensiunea actuala a cupei este de 1024 .

  • Pentru numarul de galeti K si cioburi fizice N, de obicei K >> N. Galetele sunt impartite in intervale de marime N / K si fiecare interval este mapat unu-la-unu cu un ciob fizic.

Algoritm Hashing pentru uniformizare uniforma

Se foloseste Hashing.murmur3_128 () din biblioteca Guava care da o valoare de 128 biti corespunzatoare cheii de hash. Aceasta valoare este convertita in numar intreg pentru a obtine bucket si, la randul sau, fragmente fizice la care valoarea pentru cheie va fi salvata si recuperata.

Ce se intampla daca un proprietar de aplicatie decide sa schimbe numarul de cioburi fizice. De exemplu de la 16 la 32.

Resharding-ul va fi necesar pentru a pastra datele in noul sau fragment.

DAO-uri

Se presupune ca Daos sunt obiecte pentru a interactiona cu sursa de date. Clasele Dao din pachetul de db sharding sunt un strat deasupra Hibernate. Daos interactioneaza cu baza de date prin sesiunea Hibernate.

Tipuri de DAO acceptate

RelationalDao

  • Un dao obisnuia sa lucreze cu entitati legate de un fragment parinte. Parintele poate sau nu poate fi prezent fizic.
  • Un hash murmur 128 al cheii parinte sir este utilizat pentru a directiona salvarea si preluarea apelurilor din fragmentul corespunzator.

CautaDao

  • Un dao pentru salvarea si recuperarea entitatilor de nivel superior din sistem.
  • Entitatea a continuat sa utilizeze LookupDao trebuie sa aiba exact un camp adnotat cu @LookupKey. Acest camp va fi folosit ca cheie de impartire si hash la fragmentul drept de aceeasi logica explicata mai sus.

CacheableLookupDao

CacheableRelationalDao

  • O invelitoare read-through / write-through peste RelationalDao.
  • Are o interfata cache simpla RelationalCache cu mai multe metode in comparatie cu LookupCache.
  • Orice implementare cache personalizata poate fi utilizata pentru a implementa aceasta cache si initializa CacheableRelationalDao, de exemplu. Cofeina / cache guava.

Intrebari frecvente despre DAO-uri

Daca atat RelationalDao, cat si LookupDao folosesc aceeasi logica de sharding bazata pe o cheie, care este diferenta dintre aceste doua DAO-uri?

Cand sa folosesti care? Acest lucru poate fi usor confuz pentru un incepator! RelationalDao este alegerea corecta pentru toate entitatile care pot fi vazute ca fiind copii ai aceluiasi parinte. In timp ce LookupDao este alegerea corecta pentru o entitate care nu pare sa aiba relatie parinte-copil sau relatie de frate cu nicio alta entitate.

Exemplu – Daca comerciantul este considerat ca entitate mama, toate entitatile, cum ar fi optiunile de plata ale comerciantului, atributele comerciantului, informatiile despre preferintele comerciantului, pot fi tratate ca fiind copii ai acestei entitati parinte si persista utilizand un RelationalDao. Utilizarea unui dao relational indica faptul ca aceste entitati sunt legate si ar trebui sa fie plasate pe acelasi fragment pentru a permite interogarile de asociere / selectare etc.

Dar, o alta entitate, cum ar fi tabelul Agent, care pastreaza informatii despre agentii care lucreaza la achizitionarea sau ajutarea mai multor comercianti si care nu sunt inrudite cu nicio alta entitate din baza de date a comerciantilor, poate utiliza un LookupDao, deoarece este o entitate TOP-LEVEL din sistem.

Care este conceptul de cheie parinte in RelationalDao?

Una dintre principalele cerinte de partajare a datelor relationale este de a coloca date pentru entitatile care ar putea fi accesate sau recuperate impreuna. De exemplu, profilul unui comerciant, informatiile despre magazin, optiunile sale de plata ar putea fi reunite in anumite fluxuri, deci ar trebui sa fie amplasat pe acelasi fragment pentru un comerciant M. In acest scop, poate fi luat in considerare fragmentul care contine informatiile principale ale profilului comerciantului M. ca fragment parinte si codul comerciantului pot fi tratate ca cheie parinte. Aceasta cheie parinte poate fi utilizata pentru entitatile conexe persistente pentru comerciant utilizand Dao relational.

Este necesar ca diferite entitati sa utilizeze aceeasi cheie parinte?

Numai pentru entitatile conexe, este logic sa alegeti si sa utilizati aceeasi cheie parinte.

Cheia de partajare este specifica tabelului sau intregului db?

Cheia de fragmentare este necesara pentru a imparti datele unei entitati intre diferite fragmente, este posibil sa nu aiba nicio relatie in general cu orice alta entitate. Dar, in principal, entitatile sunt legate intre ele, astfel incat alegerea unei chei de sharding / cheie parinte pentru a persista o serie de entitati conexe ajuta la mentinerea codului previzibil si mentinut.

Care este alternativa pentru entitatea persistenta care este o entitate radacina in sine si care nu are un parinte clar?

LookupDao poate fi utilizat in acest scop. Spre deosebire de RelationalDao, LookupDao are conceptul LookupKey. Unul dintre campurile din entitate poate fi adnotat cu adnotare @LookupKey pentru a utiliza acest camp pentru salvarea si recuperarea entitatii. Acest camp va fi tratat ca cheie hashing cu Dao.

Lista neagra a fragmentelor

Uneori este posibil ca unul sau mai multe cioburi sa nu functioneze din cauza unei probleme hardware sau de conectivitate. In aceasta situatie, acel fragment poate fi listat pe lista neagra, pentru a mentine serviciul operational in timp ce fragmentul este fix sau punctul final al fragmentului este modificat.

ShardBlacklistingStore este o interfata care contine metode pentru:

  • lista neagra a unui ciob
  • anulati lista neagra a unui ciob
  • verificati daca un ciob este pe lista neagra

Deoarece acest pachet de biblioteca va face parte dintr-o aplicatie cu mai multe casete, va fi mai usor sa implementati ShardBlacklistingStore ca integrare cu un cache distribuit sau un serviciu desemnat, care va tine cont de cioburile listate in prezent pentru serviciul dvs. backend.

Caracteristici

  • Suport pentru paginare

  • Cadrul Hibernate are suport incorporat pentru paginare. DBShardingBundle are metode de impachetare care apeleaza intern apis hibernat care suporta paginarea, cum ar fi lista (Criterii) Exemplu – Lista publica <T> selectati (String parentKey, DetachedCriteria criterii, int first, int numResults) arunca Exception;
  • Actualizarea mai multor randuri simultan – TBD

Va rugam sa consultati clasele de testare pentru a intelege utilizarea mostrelor de daos.

Utilizare

Dependentele proiectului sunt:

<dependency> <groupId> io.appform.dropwizard.sharding </groupId> <artifactId> db-sharding-bundle </artifactId> <version> 1.3.13-9 </version> </dependency>
  • Pachetul si ID-ul grupului s-au schimbat de la io.dropwizard.sharding la io.appfrom.dropwizard.sharding de la 1.3.12-3.
  • metodele static create * au fost inlocuite cu metode de instanta de la 1.3.13-4