PDA

Pogčedajte punu verziju : mysql cache


robi-bobi
09. 01. 2006., 17:10
pozdrav

interesuje me da li je neko od vas koristio mysql cache-ing
da li ste zadovoljni njime?

koji bi cache algoritam bio bolji:
rucno uradjen iz jezika (PHP, cache bi se cuvao u fajlovima i obnavljao iz crona) ili koristiti MySQL cache

Ilija Studen
09. 01. 2006., 17:42
Sisteme za keširanje sam uglavnom pravio sam na nivou skripte. MySQL cache nisam koristio.

Možda ti se ovo učini zanimljivim:

- ADOdb keširanje (http://phplens.com/lens/adodb/docs-adodb.htm#caching) - nameravam da iskoristim ovu mogućnost uskoro pa javljam utiske.
- Cache_Lite PEAR paket (http://pear.php.net/package/Cache_Lite) - radi maksimalno korektno, a krajenje je jednostavan za korišćenje.

Bojan Zivanovic
10. 01. 2006., 00:03
MySQL ima interni cache i njega nemoj nikako da koristis, posto on obrise ceo cache za datu tabelu cim promenis (UPDATE) jedan red.. Znaci vrlo glupo, samo ce da uspori aplikaciju..
Najbolje resenje je memcached (http://www.danga.com/memcached/).
Svi veliki sajtovi ga koriste (livejournal,slashdot...)
Ima API za sve vece jezike...

robi-bobi
10. 01. 2006., 01:02
da, bas sam danas procitao za taj feature mysql cache-a
dakle, to otpada

stvarno glupo od mene sto se nisam ranije setio PEAR-a :D



<?php
require_once('Cache/Lite.php');

$options = array(
'cacheDir' => '/tmp/',
'lifeTime' => 3600
);

// Create a Cache_Lite object
$Cache_Lite = new Cache_Lite($options);

if ($data = $Cache_Lite->get('block1')) {
echo($data);
} else {
$data = 'Data of the block 1';
$Cache_Lite->save($data);
}

echo('<br><br>Non cached line !<br><br>');

if ($data = $Cache_Lite->get('block2')) {
echo($data);
} else {
$data = 'Data of the block 2';
$Cache_Lite->save($data);
}

?>

ovo izgleda obecavajuce
kod ovog paketa je samo 32kB, sto je opet sasvim, sasvim ok

moja prva ideja je bila da uradim file cache-iranje upravo na slican nacin, samo sam se cudio sta cu sa problemima konkurentnih write operacija.

Mozda na kraju samo 'ukradem' logiku iz Cache_Lite


u principu ne volim velike gotove projekte
sa ADOdb sam radio samo jednom - nije nikakav problem, ali ja radije koristim moj mali library
takodje, on ovde otpada jer je meni bolje raditi cache gotowog HTML koda, nego rezultata iz DB

edit:
takodje, mislim da je varijanta sa stalnim proveravanjem:

<?php
if(ima_kesha()) {
$block1 = ucitaj_kesh();
} else {
generate_kesh();
$block1 = ucitaj_kesh();
}

sporija od verzije gde ja znam da kesh postoji( i koji cu pregenerirati cron jobom) te zato uvek radim:

<?php
$block1 = ucitaj_kesh();


vasa misljenja?

Ilija Studen
10. 01. 2006., 07:43
Ne treba preterano vremena pa preraditi Cache_Lite da radi nezavisno od PEARa. Uradio sam to pre nekih godinu dana. Nikakav problem...

Ideja da uvek imaš spreman cache (kreiran od strane skripte, crona ili ručno od strane korisnika) je sasvim OK. Ali opet, sve zavisi od konkretnog slučaja. Proveravanja da li cache postoji i nije toliko usporenje ako je učitavanje potrebnih podataka iz baze dugo i zahtevno recimo.



Što se ADOdb tiče ni ja ne volim previše glomazna gotova rešenja, ali mi treba proveren skup PHP4 klasa koji radi lepo sa svim popularnim bazama, a da ja ne moram da izmišljam toplu vodu. ADOdb se pokazao kao dobro rešenje: odlične performanse, relativno mali kad se okreše na minimalnu instalaciju, gomile zgodnih i proverene mogućnosti... Ima i svojih mana, ali su zanemarive naspram onoga što dobijaš (provereno, brzo, bogato).

robi-bobi
10. 01. 2006., 16:41
stvar je u tome sto cu kesh regenerirati relativno brzo - bice blokova koji ce biti keshirani samo 5-10 min, mada ce biti i takvih koji ce imati do 5 dana lifetime

imedju ostalog (kad smo vec otisli u offtopic) koje su vase preporuke za ubzanje koda?
radi se o sajtu koji ima preko 4 000 registrovanih korisnika, dobar deo njih je veoma aktivan u vreme nekih takmicenja i glasanja, tako da je u to vreme server dosta 'zauzet'
(sajt je dostupan i neregistrovanim posetiocima)

evo i daljih mojih razmisljanja:
- sajt ce biti multilingual. ono sto se moze keshirati ce biti u language-specific keshu. U principu za obicne fraze ('login', 'username' i sl) obicno imam nekoliko fajlova tipa: translation.en.php koje inkludujem u zavistosti od izabranog jezika. neko bolje resenje?
- mod_rewrite - koliko on ustvari opterecuje server? procena u procentima mi saswim odgowara


takodje, izgleda da cu morati da im napisem i mali forumchic
tipovi imaju phpBB, koji po meni nije prijateljski nastrojen ka resursima. koliko sam mogao shvatiti od kratkog researcha, gotovi forumi imaju sledece boljke:
- pre ili kasnije postanu teski
- oni koji nisu jos uvek postali teski, imaju mali lifetime, sto znaci da nisu dobro oprobani protiv svakojakih hack-ova i sl - a upravo to je ono sto je meni dosta bitno
najverovatnije cu uraditi neki tiny forum sa naj-naj vaznijim opcijama iz phpBB-a i toliko :)

moderatori: mozda da splitujemo temu i da od mog posta: "da, bas sam danas procitao za taj feature mysql cache-a ....." ovo ode u PHP?

Ilija Studen
10. 01. 2006., 20:54
Pogledaj ovu temu (http://www.devprotalk.com/t237-performanse-velikih-phpmysql-projekata.html).

ivanhoe
11. 01. 2006., 00:57
- sajt ce biti multilingual. ono sto se moze keshirati ce biti u language-specific keshu. U principu za obicne fraze ('login', 'username' i sl) obicno imam nekoliko fajlova tipa: translation.en.php koje inkludujem u zavistosti od izabranog jezika. neko bolje resenje?


ja preferiram gettext jer je standard, i olaksava posao oko odrzavanja prevoda (sam cupa reci koje treba prevesti i pravi language fajl), ali sto se tice perfomansi je verovatno slabije resenje od tvog...

Ako imas puno include-a razmisli da na server instaliras APC ili neko slicno resenje (mozda i komercijalni Zend optimizer) jer oni kesiraju inkludovane fajlove u izkomajliranoj formi sto moze znacajno da ubrza stvari...


- mod_rewrite - koliko on ustvari opterecuje server? procena u procentima mi saswim odgowara


u principu overhead je vrlo mali jer se radi o veoma optimizovanom kodu koji koristi unapred kompajlirane regExp-e, ali brzina zavisi dosta od RewriteRules koje koristis i na to treba paziti. Procitaj manual za mod_rewrite za detaljno objasnjenje, ali ukratko treba da:
1. rules stavis u httpd.conf (a ne u .htaccess) ako imas privilegije naravno naravno,
2. da izbegavas pravila koja pristupaju fajl sistemu ( -f , -d i slicno)
3. da izbegavas externe [R] redirekte... ako su ti pravila u httpd.conf onda ti [L] flag (leave) ne dodaju overhead jer nije potreban interni redirekt, a ako su u .htaccess onda da, i tada treba izbegavati visestruke [L] redirekte (mada su interni redirekti i dalje brzi od externih)
4. Ako koristis .htacess fajlove, onda treba u svaki sub-direktorijum da stavis .htaccess, makar i prazan, jer ako apache ne nadje .htaccess u dir-u on ga trazi na gore kroz hijerarhiju direktorijuma sve do roota. Znaci ako mu ga odmah das, ustedeces mu par pristupa faj sistemu (ili jos bolje ako mozes iskljuci .htacess i postavi sva podesavanja u httpd.conf)

a tacne procente ne znam, naravno, najzdravije je da sam testiras i vidis kako se ponasa na tvom sistemu..

bluesman
11. 01. 2006., 01:32
Vrlo interesantna tema...

Ja sam koristio svoj neki interni cache, na osnovu ovoga sto vidim radi slicno ovaj PEAR klasi, samo sto ja nemam te ostale "fensi" opcije, vec jedino (un)serialize i slicno se ponasa kao session.

To je najprimenjivije na stranama kao sto su "who is online" sa mnogo usera, recimo kod mene je to najpopularnija strana i u minuti imam i po 30 querija, manje-vise identicnih... a za minut, malo toga moze i da se promeni, a i ako se promeni, nije kriticno.

Mysql cache nisam nikada ni pokusavao da koristim, moram da verujem na rec Bojanu, mada ne mogu da poverujem da su to bas tako traljavo odradili da je neupotrebljivo.

Koliko sam ja upoznat, mysql ima svoj interni cache querija pa cak i ako ne koristis cache i ako saljes isti query nekoliko puta, ona ga cache-ira interno. To se lako moze videti kada izvrsite neki komplikovan query nad velikom tabelom i merite execution time. Prvi put je uvek najveci, zatim pada uvek na 0,0x sekundi...

Prvo sto sam razmisljao kada sam pravio moj mali cache je da je uvek brze procitati iz mysql nego iz filesystem-a, medjutim kada bolje razmislis i mysql pristupa filesystem-u pa ako stvarno ima smisla (query je komplikovan) onda je sasvim opravdano citati iz cache pre nego baze.

Moram da probam i ovaj memcached.

robi-bobi
11. 01. 2006., 11:11
da, zaista, ovo sto je ivanhoe rekao za httpd i .htaccess je tako logicno a nisam se toga setio.
hvala opet za hintove za mod_rewrite. otprilike sam upoznat sa svim onim njegovim flagovima, ali bicu dobar, evo idem da citam apache man.

ilija, tu temu sam citao ranije, ali je svakako odlicna. Hvala sto si me podsetio na nju


Prvo sto sam razmisljao kada sam pravio moj mali cache je da je uvek brze procitati iz mysql nego iz filesystem-a

da, i ja sam se pitao sta je ustvari brze... Ipak sql server je napravljen (izmedju ostalog ) za to - da prima stotine konkurentnih upita. A filesystem - kako ce se to drzati na sajtu koji ima puno request-a. Videcemo. Po meni bi kesh trebao biti brzi, jer:
- mysql koristi filesystem (ma koliko optimizovan nacin njegovog pristupa bio, opet je to filesystem)
- zahvaljujuci pear klasi, videcu kako je resheno pitanje lock-ova fajlowa i konkurentnih write operacija. Taj problem takodje otpada
- ponekad ce podaci zahtevati obradu u PHP-u. kesh tu takodje dobija bitku

dakle, sve u svemu zakljucak je sledeci:
- rucni kesh (najverovatnije uradjen od PEAR kech-a) je ok. Keshiracu gotovi html, ne DB objekte
- translation: gettext je dobar, mada verovatno fajl sa translationima takodje radi isti posao (mozda i bolji). U ovom slucaju ja cu se verovatno odluciti za lang file koji mi je poznatiji pristip
- mod_rewrite - ok je koristiti, treba paziti ipak. Sajt ce biti na sopstvenom serveru, tako da cu izkljuciti .htaccess
- uraditi enkode (zend encode je ipak skup (najjeftinija varijanta: $2400/lifetime), pogledacu i alternative)


naravno pazicu na petlje, "dobar programerski stil", radicu include samo onih fajlova koji mi trebaju i samo tamo gde mi treba itd

ivanhoe
11. 01. 2006., 22:11
a jeste li razmisljali o upotrebi temp tabela koje su tipa HEAP, to jest drze se u memoriji servera ?

Nisam nikad merio vreme, ali su HEAP tabele prilicno brzo, ja sam tu tehniku koristio za kesiranje hijerarhije kategorija (posto su se u bazi cuvali samo parent id za pod-kategorije, pa onda to treba prevezati u stablo..) i fino je radilo... nema pojma doduse koliko je to brzo u poredjenju sa fajlovima, meni je trebao sql join, pa mi je odgovaralo da koristim bazu za to, da ne moram rucno da ga radim...

mislim da postoji i neka fora da se nalozi mysql da za obicnu myisam tabelu cuva index u memoriji umesto u zasebnom fajlu, jel zna neko nesto o tome ???

Petar Marić
11. 01. 2006., 23:53
Hm, mislim da HEAP (aka MEMORY) tabele nisu najefikasnije rešenje za keš, osim ako ne želiš da izgubiš sav sadržaj keša pri restartovanju servera :D

14.3. The MEMORY (HEAP) Storage Engine
The MEMORY storage engine creates tables with contents that are stored in memory. Before MySQL 4.1, MEMORY tables are called HEAP tables. As of 4.1, MEMORY is the preferred term, and HEAP is a synonym for MEMORY.

Each MEMORY table is associated with one disk file. The filename begins with the table name and has an extension of .frm to indicate that it stores the table definition.

To specify explicitly that you want a MEMORY table, indicate that with an ENGINE or TYPE table option:

CREATE TABLE t (i INT) ENGINE = MEMORY;
CREATE TABLE t (i INT) TYPE = HEAP;

MEMORY tables are stored in memory and use hash indexes by default. This makes them very fast, and very useful for creating temporary tables. However, when the server shuts down, all data stored in MEMORY tables is lost. The tables continue to exist because their definitions are stored in the .frm files on disk, but their contents are empty when the server restarts.

... Ako pročitate celokupnu stranicu možete zaključiti sledeće o HEAP/MEMORY tabelama:
Pros:
1. Brže su

Cons:
1. Zahtevaju dodatni RAM
2. Celokupne se moraju nalaziti u RAM-u
3. Pri restartovanju servera gube se podaci sadržani u njima (definicije same tabele ostaju)
4. Mogući sinhronizacioni problemi ako koristimo replikaciju
5. Ne podržavaju BLOB i TEXT polja (kao i njihove varijante, duh)
6. Polja tabele su fiksne dužine

Eto, sad je samo ostalo da se dodaju korektivni faktori za svaku stavku i da donesemo odluku (narodski rečeno: da izvagamo rešenje) ;)

bluesman
12. 01. 2006., 00:55
Heap tabele su (po meni) jedino dobre za privremene transakcije kada je potrebna temp tabela... iako mysql moze automatski da kreira TEMPORARY table pa da je brise po zavrsetku sesije, heap je ipak dosta brzi... Istina, igrao sam se sa tim cisto zbog testiranja i jednostavno nisam mogao da nadjem dobar razlog za neku drugu primenu.

Sto se tice tvog "Cons" br 3. to i nije tako "cons", narocito ako se koristi za kesiranje.

Petar Marić
12. 01. 2006., 01:52
Hmm, zavisi od situacije - ali se u opštem slučaju slažem s tobom Gorane.

zextra
12. 01. 2006., 13:21
A mozda za podatke koji slobodno mogu da nestanu nakon restarta servera? Mislim da se za svaki podatak moze reci da je bitan, ali isto tako (bar po meni) postoje situacije kada se podatak moze proglasiti nevaznim (npr. pre-generisani captcha kodovi koji nisu prosli validaciju, a jos uvek nisu uklonjeni iz nekog razloga, ili tabela sa aktivnim sesijama...)

Sto se tice privremenih tabela, ja sam koristio MyISAM jer sam imao potrebu da ucitam veliku kolicinu podataka, sortiram ih na nekoliko nacina, izracunam poziciju svakog clana doticnog niza prilikom svakog od sortiranja, i dobijene podatke da ucitam u stvarnu tabelu... Bez da zalazim u dalju problematiku, ne znam zasto se nisam odlucio za HEAP tabele, iako sam znao da postoje - morao bih to ponovo da uradim da bih uocio problem na koji sam tada naisao...

bojan_bozovic
12. 01. 2006., 15:22
A CREATE TABLE tabela1 TYPE=HEAP SELECT ... Da li se pogledi skladiste u memoriji? Ja cu da prenesem podatke iz moje baze na serveru u lokal (v5) da bas vidim hoce li tabela tipa HEAP uz DROP TABLE IF EXISTS da bude brze resenje od pogleda, jer poglede imam samo u lokalu. Mogu li ja nekako znati da li je DB server pao, pa ako jeste da regenerisem tabele? Mada MySQL ima svoj interni cache, za malo podataka i mnogo UPDATE upita bilo bi mozda bolje da se ide sa tabelom tipa HEAP (moj slucaj).

BEGIN ;# MySQL returned an empty result set (i.e. zero rows).
CREATE TABLE TMP(
PRIMARY KEY ( UID )
) TYPE = HEAP SELECT UID, USERNAME, AVERAGE
FROM USER
LEFT JOIN VOTES ON USER.UID = VOTES.USERID;# Affected rows:64
UPDATE TMP SET AVERAGE =10 WHERE UID =2;# Affected rows:1
SELECT *
FROM TMP
ORDER BY AVERAGE DESC ;# Rows: 64
COMMIT ;# MySQL returned an empty result set (i.e. zero rows).


Pogledi na MySQL 3.23 ;) Plus sto mozemo da udaramo upite u memoriju koliko zelimo (da li moze UPDATE ili INSERT INTO pa SELECT kod pogleda?) Naravno na kraju se udari REPLACE ili INSERT INTO ... SELECT - hmm SELECT nema smisla zbog BEGIN...COMMIT ali ovako mozemo da implementiramo AUTOCOMMIT=0 na MyISAM tabelama (ispravite me ako gresim) - jer ovo je rucno upravo ono sto InnoDB radi - pise u memoriju ;) I pre zadnjeg REPLACE nista ne moze biti upisano u tabelu ako server padne ;) Gledao sam prakticno na ovo kao na implementaciju pogleda u MySQL<5.0 ali ispade da moze vise da se uradi ;)