ugrás a tartalomhoz

ETAG tárolása fájlban

inf3rno · 2013. Szep. 27. (P), 13.00
Üdv.

Le szeretnék tárolni egy etag-et a szerveren, amit minden változtatáskor módosítanék, illetve minden lekéréskor ehhez nyúlna a szerver, hogy változott e a megadotthoz képest a helyzet... Annyi a problémám ezzel kapcsolatban, hogy jelenleg nincs memcached, és nem is valószínű, hogy lesz ilyesmi a tárhelyen. Ha fájlban tárolom, akkor minden egyes lekérés azt az egy fájlt akarja majd elérni, tehát valószínűleg az lesz a szűk keresztmetszet az alkalmazásban. Olyan szempontból szerencsém van, hogy egy kis forgalmú oldal lesz, amit csinálok, tehát ennél a projektnél biztosan nem okoz majd gondot. Szerintetek nagy forgalmú oldalaknál az ilyesmi problémát jelenthet?
 
1

Kicsit konkrétabban is

Joó Ádám · 2013. Szep. 27. (P), 13.07
Kicsit konkrétabban is leírhatnád a helyzetet, mert így nem tiszta, miről van szó.
2

Melyik része nem érthető?

inf3rno · 2013. Szep. 27. (P), 13.15
Melyik része nem érthető?
3

Minek a változását indikálja

Joó Ádám · 2013. Szep. 27. (P), 13.20
Minek a változását indikálja az etag?
5

Bármilyen adatét. Nincs

inf3rno · 2013. Szep. 27. (P), 13.22
Bármilyen adatét. Nincs kedvem részletes cache-t írni.

szerk:
Rosszul olvastam. Ha változik bármilyen adat a szerveren, akkor változik az etag. Az etag a kliens állapotának a megváltozását indukálja, a szerver szempontjából lényegtelen.
7

Tárold munkamenetben,

Joó Ádám · 2013. Szep. 27. (P), 13.25
Tárold munkamenetben, gondolom a PHP valamilyen szinten optimalizálja a hozzáférést. Tárold fájlnévben, a stat talán olcsóbb, mint a fájlnyitás. Esetleg írj egy TCP szervert, amihez kapcsolódsz és lekérdezed.

De az igazság az, hogy ha PHP-t használsz, akkor már eleve annyi erőforrást pazarolsz el, hogy ezen semmi értelme optimalizálni.
8

Okés, akkor nem foglalkozok a

inf3rno · 2013. Szep. 27. (P), 13.30
Okés, akkor nem foglalkozok a dologgal. Az igazi az lenne, ha írnék egy cache service-t, ahol minden erőforráshoz/erőforrás csoporthoz külön etag-eket tárolnék, de nincs most erre kapacitásom, lehetőségem, a projekt meg egyébként sem indokolja. Éppen azon fáradozom, hogy automatikusan generáltassak minden egyes oldalt a klienssel.
4

A memcached-nek és társaiknak

Hidvégi Gábor · 2013. Szep. 27. (P), 13.21
A memcached-nek és társaiknak akkor van jelentősége, ha sok adatot szeretnél elosztottan, több szerveren megosztani. Kis site-nál a fájlba való írás gyors, mert állandóan a memóriában van, én már próbáltam többmegabájtos PHP munkameneteket memcached-ben és redisben tárolni, és nem volt gyorsabb, mint a hagyományos, fájl alapú megoldás.
6

Én inkább arra gondoltam,

inf3rno · 2013. Szep. 27. (P), 13.25
Én inkább arra gondoltam, hogy minden változtatásnál lockolja a kérés ugyanazt a fájlt, emiatt a többi kérésnek várnia kell, amíg végez az előző az etag frissítéssel. Ez szerintem biztosan bekövetkezik egy kérés szám felett. Vajon mekkora lehet ez a kérés szám?
9

Szerintem a lockolás nagy

