ObjectRepository - .NET in-memory repository pateni yemapurojekiti ako epamba

Sei uchichengeta data rese mundangariro?

Kuchengeta webhusaiti kana backend data, chishuwo chekutanga chevanhu vazhinji vane njere ichave yekusarudza dhatabhesi reSQL. 

Asi dzimwe nguva pfungwa inouya mupfungwa yokuti data data haikodzeri SQL: somuenzaniso, paunenge uchivaka kutsvaga kana girafu yemagariro, unoda kutsvaga hukama hwakaoma pakati pezvinhu. 

Mamiriro akanyanya kuipa ndeye kana iwe ukashanda muchikwata uye waunoshanda naye haazive nzira yekuvaka nekukurumidza mibvunzo. Inguva yakareba sei yawakapedza uchigadzirisa matambudziko eN+1 nekugadzira mamwe ma indexes kuitira kuti SARUDZA iri papeji huru ipedze nenguva yakafanira?

Imwe nzira yakakurumbira ndeyeNoSQL. Makore akati wandei apfuura pakanga paine hype yakawanda yakatenderedza musoro uyu - kune chero chiitiko chakanaka ivo vakaisa MongoDB uye vaifara nemhinduro muchimiro chejson zvinyorwa. (nenzira, mangani madondoro awaifanira kuisa nekuda kwema denderedzwa links mumagwaro?).

Ini ndinokurudzira kuyedza imwe, imwe nzira - wadii kuedza kuchengeta data rese mundangariro yekushandisa, nguva nenguva uchiichengeta kune yakasarudzika chengetedzo (faira, kure dhatabhesi)? 

Memory yave yakachipa, uye chero data inokwanisika yemapurojekiti mazhinji madiki uye epakati anokwana mu1 GB yendangariro. (Semuenzaniso, purojekiti yangu yepamba yandinofarira ndeye mari tracker, iyo inochengeta nhamba dzezuva nezuva nenhoroondo yezvekushandisa kwangu, zviyereso, uye kutengeserana kwegore nehafu, inodya chete 45 MB yendangariro.)

Pros:

  • Kuwana data kunova nyore - haufanirwe kunetseka nezve mibvunzo, usimbe kurodha, ORM maficha, unoshanda nezvakajairwa C # zvinhu;
  • Iko hakuna matambudziko ane chekuita nekuwana kubva kune akasiyana shinda;
  • Kukurumidza kwazvo - hapana zvikumbiro zvetiweki, hapana kushandurwa kwekodhi mumutauro wekubvunza, hapana chikonzero che (de) serialization yezvinhu;
  • Zvinotenderwa kuchengeta data mune chero fomu - ingave iri muXML pane dhisiki, kana muSQL Server, kana muAzure Tafura Kuchengeta.

Cons:

  • Horizontal scaling yakarasika, uye semhedzisiro, zero downtime deployment haigone kuitwa;
  • Kana iyo application ikaparara, unogona kurasikirwa nedata zvishoma. (Asi application yedu haina kumboparara, handiti?)

Sei kushanda?

Iyo algorithm iri seinotevera:

  • Pakutanga, kushamwaridzana kunotangwa nekuchengetedza data, uye data inotakurwa;
  • Muenzaniso wechinhu, maindekisi ekutanga, uye indexes yehukama (1:1, 1:Mazhinji) anovakwa;
  • Kunyoreswa kunogadzirirwa shanduko muzvinhu zvechinhu (INotifyPropertyChanged) uye yekuwedzera kana kubvisa zvinhu kuunganidzwa (INotifyCollectionChanged);
  • Kana kunyoreswa kuchiitwa, chinhu chakashandurwa chinowedzerwa kumutsara wekunyorera kune data rekuchengetedza;
  • Shanduko dzekuchengetedza dzinochengetwa nguva nenguva (pane timer) mune yekumashure tambo;
  • Paunobuda muapp, shanduko dzinochengetwawo mudura.

Code Muenzaniso

Kuwedzera zvinodiwa zvinoenderana

// Основная библиотека
Install-Package OutCode.EscapeTeams.ObjectRepository
    
// Хранилище данных, в котором будут сохраняться изменения
// Используйте то, которым будете пользоваться.
Install-Package OutCode.EscapeTeams.ObjectRepository.File
Install-Package OutCode.EscapeTeams.ObjectRepository.LiteDb
Install-Package OutCode.EscapeTeams.ObjectRepository.AzureTableStorage
    
