2009-02-23 6 views
36

C'è un modo per dire a Linux che non dovrebbe scambiare la memoria di un particolare processo su disco?Posso dire a Linux di non scambiare la memoria di un particolare processo?

È un'app Java, quindi, idealmente, spero in un modo per farlo dalla riga di comando.

Sono consapevole che è possibile impostare lo swappiness globale su 0, ma è saggio?

+0

Unix era solito onorare il "sticky bit" se si eseguiva un "chmod + S" su un'app, ma non credo che funzioni di più. –

+1

Mi spiace, voglio dire "chmod + t", ma ho solo guardato e Linux ignora il bit appiccicoso. –

+0

http://blogs.msdn.com/b/oldnewthing/archive/2005/06/07/426294.aspx – Hello71

risposta

22

È possibile farlo tramite la chiamata di sistema mlockall(2) sotto Linux; questo funzionerà per l'intero processo, ma leggi l'argomento che devi passare.

Hai davvero bisogno di mettere tutto dentro il nucleo? Se si tratta di un'app java, si presumibilmente bloccherà l'intero JVM in-core. Non conosco un metodo da riga di comando per farlo, ma potresti scrivere un programma banale per chiamare fork, chiamare mlockall, quindi exec.

Si potrebbe anche verificare se una delle notifiche del modello di accesso in madvise(2) soddisfa le proprie esigenze. Avvisare il sottosistema VM su una migliore strategia di paging potrebbe funzionare meglio se è applicabile a te.

Nota che molto tempo fa ora in SunOS, c'era un meccanismo simile a madvise chiamato vadvise(2).

+0

@sanity hai provato questo? Come ha funzionato per te? Stavo pensando di fare qualcosa di simile. –

+6

["I blocchi di memoria non vengono ereditati da un figlio creato tramite fork (2) e vengono automaticamente rimossi (sbloccati) durante un execve (2) o quando il processo termina."] (Http://www.kernel.org/doc /man-pages/online/pages/man2/mlock.2.html) - l'approccio fork/mlock/exec non funzionerà – Mat

+0

@Mat sembra giusto ... OK ... che dire qualcosa come scrivere qualcosa da chiamare via JNI che chiama mlockall? Che inizia a sentirsi piuttosto hackish però ... –

2

È possibile farlo dalla famiglia di syscalls mlock. Non sono sicuro, tuttavia, se puoi farlo per un processo diverso.

+0

Tuttavia, farei attenzione alla quantità di memoria totale del sistema bloccata. Sospetto che potresti far cadere il sistema attraverso la cestinazione se non fossi attento. –

2

In qualità di super utente, è possibile "adattarlo" al livello di priorità più elevato -20 e sperare che sia sufficiente per evitare che venga scambiato. Di solito è. Numeri positivi priorità di schedulazione inferiore. Gli utenti normali non possono essere piacevoli verso l'alto (numeri negativi)

+3

a meno che non mi sbagli, questo influenzerà solo il tempo di CPU concesso al processo, non la sua tendenza all'uso della memoria principale. – intuited

+3

@intuited: Credo che voglia dire che il sottosistema VM valuterà anche il valore 'nice' per decidere l'importanza di un processo e non sostituirlo. Sembra plausibile; Non so se Linux lo faccia davvero, comunque. – sleske

+0

'ionice' potrebbe anche essere utile qui – fread2281

2

Tranne che in circostanze estremamente insolite, fare questa domanda significa che stai facendo male (tm).

Seriamente, se Linux vuole scambiare e stai cercando di mantenere il tuo processo in memoria, stai mettendo una richiesta irragionevole sul sistema operativo. Se la tua app è così importante 1) acquista più memoria, 2) rimuovi altre app/demoni dalla macchina, o dedica una macchina alla tua app, e/o 3) investi in un sottosistema di dischi veramente veloce. Questi passaggi sono ragionevoli per un'app importante. Se non puoi giustificarli, allora probabilmente non puoi giustificare il cablaggio della memoria e morire di fame altri processi.