Hidvégi Gábor · 2013. Szep. 27. (P), 13.34
Szerintem a rendszer által biztosított lockolás nagy előny, mert nem neked kell megvalósítanod. Ez a szám szerintem nagy, mert beolvasod a fájlt, és ha a kezelőjét mindjárt el is elengeded, azaz tízezredmásodperces időtartam az egész. Én nem filozofálnék rajta, megcsinálnám, aztán majd ha ez lesz a szűk keresztmetszet, elgondolkodnék, mivel lehetne kiváltani.
10

Igazad van, alapnak jó ez a

inf3rno · 2013. Szep. 27. (P), 13.37
Igazad van, alapnak jó ez a megoldás, ha meg ebből szűk keresztmetszet lesz, akkor meg már úgyis új tárhely kell a kérések száma miatt, az új tárhelynél meg akkor már lehetőség lesz a memóriába rakásra.
24

Szerintem is, itt bőven elég

BlaZe · 2013. Szep. 29. (V), 13.58
Szerintem is, itt bőven elég a file szintű lock (ha csak az írás idejére van), ágyúval verébre lenne egy komolyabb megoldás. De értelemszerűen érdemes elrejteni egy interface mögé, hogy egyszerű legyen a cseréje. Durvább terhelésnél viszont már nem jó a file lock, mert szinkron hívás (és nem skálázható), gyakorlatilag az erőforráson szinkronizálsz közvetlenül, ami rossz esetben egyszerre sok szálat tarthat waitben, és egy szint felett ebből az állapotból már nem tud kijönni a rendszer, gyakorlatilag leDOSolod magad :)

Itt az agyam előrángatja a Single Writer Principle-t, ami valahol jogos, viszont a gugli erre adott találatai mind Martin Thompson blogjára mutatnak, ami CPU architektúra szinten tárgyalja a problémát, és ez talán túl mély ehhez a témához. De azért csak leírtam :), mert egyrészt a téma iránt érdeklődőknek ezek az írások igazi csemegék (Martin Thompson blogja a témában etalonnak számít), másrészt ez nagyban is igaz.

Kicsit visszakanyarodva a témához itt egy async service tud segíteni. PHP-val (önmagában) viszont itt már komoly architekturális falakba ütközöl, valóban külső service kell hozzá. De +1 annak, hogy ezzel a problémával addig ne foglalkozz, amíg nem kerül elő.
29

Ez a Disruptor, amiről ír

inf3rno · 2013. Szep. 30. (H), 05.37
Ez a Disruptor, amiről ír ugyanúgy event cycle-t használ, mint nodejs? Esetleg írhatnál cikket konkurrencia kezelésről, meg többszálú alkalmazásokról, szívesen olvasnék róla. :-)

szerk:
Közben tovább olvastam, aztán ja, a nodejs is valami hasonlót használ.
Nem igazán látom, hogy a single writer principle hogyan lenne megvalósítható ennél a fájlba írásos problémánál... Kéne csinálni egy daemont neki, ami queue-be rakja a kéréseket, és azt hívogatni, vagymi? :D A lock is ugyanezt csinálja, nem?
31

Én is!

Pepita · 2013. Szep. 30. (H), 22.35
Esetleg írhatnál cikket konkurrencia kezelésről, meg többszálú alkalmazásokról, szívesen olvasnék róla. :-)
felkérések száma: 2. :)
12

Nagyjából akkor öli meg a

tgr · 2013. Szep. 28. (Szo), 09.42
Nagyjából akkor öli meg a szerveredet, amikor a kérések másodpercenkénti száma nagyobb lesz, mint egy kérés kiszolgálási idejének a reciproka. (Alatta is bekövetkezik, de akkor csak a felhasználói élményt rontja.)
14

Nem tudom jól értem e, a

inf3rno · 2013. Szep. 28. (Szo), 13.34
Nem tudom jól értem e, a kérés kiszolgálása a teljes http kérésre vonatkozik, vagy csak a fájlba írásra. Pl ha a teljes http kérés kiszolgálása 200msec, akkor 1/0,200 = 5 kérés / másodperc, ami kinyírja, ami azért nem túl sok. :S
16

Engem az is érdekelne, hogy

