Huwag kailanman isulat ang iyong solusyon sa pag-cache

Ang isa pang paraan upang mapabilis ang trabaho sa database ay ang pag-cache ng mga bagay na hiniling na namin kanina.

Mahalaga! Huwag kailanman isulat ang iyong sariling solusyon sa pag-cache. Ang gawaing ito ay may napakaraming pitfalls na hindi mo pinangarap.

Isyu 1 - cache flush . Minsan nangyayari ang mga kaganapan kapag ang isang bagay ay kailangang alisin sa cache o i-update sa cache. Ang tanging paraan upang magawa ito nang may kakayahan ay ipasa ang lahat ng mga kahilingan sa database sa pamamagitan ng cache engine. Kung hindi man, sa bawat oras na kailangan mong tahasang sabihin sa cache kung aling mga bagay sa loob nito ang dapat tanggalin o i-update.

Problema 2 - kakulangan ng memorya . Ang pag-cache ay tila isang magandang ideya hanggang sa makita mo na ang mga bagay sa memorya ay kumukuha ng maraming espasyo. Kailangan mo ng karagdagang sampu-sampung gigabytes ng memorya para gumana nang epektibo ang cache ng application ng server.

At dahil palaging may kakulangan sa memorya, kailangan ang isang epektibong diskarte para sa pagtanggal ng mga bagay mula sa cache. Ito ay medyo katulad ng tagakolekta ng basura sa Java. At gaya ng naaalala mo, sa loob ng maraming dekada ang pinakamahusay na mga isip ay nag-imbento ng iba't ibang paraan ng pagmamarka ng mga bagay sa pamamagitan ng mga henerasyon, atbp.

Problema 3 - iba't ibang estratehiya . Tulad ng ipinapakita ng kasanayan, ang iba't ibang mga diskarte para sa pag-iimbak at pag-update sa cache ay epektibo para sa iba't ibang mga bagay. Ang isang mahusay na sistema ng pag-cache ay hindi maaaring gumawa ng isang diskarte lamang para sa lahat ng mga bagay.

Problema 4 - Mahusay na pag-iimbak ng . Hindi ka maaaring mag-imbak lamang ng mga bagay sa cache. Ang mga bagay ay masyadong madalas na naglalaman ng mga sanggunian sa iba pang mga bagay, at iba pa. Sa rate na ito, hindi mo na kailangan ng isang basurero: wala itong anumang aalisin.

Samakatuwid, sa halip na mag-imbak ng mga bagay sa kanilang sarili, kung minsan ay mas mahusay na mag-imbak ng mga halaga ng kanilang mga primitive na larangan. At mga sistema para sa mabilis na pagbuo ng mga bagay batay sa kanila.

Bilang resulta, makakakuha ka ng isang buong virtual na DBMS sa memorya, na dapat gumana nang mabilis at kumonsumo ng kaunting memorya.

Pag-cache ng database

Bilang karagdagan sa pag-cache nang direkta sa isang Java program, ang pag-cache ay madalas na direktang nakaayos sa database.

Mayroong apat na malalaking diskarte:

Ang unang diskarte ay ang denormalize ang database . Ang SQL server ay nag-iimbak ng data sa memorya nang iba sa kung paano ito iniimbak sa mga talahanayan.

Kapag ang data ay naka-imbak sa disk sa mga talahanayan, madalas na sinusubukan ng mga developer na maiwasan ang pagdoble ng data hangga't maaari - ang prosesong ito ay tinatawag na normalisasyon ng database. Kaya, upang mapabilis ang trabaho sa data sa memorya, ang reverse na proseso ay ginaganap - database denormalization. Ang isang grupo ng mga kaugnay na talahanayan ay maaari nang maimbak sa isang pinagsamang anyo - sa anyo ng mga malalaking talahanayan, atbp.

Ang pangalawang diskarte ay query caching . At mga resulta ng query.

Nakikita ng DBMS na madalas na pareho o katulad na mga kahilingan ang dumarating dito. Pagkatapos ay magsisimula lamang itong i-cache ang mga kahilingang ito at ang kanilang mga tugon. Ngunit sa parehong oras, kailangan mong tiyakin na ang mga hilera na nagbago sa database ay tinanggal mula sa cache sa isang napapanahong paraan.

Ang diskarte na ito ay maaaring maging napaka-epektibo sa isang tao na maaaring magsuri ng mga query at makatulong sa DBMS na malaman kung paano pinakamahusay na i-cache ang mga ito.