+26

Se fosse correlato alla crittografia, è del tutto ragionevole voler rimanere in memoria. gnome-keyring, ad esempio, richiede un bel po 'di passaggi per mantenere importanti bit di se stesso al di fuori dello swap. (Oltre a questo, osservazioni ragionevoli.) –

+1

Buon punto, Paul. Sento che questo si qualifica come una circostanza insolita. – dwc

+2

È piuttosto usuale nel settore bancario e delle carte di pagamento con tutti i requisiti di crittografia più rigorosi. –

1

Perché vuoi farlo?
Se stai cercando di aumentare le prestazioni di questa app, probabilmente sei sulla strada sbagliata. Il sistema operativo sostituirà un processo per aumentare la memoria per la cache del disco - anche se c'è una RAM libera, il kernel lo sa meglio (actauly i ragazzi che hanno scritto lo scheduler lo sanno meglio).
Se si dispone di un processo che richiede reattività (viene sostituito quando non viene utilizzato e ne è necessario il riavvio rapido), è utile eseguire il comando con una priorità elevata, mlock o utilizzare un kernel in tempo reale.

2

Esistono una classe di applicazioni in cui non si vuole loro di scambiare . Una di queste classi è un database. I database useranno la memoria come cache e buffer per le loro aree disco, e non ha assolutamente senso che questi vengano mai scambiati. La memoria particolare può contenere alcuni dati rilevanti che non sono necessari per una settimana fino al giorno in cui un cliente lo richiede.Senza il caching/swapping, il database troverebbe semplicemente il record relativo sul disco, che sarebbe abbastanza veloce; ma con lo scambio, il servizio potrebbe richiedere molto tempo per rispondere.

mysqld include il codice per utilizzare la chiamata sistema/sistema memlock. Su Linux, dal momento che almeno 2.6.9, questa chiamata di sistema funzionerà per processi non root che hanno la capacità CAP_IPC_LOCK[1]. Quando si utilizza memlock(), il processo deve comunque funzionare entro i limiti del limite LimitMEMLOCK. [2]. Una delle (poche) cose positive su systemd consiste nel fatto che è possibile concedere il processo mysqld a queste funzionalità, senza richiedere un programma speciale. Se è possibile impostare i rlimits come ci si aspetterebbe con ulimit. Ecco un file override per mysqld che fa i passi necessari, tra cui un paio di altri che potrebbe essere necessario per un processo come un database:

[Service] 
# Prevent mysql from swapping 
CapabilityBoundingSet=CAP_IPC_LOCK 

# Let mysqld lock all memory to core (don't swap) 
LimitMEMLOCK=-1 

# do not kills this process if low on memory 
OOMScoreAdjust=-900 

# Use higher io scheduling 
IOSchedulingClass=realtime  

Type=simple  
ExecStart= 
ExecStart=/usr/sbin/mysqld --memlock $MYSQLD_OPTS 

Nota La comunità mysql di serie attualmente fornito con Type=forking e aggiunge --daemonize nell'opzione per il servizio sulla linea ExecStart. Questo è intrinsecamente meno stabile del metodo sopra.

UPDATE Non sono soddisfatto al 100% di questa soluzione. Dopo diversi giorni di runtime, ho notato che il processo aveva ancora enormi quantità di scambio! Esaminando /proc/XXXX/smaps, prendo nota quanto segue:

  • Il più grande contributore di scambio è da un segmento di stack! 437 MB e fluttuante. Ciò presenta evidenti problemi di prestazioni. Indica anche perdita di memoria basata sullo stack.
  • Ci sono zero Pagine bloccate. Ciò indica che l'opzione memlock in MySQL (o Linux) è danneggiata. In questo caso, non importa molto perché MySQL non può memlock stack.
Problemi correlati