Joó Ádám · 2013. Szep. 28. (Szo), 13.49
Engem az is érdekelne, hogy mit értünk kinyírja alatt? Illetve milyen szerverparaméterek mellett.
20

Ha egy kérés kiszolgálása

tgr · 2013. Szep. 29. (V), 12.29
Ha egy kérés kiszolgálása tovább tart, mint amennyi szabad ideje van a szervernek, mielőtt megérkezik a következő kérdés, annak nyilván nem lesz jó vége. A paraméterektől legfeljebb az függ, hogy elkezd kéréseket eldobálni, vagy csak csendben meghal.
23

Állandó terhelés mellett ez

Joó Ádám · 2013. Szep. 29. (V), 12.55
Állandó terhelés mellett ez nyilván így van, de azért reális körülmények között a terhelés hullámozni szokott. Ha van elég sávszélesség, memória, CPU, akkor a következő hullámvölgyben behozhatja magát, és csak lassult a kiszolgálás, de kérés nem veszett el. Vagy nem jól látom?
30

Szerintem nem jól, ha nagyobb

tgr · 2013. Szep. 30. (H), 09.33
Szerintem nem jól, ha nagyobb lesz a kérések kiszolgálási ideje, mint a két kérés beérkezése közötti késleltetés, akkor elkezd nőni a várakozó kérések száma, és két dolog történhet: vagy úgy van bekonfigurálva a webszerver, hogy egyszerre csak X requestet szolgáljon ki (X tipikusan pár tíz), és a látogatók egy része elkezd 503-as hibaoldalakat kapni (és amikor lejön a hullámhegyről a szerver, akkor helyreál a normális működés, de az elveszett requestek már elvesztek), vagy nincs benne ilyen védelem, és akkor elfogy a memória, vagy más hasonló kellemetlenség történik, és jó eséllyel valami olyan állapotba kerül a szerver, amiből már nem tud magától felállni.

Persze ha nagyon rövid a hullámhegy (csak egy-két request idejéig tart), akkor nincs probléma egyik esetben sem.
21

Gondolom a request elején

tgr · 2013. Szep. 29. (V), 12.36
Gondolom a request elején szerzed meg a write lockot, mert ha a végén szereznéd meg csak, akkor mindenféle vicces versenyhelyzetek alakulhatnának ki, úgyhogy a teljes request idejére ki van lockolva a többi request. 5 write request / sec amúgy meglehetősen sok, ha 100 felhasználód van, akkor átlagban 20 másodpercenként kell menteniük hozzá, ami egy ügyviteli szoftvernél szerintem nem tipikus.
22

Mi történne, ha csak a

inf3rno · 2013. Szep. 29. (V), 12.45
Mi történne, ha csak a sikeres tranzakciók végén írnám át a fájlt, és addig nem lockolnám?
25

Semmi

Pepita · 2013. Szep. 30. (H), 02.56
Itt a fájl írási idején van a hangsúly, nyilván ha a folyamat elején van, akkor is ugyanazon feltételek mellett akarod írni, nem? Furcsállanám, ha adatváltozás nélkül te újraírnál valamit. De szerintem felesleges rajta filózni, annyira kevés kérésed lesz. Az interface jó ötlet, téged ismerve biztos úgy lesz. Akkor, ha bekövetkezik a kb lehetetlen, a fájl helyett bedobod db-be, sessionbe, máshova.
26

Ha túl sok lesz a kérés,

inf3rno · 2013. Szep. 30. (H), 03.14
Ha túl sok lesz a kérés, attól még ugyanúgy maradhat fájlrendszerben, csak szét kell osztani aloldalanként külön fájlokra, aztán meg ha már az sem elég, akkor be lehet tenni memóriába. Ez nem annyira nagy kunszt.