Ang ikatlong diskarte ay isang in-memory database .

Isa pang karaniwang ginagamit na diskarte. Ang isa pang database ay inilalagay sa pagitan ng server at ng DBMS, na nag-iimbak ng lahat ng data nito sa memorya lamang. Tinatawag din itong In-Memory-DB. Kung mayroon kang maraming iba't ibang mga server na nag-a-access sa parehong database, gamit ang In-Memory-DB maaari mong ayusin ang pag-cache batay sa uri ng isang partikular na server.

Halimbawa:

Diskarte 4 - database cluster . Ilang read-only na base.

Ang isa pang solusyon ay ang paggamit ng isang cluster: maraming DBMS ng parehong uri ang naglalaman ng magkaparehong data. Kasabay nito, maaari mong basahin ang data mula sa lahat ng mga database, at sumulat sa isa lamang. Na pagkatapos ay naka-synchronize sa iba pang mga database.

Ito ay isang napakahusay na solusyon dahil ito ay madaling i-configure at gumagana sa pagsasanay. Karaniwan, para sa isang kahilingan sa database na baguhin ang data, 10-100 mga kahilingan para sa pagbabasa ng data ang dumating dito.

Mga uri ng caching sa Hibernate

Sinusuportahan ng hibernate ang tatlong antas ng pag-cache:

  • Pag-cache sa antas ng session (Session)
  • Pag-cache sa antas ng SessionFactory
  • Mga kahilingan sa pag-cache (at ang kanilang mga resulta)

Maaari mong subukang katawanin ang sistemang ito sa anyo ng naturang figure:

Ang pinakasimpleng uri ng pag-cache (tinatawag ding unang antas ng cache ) ay ipinatupad sa antas ng Hibernate session. Palaging ginagamit ng hibernate ang cache na ito bilang default at hindi maaaring i-disable .

Isaalang-alang natin kaagad ang sumusunod na halimbawa:

Employee director1 = session.get(Employee.class, 4);
Employee director2 = session.get(Employee.class, 4);

assertTrue(director1 == director2);

Maaaring mukhang dalawang query sa database ang isasagawa dito, ngunit hindi ito ganoon. Pagkatapos ng unang kahilingan sa database, ang object ng Empleyado ay mai-cache. At kung itatanong mo muli ang object sa parehong session, ibabalik ng Hibernate ang parehong object ng Java.

Ang parehong bagay ay nangangahulugan na kahit na ang mga object reference ay magkapareho. Ito ay talagang ang parehong bagay.

Ang save() , update() , saveOrUpdate() , load() , get() , list() , iterate() , at scroll() na mga pamamaraan ay palaging gagamit ng unang antas ng cache. Actually, wala nang idadagdag pa.

Pangalawang antas ng pag-cache

Kung ang unang antas ng cache ay nakatali sa session object, ang pangalawang antas ng cache ay nakatali sa session object.SessionFactory. Na nangangahulugan na ang visibility ng mga bagay sa cache na ito ay mas malawak kaysa sa unang antas ng cache.

Halimbawa:

Session session = factory.openSession();
Employee director1 = session.get(Employee.class, 4);
session.close();

Session session = factory.openSession();
Employee director2 = session.get(Employee.class, 4);
session.close();

assertTrue(director1 != director2);
assertTrue(director1.equals(director2));

Sa halimbawang ito, dalawang query ang gagawin sa database. Ang hibernate ay magbabalik ng magkatulad na mga bagay, ngunit hindi ito magiging parehong bagay - magkakaroon sila ng magkakaibang mga sanggunian.

Ang pangalawang antas ng pag-cache ay hindi pinagana bilang default . Samakatuwid, mayroon kaming dalawang query sa database sa halip na isa.

Upang paganahin ito, kailangan mong isulat ang mga sumusunod na linya sa hibernate.cfg.xml file:

<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletEhCacheProvider"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>

Pagkatapos i-enable ang pag-cache sa pangalawang antas, medyo magbabago ang gawi sa Hibernate:

Session session = factory.openSession();
Employee director1 = session.get(Employee.class, 4);
session.close();

Session session = factory.openSession();
Employee director2 = session.get(Employee.class, 4);
session.close();

assertTrue(director1 == director2);

Pagkatapos lamang ng lahat ng mga manipulasyong ito ay paganahin ang pangalawang antas na cache, at sa halimbawa sa itaas, isang query lamang sa database ang isasagawa.