// Опционально - если нужно хранить модель данных для Hangfire
// Install-Package OutCode.EscapeTeams.ObjectRepository.Hangfire

Isu tinotsanangura iyo data data iyo ichachengetwa mukuchengetedza

public class ParentEntity : BaseEntity
{
    public ParentEntity(Guid id) => Id = id;
}
    
public class ChildEntity : BaseEntity
{
    public ChildEntity(Guid id) => Id = id;
    public Guid ParentId { get; set; }
    public string Value { get; set; }
}

Zvadaro chinhu modhi:

public class ParentModel : ModelBase
{
    public ParentModel(ParentEntity entity)
    {
        Entity = entity;
    }
    
    public ParentModel()
    {
        Entity = new ParentEntity(Guid.NewGuid());
    }
    
    public Guid? NullableId => null;
    
    // Пример связи 1:Many
    public IEnumerable<ChildModel> Children => Multiple<ChildModel>(x => x.ParentId);
    
    protected override BaseEntity Entity { get; }
}
    
public class ChildModel : ModelBase
{
    private ChildEntity _childEntity;
    
    public ChildModel(ChildEntity entity)
    {
        _childEntity = entity;
    }
    
    public ChildModel() 
    {
        _childEntity = new ChildEntity(Guid.NewGuid());
    }
    
    public Guid ParentId
    {
        get => _childEntity.ParentId;
        set => UpdateProperty(() => _childEntity.ParentId, value);
    }
    
    public string Value
    {
        get => _childEntity.Value;
        set => UpdateProperty(() => _childEntity.Value, value
    }
    
    // Доступ с поиском по индексу
    public ParentModel Parent => Single<ParentModel>(ParentId);
    
    protected override BaseEntity Entity => _childEntity;
}

Uye pakupedzisira, iyo repository kirasi pachayo yekuwana data:

public class MyObjectRepository : ObjectRepositoryBase
{
    public MyObjectRepository(IStorage storage) : base(storage, NullLogger.Instance)
    {
        IsReadOnly = true; // Для тестов, позволяет не сохранять изменения в базу
    
        AddType((ParentEntity x) => new ParentModel(x));
        AddType((ChildEntity x) => new ChildModel(x));
    
        // Если используется Hangfire и необходимо хранить модель данных для Hangfire в ObjectRepository
        // this.RegisterHangfireScheme(); 
    
        Initialize();
    }
}

Gadzira chiitiko cheObjectRepository:

var memory = new MemoryStream();
var db = new LiteDatabase(memory);
var dbStorage = new LiteDbStorage(db);
    
var repository = new MyObjectRepository(dbStorage);
await repository.WaitForInitialize();

Kana iyo purojekiti ichashandisa HangFire

public void ConfigureServices(IServiceCollection services, ObjectRepository objectRepository)
{
    services.AddHangfire(s => s.UseHangfireStorage(objectRepository));
}

Kuisa chinhu chitsva:

var newParent = new ParentModel()
repository.Add(newParent);

Nekudanwa uku, chinhu ParentModel inowedzerwa kune zvese cache yemuno uye mutsara wekunyora kune dhatabhesi. Naizvozvo, oparesheni iyi inotora O (1), uye chinhu ichi chinogona kushandiswa nekukurumidza.

Semuenzaniso, kuwana chinhu ichi mune repository uye simbisa kuti chinhu chakadzoserwa ndicho chiitiko chimwe chete:

var parents = repository.Set<ParentModel>();
var myParent = parents.Find(newParent.Id);
Assert.IsTrue(ReferenceEquals(myParent, newParent));

Chii chiri kuitika? Set () anodzoka TableDictionary, iyo ine ConcurrentDictionary uye inopa humwe mashandiro ekutanga uye echipiri indexes. Izvi zvinokutendera iwe kuve nemaitiro ekutsvaga neId (kana mamwe anopokana mushandisi indexes) pasina kunyatso dzokorora pamusoro pezvinhu zvese.

Pakuwedzera zvinhu ObjectRepository kunyoreswa kunowedzerwa kushandura zvivakwa zvavo, saka chero shanduko mumidziyo inokonzeresa kuti chinhu ichi chiwedzerwe pamutsetse wekunyora. 
Kuvandudza zvivakwa kubva kunze kunotaridzika zvakafanana nekushanda nePOCO chinhu:

myParent.Children.First().Property = "Updated value";

Unogona kudzima chinhu nenzira dzinotevera:

repository.Remove(myParent);
repository.RemoveRange(otherParents);
repository.Remove<ParentModel>(x => !x.Children.Any());

Izvi zvinowedzerawo chinhu kumutsara wekudzima.

Kuchengetedza kunoshanda sei?

ObjectRepository kana zvinhu zvinotariswa zvichichinja (zvichida kuwedzera kana kudzima, kana kushandura zvivakwa), zvinosimudza chiitiko ModelChangedvakanyoresa ku IStorage. Implementations IStorage kana chiitiko chikaitika ModelChanged shanduko dzinoiswa mumitsetse mitatu - yekuwedzera, yekuvandudza, uye yekudzima.

Uyezve kushandisa IStorage pavanotanga, vanogadzira timer inokonzera shanduko kuti dzichengetedzwe ose 5 masekonzi. 

Uye zvakare, kune API yekumanikidza kuchengetedza kufona: ObjectRepository.Save().

Pamberi pese pese pese, zviito zvisina zvazvinoreva zvinotanga kubviswa kubva mumitsetse (semuenzaniso, kudzokorora zviitiko - apo chinhu chakachinjwa kaviri kana nekukurumidza kuwedzera / kubviswa zvinhu), uye ipapo chete chengetedza pachayo. 

Muzviitiko zvese, chinhu chose chazvino chinochengetedzwa, saka zvinogoneka kuti zvinhu zvinoponeswa mune imwe hurongwa pane zvayakashandurwa, kusanganisira nyowani nyowani dzezvinhu pane panguva yadzakawedzerwa kumutsara.

Chii chimwe chiripo?