Inkább az érdekelne, hogy miért kell már a kérés elején lockolni az etag fájlt módosításra, és csak a végén módosítani. Gyakorlati haszna szerintem ennek egyáltalán nincs. Tegyük fel, hogy a tranzakció commit megvolt, de az etag fájl még nem frissült, és ilyenkor jön egy get a szerver felé. Ilyenkor az előző etaggel kapja meg a kérés a friss adatot. Maximum a következő kéréskor újra lekéri ugyanazt az adatot csak akkor már a friss etag-el, vagy ha kesselve volt az adat, akkor úgy veszi, hogy még nem módosult. Ha nem get, hanem mondjuk post kérés jön, akkor az etag annak a szempontjából tök lényegtelen, mert azt nem kesseljük. Szóval összességében szerintem nem kell teljes kérésre lockolni, elég csak arra a néhány mikroszekundumra lockolni a rendszert, amíg a fájl írása megtörténik, vagy esetleg arra a pár milliszekundumra, amíg a commit lemegy az adatbázisban, ha már tényleg alaposak akarunk lenni... Szóval az 5 req/sec helyett simán lehet az akár 1000 req/sec is...
27

A feladatból kiindulva

Pepita · 2013. Szep. 30. (H), 03.32
én mindjárt az "elején" írnám is a fájlt, hiszen kiderül az Etag mibenléte (megjön a kérés + az adat db-ből), és már szabadítanám is fel. A végig lock szerintem arra jó, hogy egy egész végrehajtást kvázi tranzakcióként kezelj, de neked itt csak arra van szükséged, hogy letöltendő-e a cucc, vagy nem. Tehát felesleges végig lockolni, ha más is akarja írni, vár.
Bár pont az lehet mögötte, hogy egyszerre jön két kérés, és mindkettő megállapítja, hogy frissíteni kell. Emiatt lehet értelme végig lockolni, hogy a másodiknak jövő már az új Etag-összehasonlítást csinálja (spórolsz a wrinyóírással), különben ugyanazt az adatot fogják ketten beírni.
De úgy tűnik, neked a sohanapja lesz, mikor változtatni kell rajta.
28

Azért nem olyan jó az elejére

inf3rno · 2013. Szep. 30. (H), 03.43
Azért nem olyan jó az elejére tenni, mert akkor a régi adat megy el az új etaggel ütközéskor, és így egy későbbi get-kor sem fogja a böngésző frissíteni a cache-t az új adatra. Ezzel szemben ha a végére teszed az etag fájl írását, akkor ütközéskor az új adat fog elmenni a régi etaggel, ami teljesen jó. Sőt még az sem okoz problémát, ha egy későbbi kéréskor lerántja ugyanazt a szerverről, mert ritka az ilyen ütközés, és egy-egy ütköző kérést újra kiszolgálni nem egy nagy költség. Ha végig lock van, az sem nyújt többet semmiben sem ennél, csak szűk keresztmetszetet csinál. Szóval szerintem így fogom megoldani a kérdést. Automatizálni meg rest esetében nagyon könnyű, megnézem a request method-ot, aztán ha get, akkor összehasonlítom az etag-eket a cache-elés miatt, ha meg nem get, akkor meg frissítem az etag-et a végrehajtás után.
11

Nem támogatja maga a szerver

MadBence · 2013. Szep. 27. (P), 19.35
Nem támogatja maga a szerver az ETag-et? És akkor nem neked kellene vele foglalkoznod.

Szerk: ahogy látom neked a dinamikus adatokhoz kellene ETag, ezt sajnos neked kell megoldanod, ha az alkalmazás valami egyedi megoldás...
13

Ha az adatot nem kell több

tgr · 2013. Szep. 28. (Szo), 10.04
Ha az adatot nem kell több gép között megosztani, akkor APC user cache a leggyorsabb megoldás (ez lényegében osztott memóriában tárol). Ha annyira nagy forgalmú az oldal, hogy horizontálisan skálázni kell több vasra, akkor meg memcached.

Szerintetek nagy forgalmú oldalaknál [fájlt használni] problémát jelenthet?


