Wanneer moet ik /dev/shm/ gebruiken en wanneer /tmp/?
Wanneer moet ik /dev/shm/
gebruiken en wanneer /tmp/
? Kan ik er altijd op vertrouwen dat ze er allebei zijn op Unices?
Wanneer moet ik /dev/shm/
gebruiken en wanneer /tmp/
? Kan ik er altijd op vertrouwen dat ze er allebei zijn op Unices?
In aflopende volgorde van waarschijnlijkheid:
┌───────────┬──────────────┬────────────────┐
│ /dev/shm │ always tmpfs │ Linux specific │
├───────────┼──────────────┼────────────────┤
│ /tmp │ can be tmpfs │ FHS 1.0 │
├───────────┼──────────────┼────────────────┤
│ /var/tmp │ never tmpfs │ FHS 1.0 │
└───────────┴──────────────┴────────────────┘
Aangezien je vraagt naar een Linux specifiek tmpfs mountpoint versus een overdraagbaar gedefinieerde directory die tmpfs kan zijn (afhankelijk van je sysadmin en wat standaard is voor je distro), heeft je vraag twee aspecten, die in andere antwoorden anders zijn benadrukt:
Conservatieve editie (mengsel van conventies van FHS en algemeen gebruik):
tmpfs
. /tmp
voor grote gegevens die misschien niet gemakkelijk in ram passen. /var/tmp
voor gegevens die bewaard moeten blijven na een herstart (zoals een cache). /var/tmp
als een neveneffect van het aanroepen van /dev/shm
. Het beoogde publiek zijn begrensde buffers die eindeloos overschreven worden. Dus dit is voor langlevende bestanden waarvan de inhoud vluchtig is en niet verschrikkelijk groot. shm_open()
programma respecteert de mktemp
omgevingsvariabele. Pragmatische editie:
Gebruik TMPDIR
als het belangrijk is om tmpfs te gebruiken, /dev/shm
als het belangrijk is om dat niet te doen, anders /var/tmp
.
/tmp
is een no-op op tmpfs. Deze syscall is de grootste vijand van (IO) prestatie (en levensduur van flash, als je daar om geeft), maar als je tmpfs (of eatmydata ) gebruikt om fsync te verslaan, dan doe jij (of een andere ontwikkelaar in de keten) iets verkeerd. Het betekent dat de transacties naar het opslagapparaat onnodig fijnkorrelig zijn voor uw doel - u bent duidelijk bereid om sommige savepoints over te slaan voor prestaties, omdat u nu tot het uiterste bent gegaan om ze allemaal te saboteren - zelden het beste compromis. Het is ook hier in transactieprestatieland waar enkele van de grootste voordelen van een SSD te vinden zijn - elke fatsoenlijke SSD presteert ongeëvenaard in vergelijking met wat een draaiende schijf aankan (7200 rpm = 120 Hz, als er verder niets mee wordt gedaan), om nog maar te zwijgen van flashgeheugenkaarten, die sterk variëren op dit punt (niet in het minst omdat het een afweging is met sequentiële prestaties, waar ze op worden beoordeeld, bijv. de SD-kaartklasse). Dus pas op, ontwikkelaars met razendsnelle SSD’s, om uw gebruikers niet te dwingen in deze use case!
Wil je een belachelijk verhaal horen? Mijn eerste fsync
les: ik had een baan waarbij ik routinematig een stel Sqlite-databases (die als testcases werden bewaard) moest “upgraden” naar een steeds veranderend, actueel formaat. Het “upgrade” framework draaide een aantal scripts, die elk minstens één transactie maakten, om een database te upgraden. Natuurlijk, upgradete ik mijn databases parallel (8 in parallel, daar ik gezegend was met een machtige 8 core CPU). Maar zoals ik ontdekte, was er geen enkele parallellisatie-snelheid (eerder een lichte hit) omdat het proces volledig IO gebonden was. Hilarisch genoeg was het 100 keer sneller om het upgrade framework te verpakken in een script dat elke database naar fsync
kopieerde, het daar upgradete, en het terug naar schijf kopieerde (nog steeds met 8 in parallel). Als bonus, was de PC ook bruikbaar tijdens het upgraden van de databases.
Het juiste gebruik van tmpfs is om onnodig schrijven van vluchtige gegevens te vermijden. Effectief uitschakelen van writeback, zoals het op oneindig zetten van /dev/shm
op een regulier bestandssysteem.
Dit heeft heel weinig te maken met prestaties, en het falen hiervan is een veel kleiner probleem dan het misbruiken van fsync: De terugschrijftime-out bepaalt hoe lui de schijfinhoud wordt bijgewerkt na de inhoud van de pagecache, en de standaardinstelling van 5 seconden is lang voor een computer - een applicatie kan een bestand zo vaak overschrijven als hij wil, in de pagecache, maar de inhoud op schijf wordt maar ongeveer eens in de 5 seconden bijgewerkt. Tenzij de applicatie het forceert met fsync, dat is. Bedenk hoeveel keer een applicatie een klein bestand kan uitvoeren in deze tijd, en je ziet waarom het fsyncen van elk bestand een veel groter probleem zou zijn.
/proc/sys/vm/dirty_writeback_centisecs
natuurlijk. Bewaren van koude gegevens. Je zou in de verleiding kunnen komen om te denken dat het serveren van bestanden vanuit swap net zo efficiënt is als een normaal bestandssysteem, maar er zijn een paar redenen waarom dat niet zo is:
Oké, hier is de realiteit.
Zowel tmpfs als een normaal bestandssysteem zijn een geheugen cache over schijf.
De tmpfs gebruikt geheugen en swapspace als opslag, een bestandssysteem gebruikt een specifiek deel van de schijf, geen van beide is gelimiteerd in de grootte van het bestandssysteem, het is heel goed mogelijk om een 200GB tmpfs te hebben op een machine met minder dan een GB ram als je genoeg swapspace hebt.
Het verschil zit hem in wanneer gegevens naar de schijf worden geschreven. Bij een tmpfs wordt de data ALLEEN geschreven als het geheugen te vol wordt of als de data waarschijnlijk niet snel gebruikt zal worden. De meeste normale Linux bestandssystemen zijn echter ontworpen om altijd een min of meer consistente set gegevens op de schijf te hebben, zodat als de gebruiker de stekker eruit trekt, hij niet alles kwijt is.
Persoonlijk ben ik gewend aan besturingssystemen die niet crashen en UPS systemen (b.v.: laptop batterijen), dus ik denk dat de ext2/3 bestandssystemen te paranoïde zijn met hun 5-10 seconden checkpoint interval. Het ext4 bestandssysteem is beter met een 10 minuten checkpoint, maar het behandelt gebruikersgegevens als tweederangs en beschermt ze niet. (ext3 is hetzelfde, maar je merkt het niet vanwege het 5 seconden checkpoint)
Dit frequente checkpointing betekent dat er voortdurend onnodige gegevens naar schijf worden geschreven, zelfs voor /tmp.
Dus het resultaat is dat je swapruimte moet maken die zo groot is als je /tmp moet zijn (zelfs als je een swapfile moet maken) en die ruimte moet gebruiken om een tmpfs van de vereiste grootte op /tmp te mounten.
Gebruik NOOIT /dev/shm.
Tenzij je het gebruikt voor hele kleine (waarschijnlijk mmap’d) IPC bestanden en je zeker weet dat het bestaat (het is geen standaard) en de machine meer dan genoeg geheugen + swap beschikbaar heeft.
Gebruik /tmp/ voor tijdelijke bestanden. Gebruik /dev/shm/ als je gedeeld geheugen wilt (d.w.z. interprocess communicatie via bestanden).
Je kunt erop vertrouwen dat /tmp/ er is, maar /dev/shm/ is een relatief recent Linux ding.
Een ander moment waarop je /dev/shm zou moeten gebruiken (voor Linux 2.6 en hoger) is wanneer je een gegarandeerd tmpfs bestandssysteem nodig hebt omdat je niet weet of je kan schrijven naar schijf.
Een monitoring systeem dat ik ken moet tijdelijke bestanden wegschrijven terwijl het zijn rapport opbouwt voor indiening bij een centrale server. Het is in de praktijk veel waarschijnlijker dat iets het schrijven naar een bestandssysteem verhindert (ofwel geen schijfruimte meer, ofwel een onderliggende RAID-storing heeft het systeem in een hardwarematige alleen-lezen-modus geduwd), maar je zult nog steeds in staat zijn om mee te hinken om er een waarschuwing over te geven, dan wanneer iets al het beschikbare geheugen zo opslokt dat tmpfs onbruikbaar wordt (en de doos niet dood is). In dit soort gevallen zal een monitoring systeem er de voorkeur aan geven om naar RAM weg te schrijven om mogelijk een waarschuwing te kunnen sturen over een volle schijf of dode/dode hardware.
/dev/shm wordt gebruikt voor gedeeld virtueel geheugen systeemspecifieke device drivers en programma’s.
Als je een programma maakt dat een heap aan virtueel geheugen nodig heeft, dan moet dat gemapt worden naar virtueel geheugen. Dit geldt dubbel zo als je meerdere processen of threads nodig hebt om dat geheugen veilig te kunnen benaderen.
Het feit is dat het stuurprogramma een speciale versie van tmpfs gebruikt, betekent niet dat je het als een generieke tmpfs partitie moet gebruiken. In plaats daarvan moet u gewoon een andere tmpfs partitie aanmaken als u er een wilt voor uw tijdelijke map.
In PERL, met een minimum van 8GB op elke machine (die allemaal Linux Mint draaien), heb ik de goede gewoonte om DB_File-gebaseerde (datastructuur in een bestand) complexe algoritmes te doen met miljoenen reads en writes gebruikmakend van /dev/shm
In andere talen, niet overal gigether hebbend, om de starts en stops in netwerkoverdracht te vermijden (lokaal werken aan een bestand dat op een server staat in een client-server sfeer), gebruik ik een of ander batch bestand, kopieer ik het hele (300-900MB) bestand in een keer naar /dev/shm, voer het programma uit met uitvoer naar /dev/shm, schrijf de resultaten terug naar de server, en verwijder van /dev/shm
Natuurlijk, als ik minder RAM had, zou ik dit niet doen. Gewoonlijk leest het in-memory bestandssysteem van /dev/shm als een grootte die de helft is van uw beschikbare RAM. Het gewone gebruik van RAM is echter constant. Dus je zou dit echt niet kunnen doen op een apparaat met 2GB of minder. Om de parafrase om te zetten in hyperbool, er zit vaak van alles in RAM dat zelfs het systeem niet goed rapporteert.