ObjectRepository -

Nahoana no mitahiry ny angona rehetra ao anaty fitadidiana?

Mba hitahiry angon-drakitra amin'ny tranokala na backend, ny faniriana voalohany amin'ny ankamaroan'ny olona salama dia ny misafidy angona SQL. 

Saingy indraindray ny eritreritra dia tonga ao an-tsaina fa ny modely angon-drakitra dia tsy mety amin'ny SQL: ohatra, rehefa manangana fikarohana na tabilao sosialy dia mila mitady fifandraisana sarotra eo amin'ny zavatra ianao. 

Ny toe-javatra ratsy indrindra dia rehefa miasa ao amin'ny ekipa ianao ary ny mpiara-miasa iray dia tsy mahay manamboatra fanontaniana haingana. Ohatrinona ny fotoana laninao namaha olana N+1 sy nanamboatra tondro fanampiny mba hahavitan'ny SELECT ao amin'ny pejy lehibe ao anatin'ny fotoana mety?

Fomba iray hafa malaza dia ny NoSQL. Taona maro lasa izay dia be dia be ny hype manodidina ity lohahevitra ity - ho an'ny fotoana mety rehetra dia nametraka MongoDB izy ireo ary faly tamin'ny valiny tamin'ny endrika json documents. (Raha ny marina, firy ny tehina tsy maintsy nampidirinao noho ny rohy boribory amin'ny antontan-taratasy?).

Manoro hevitra aho hanandrana fomba hafa hafa - maninona raha manandrana mitahiry ny angon-drakitra rehetra ao amin'ny fitadidiana fampiharana, mitahiry izany tsindraindray amin'ny fitahirizana kisendrasendra (rakitra, angon-drakitra lavitra)? 

Lasa mora ny fitadidiana, ary ny angona azo atao ho an'ny ankamaroan'ny tetikasa madinika sy salantsalany dia ho tafiditra ao anatin'ny fitadidiana 1 GB. (Ohatra, ny tetikasa an-trano tiako indrindra dia mpanara-maso ara-bola, izay mitazona ny antontan'isa isan'andro sy ny tantaran'ny fandaniana, ny fifandanjako ary ny varotra nataoko nandritra ny herintaona sy tapany, dia tsy mandany afa-tsy 45 MB fahatsiarovana.)

matihanina:

  • Lasa mora kokoa ny fidirana amin'ny angon-drakitra - tsy mila manahy momba ny fanontaniana ianao, ny fampidinana kamo, ny endri-javatra ORM, miasa amin'ny zavatra C# mahazatra ianao;
  • Tsy misy olana mifandray amin'ny fidirana amin'ny kofehy samihafa;
  • Haingana be - tsy misy fangatahana tambajotra, tsy misy fandikana ny kaody ho amin'ny fiteny manontany, tsy mila (de)serialization ny zavatra;
  • Ekena ny mitahiry angona amin'ny endriny rehetra - na amin'ny XML amin'ny kapila, na amin'ny SQL Server, na amin'ny Azure Table Storage.

maharatsy ny mifampiresaka:

  • Very ny fanamafisam-peo mitsivalana, ary vokatr'izany dia tsy azo atao ny fametrahana ny fotoana tsy misy fiatoana;
  • Raha mianjera ny fampiharana dia mety ho very ampahany ny angona. (Saingy tsy tapaka mihitsy ny fampiharana anay, sa tsy izany?)

Ahoana no miasa?

Ireto ny algorithm:

  • Eo am-piandohana, misy fifandraisana napetraka amin'ny fitahirizana angon-drakitra, ary fenoina ny angona;
  • Modely zavatra, fanondro voalohany, ary fanondro fifandraisana (1:1, 1: Maro) no natsangana;
  • Ny famandrihana dia noforonina ho an'ny fanovana amin'ny fananana zavatra (INotifyPropertyChanged) sy amin'ny fanampiana na fanesorana singa amin'ny fanangonana (INotifyCollectionChanged);
  • Rehefa atomboka ny famandrihana dia ampidirina ao amin'ny filaharana ny zavatra niova ho an'ny fitehirizana data;
  • Ny fiovana amin'ny fitahirizana dia voatahiry tsindraindray (amin'ny fameram-potoana) ao anaty kofehy ambadika;
  • Rehefa mivoaka ny fampiharana ianao dia voatahiry ao amin'ny fitahirizana ihany koa ny fanovana.

Ohatra Code

Manampy ireo fiankinana ilaina

// Основная библиотека
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

Manoritsoritra ny maodely data izay hotehirizina ao amin'ny fitahirizana izahay

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; }
}

Avy eo ny modely object:

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;
}

Ary farany, ny kilasin'ny tahiry ho an'ny fidirana 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();
    }
}

Mamorona ohatra ObjectRepository:

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

Raha hampiasa HangFire ny tetikasa

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

Mampiditra zavatra vaovao:

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

Miaraka amin'ity antso ity, ny zavatra ParentModel dia ampiana amin'ny cache eo an-toerana sy ny filaharana hanoratana amin'ny tahiry. Noho izany, ity hetsika ity dia maka O (1), ary ity zavatra ity dia azo ampiasaina avy hatrany.