Nincsenek mély ismereteim a fájl I/O-ról, de arra tippelnék, hogy amíg csak olvasásra nyitod meg, addig gond nélkül párhuzamosítható a hozzáférés, tehát ha az erőforrás ritkán változik, akkor egy közepes méretű oldalnál sem probléma a fájlhasználat. (Ha gyakran változik, akkor kilockolják egymást a szálaid, és egyszerre csak egy kérést tud a webszerver kiszolgálni, ami egy nagyobb forgalomra konfigurált szervernél úgy tizedére-huszadára veti vissza a kiszolgálási sebességet. Másrészt ha gyakran változik, akkor minek az ETag?)
15

A gyakran változást nem

inf3rno · 2013. Szep. 28. (Szo), 13.38
A gyakran változást nem igazán tudom felmérni, egy ügyviteli rendszerről van szó egy 100 fős cégnél, napi szinten csak az ügyvezető használná a rendszert, a többiek inkább havi szinten egyszer kétszer... Szóval azon dilemmázok, hogy sebességben ez hoz e annyit, hogy megéri implementálni, vagy tök értelmetlen. Tesztek nélkül maximum mások tapasztalatára tudok támaszkodni.
17

Itt a lényeg!

Pepita · 2013. Szep. 28. (Szo), 14.05
napi szinten csak az ügyvezető használná a rendszert, a többiek inkább havi szinten egyszer kétszer

Ne foglalkozz semmivel: csináld fájlban nyugodtan. Eszméletlen kicsi az esélye, hogy egyszerre akarjanak írni, ha mégis: a második vár egy kicsit. De ha a klienstől függ az állapot (kvázi a kliens állapota), akkor nem eleve külön fájlban van minden kliens?

I/O: olvasás szerintem elég gyors, beolvasás után érdemes helyből zárni is a fájlt. Írásnál meg ahogy tgr is mondta: megvárják egymást. Ilyen ritka látogatottságnál erre kb. 0 esélyed van. :)
18

A kliens állapotát kifejtem

inf3rno · 2013. Szep. 28. (Szo), 14.33
A kliens állapotát kifejtem egy kicsit jobban. Ez az etag azt jelenti, hogy a böngésző küld egy if modified since header-t, amiben benne van az előző dátum, vagy etag, amikor a legutóbb frissítette valamelyik oldalt. A szerveren én megnézem, hogy ahhoz az oldalhoz mi a legrégebbi módosítás dátuma, vagy mi a legrégebbi etag, és az alapján vagy küldök egy not modified header-t, vagy visszaküldöm a tartalmat egy új etaggel. Ezért írtam, hogy a kliens állapota, mert a böngésző tárolja helyben az információt, a kliens meg nálam a böngészőben fut, full javascript, csak adatot ránt le a szerverről rest-en keresztül. A projektbe nem fér bele, hogy aloldal meg munkamenet szintű cache-t csináljak, az viszont belefér, hogy csinálok egy közös etag-et az összes tartalomnak, és ha frissül, akkor ezt változtatom. Így végülis van cache, és ritkán változó tartalomnál nem jelent szűk keresztmetszetet a dolog. Azt hiszem a kérdés megválaszolásra került, mármint úgy néz ki, hogy lesz egy ilyen alap cache, mert mindenki azt írta, hogy nem jelent szűk keresztmetszetet az aktuális etag fájlba írása egy ekkora forgalmú oldalnál.
19

Köszi,

Pepita · 2013. Szep. 28. (Szo), 15.15
így már pontosan értem a feladatot (utólag). :)
Simán írhatod egy fájlba.
32

Egy elgondolkoztató cikk

tgr · 2013. Okt. 3. (Cs), 23.45
Egy elgondolkoztató cikk arról, hogy (a szerző szerint) mennyivel gyorsabb fájlokat használni, mint azt általában gondolják az emberek: More – The file system is slow

(Persze itt nincsenek párhuzamos lekérdezések, meg talán append módban nyitott fájloknál nem is lockol az írás, de azért érdekes.)
33

Az én esetemben sem muszáj

inf3rno · 2013. Okt. 4. (P), 00.30
Az én esetemben sem muszáj lockolni a teljes kérés idejére. Ha megfelelő helyre teszem az írást a kódban, akkor nagy bajt nem tud okozni... A fájlrendszer valóban nem lassú...