  • Maraibhurari ese akavakirwa paNET Standard 2.0. Inogona kushandiswa mune chero yemazuva ano .NET project.
  • Iyo API ndeye thread yakachengeteka. Kuunganidzwa kwemukati kunoitwa zvichibva pa ConcurrentDictionary, vabati vezviitiko vangave vane makiyi kana kuti havaade. 
    Chinhu chimwe chete chakakodzera kurangarira kufona ObjectRepository.Save();
  • Arbitrary indexes (inoda kusaenzana):

repository.Set<ChildModel>().AddIndex(x => x.Value);
repository.Set<ChildModel>().Find(x => x.Value, "myValue");

Ndiani anoishandisa?

Ini pachangu, ndakatanga kushandisa nzira iyi mumapurojekiti ese ekuzvivaraidza nekuti iri nyore uye haidi mari yakakura yekunyora dhata rekuwana data kana kuendesa inorema zvivakwa. Ini pachangu, kuchengeta data mu litedb kana faira kazhinji kunondikwanira. 

Asi munguva yakapfuura, apo ikozvino-isina kushanda EscapeTeams (Ndakafunga kuti heino, mari - asi kwete, ruzivo zvakare) - inoshandiswa kuchengetedza data muAzure Tafura Storage.

Zvirongwa zvemangwana

Ndinoda kugadzirisa chimwe chezvakashata zvikuru zveiyi nzira - horizontal scaling. Kuti uite izvi, iwe unoda kana kugoverwa kwekutengeserana (sic!), Kana kuita sarudzo yakasimba-yakasimba kuti iyo data yakafanana kubva mumamiriro akasiyana haifanirwe kuchinja, kana kuti iite kuti ichinje maererano nemusimboti "ndiani wekupedzisira akarurama."

Kubva pane tekinoroji yekuona, ini ndinoona inotevera chirongwa sezvinobvira:

  • Chengetedza ChiitikoLog uye Snapshot panzvimbo yechinhu modhi
  • Tsvaga zvimwe zviitiko (wedzera magumo ezviitiko zvese kune zvigadziriso? udp kuwanikwa? master/muranda?)
  • Dzokorora pakati peChiitikoLog zviitiko kuburikidza nechero kubvumirana algorithm, senge RAFT.

Pane zvakare rimwe dambudziko rinondinetsa - kudzima cascade, kana kuona nyaya dzekudzima kwezvinhu zvine zvinongedzo kubva kune zvimwe zvinhu. 

Purogiramu yekupa

Kana iwe wakaverenga nzira yese kusvika pano, saka chasara kuverenga iyo kodhi; inogona kuwanikwa paGitHub:
https://github.com/DiverOfDark/ObjectRepository

Source: www.habr.com

Voeg