Ohatra, mba hahitana an'io zavatra io ao amin'ny tahiry ary manamarina fa ny zavatra naverina dia ohatra iray ihany:

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

Inona no mitranga? Set () miverina TableDictionary, izay misy ConcurrentDictionary ary manome fiasa fanampiny amin'ny fanondro voalohany sy faharoa. Izany dia ahafahanao manana fomba fikarohana amin'ny alàlan'ny Id (na fanondroan'ny mpampiasa tsy ara-drariny) nefa tsy mamerina tanteraka ny zavatra rehetra.

Rehefa manampy zavatra amin'ny ObjectRepository Misy famandrihana ampiana hanovana ny fananany, ka izay fiovana amin'ny fananana dia miteraka koa ity zavatra ity ampidirina amin'ny filaharana fanoratana. 
Ny fanavaozana ny fananana avy any ivelany dia mitovy amin'ny miasa amin'ny zavatra POCO:

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

Azonao atao ny mamafa zavatra iray amin'ireto fomba manaraka ireto:

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

Manampy ny zavatra amin'ny filaharana famafana ihany koa izany.

Ahoana no fiasan'ny famonjena?

ObjectRepository rehefa miova ny zavatra araha-maso (na manampy na mamafa, na manova toetra), dia miteraka hetsika ModelChangednisoratra anarana ISstorage. Fampiharana ISstorage rehefa misy zava-mitranga ModelChanged Ny fanovana dia apetraka amin'ny filaharana 3 - amin'ny fanampiana, fanavaozana ary famafana.

Fampiharana ihany koa ISstorage amin'ny fanombohana dia mamorona fameram-potoana izay mahatonga ny fanovana ho voatahiry isaky ny 5 segondra. 

Ho fanampin'izay, misy API hanerena antso avo: ObjectRepository.Save().

Alohan'ny fitehirizana tsirairay, dia esorina amin'ny filaharana aloha ny hetsika tsy misy dikany (ohatra, hetsika dika mitovy - rehefa niova indroa na nampiana/nesorina haingana ny zavatra iray), ary avy eo dia ny famonjena ihany. 

Amin'ny toe-javatra rehetra dia voavonjy ny zavatra ankehitriny manontolo, noho izany dia azo atao ny mitahiry zavatra amin'ny filaharana hafa noho ny novaina, ao anatin'izany ny dikan-javatra vaovao kokoa noho ny tamin'ny fotoana nampidirina azy ireo tamin'ny filaharana.

Inona koa no misy?

  • Ny tranomboky rehetra dia mifototra amin'ny .NET Standard 2.0. Azo ampiasaina amin'ny tetikasa .NET maoderina rehetra.
  • Ny API dia azo antoka. Ny fanangonana anatiny dia ampiharina mifototra amin'ny ConcurrentDictionary, manana hidin-trano ny mpikarakara hetsika na tsy mila azy ireo. 
    Ny hany tokony hotsaroana dia ny miantso ObjectRepository.Save();
  • Fanondroana tsy ara-dalàna (mitaky ny maha-tokana):

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

Iza no mampiasa azy?

Izaho manokana dia nanomboka nampiasa an'io fomba fiasa io tamin'ny tetikasa fialamboly rehetra aho satria mety ary tsy mitaky fandaniana be amin'ny fanoratana sosona fidirana amin'ny data na fametrahana fotodrafitrasa mavesatra. Amiko manokana dia ampy ho ahy ny fitehirizana data ao anaty litedb na rakitra. 

Fa tamin'ny lasa, rehefa tsy misy intsony ny startup EscapeTeams (Nihevitra aho fa ity dia vola - fa tsia, traikefa indray) - ampiasaina hitahirizana angona ao amin'ny Azure Table Storage.

Drafitra ho an'ny ho avy

Te-hanamboatra ny iray amin'ireo tsy fahampiana lehibe amin'ity fomba ity aho - ny scaling horizontal. Mba hanaovana izany dia mila fifampiraharahana mizara ianao (sic!), na mandray fanapahan-kevitra matanjaka fa tsy tokony hiova ny angon-drakitra mitovy amin'ny tranga samihafa, na avelao hiova araka ny fitsipika hoe "iza no farany no marina."

Amin'ny lafiny ara-teknika, hitako ity tetika manaraka ity araka izay azo atao:

  • Mitahiry EventLog sy Snapshot fa tsy modely zavatra
  • Mitadiava tranga hafa (manampia teboka farany amin'ny tranga rehetra amin'ny toe-javatra? udp discovery? master/slave?)
  • Manaova kopia eo anelanelan'ny tranga EventLog amin'ny alàlan'ny algorithm consensus, toy ny RAFT.

Misy olana hafa koa izay mampanahy ahy - ny famafana cascade, na ny fahitana trangan'ny famafana ny zavatra misy rohy avy amin'ny zavatra hafa. 

Source

Raha efa namaky hatramin'ny farany ianao, dia ny mamaky ny kaody sisa tavela; hita ao amin'ny GitHub izany:
https://github.com/DiverOfDark/ObjectRepository

Source: www.habr.com

Add a comment