Un livello di cache è uno strato di memorizzazione aggiuntivo implementato tra il client e lo spazio di memorizzazione standard. È progettato per velocizzare l'accesso ai pool memorizzati su dischi rigidi lenti e ai pool con codice di cancellazione.
Di norma la suddivisione in livelli di cache prevede la creazione di un pool di dispositivi di memorizzazione relativamente veloci/costosi (ad esempio, le unità SSD) configurati in modo che fungano da livello di cache e un pool di supporto di dispositivi più lenti ed economici configurati per essere utilizzati come livello di memorizzazione.
Nella suddivisione in livelli di cache vengono riconosciuti due tipi di pool: un pool di cache e un pool di memorizzazione.
Per informazioni generali sui pool, vedere Capitolo 7, Gestione di pool di memorizzazione.
Pool replicato standard in cui vengono memorizzate diverse copie di un oggetto nel cluster di memorizzazione Ceph o pool con codice di cancellazione (vedere Capitolo 9, Pool con codice di cancellazione).
Talvolta il pool di memorizzazione è denominato spazio di memorizzazione "di supporto" o "offline sicura".
Pool replicato standard memorizzato in un dispositivo di memorizzazione relativamente piccolo ma veloce, con set di regole proprio in una mappa CRUSH.
Il pool di cache è denominato anche spazio di memorizzazione "ad accesso frequente".
Con la suddivisione in livelli di cache è possibile che le prestazioni vengano compromesse per workload specifici. Nei seguenti punti sono illustrati alcuni aspetti da considerare:
Dipendenza dal workload: il miglioramento delle prestazioni di una cache dipende dal workload. Poiché lo spostamento di oggetti dentro e fuori la cache comporta dei costi, può essere più efficace quando la maggior parte delle richieste toccano un numero ridotto di oggetti. Il pool di cache deve essere sufficientemente grande per acquisire il working set per il workload in modo da evitare di andare in thrashing.
Difficoltà nel benchmark: la maggior parte dei benchmark delle prestazioni potrebbero indicare rallentamenti con la suddivisione in livelli di cache. Il motivo di tali rallentamenti è dovuto a richieste di set di oggetti di grandi dimensioni per i quali la cache impiega molto tempo per "riscaldarsi".
Possibili prestazioni lente: per i workload inadatti alla suddivisione in livelli di cache, spesso le prestazioni sono più lente rispetto a un pool replicato normale in cui non è abilitata la suddivisione in livelli di cache.
Enumerazione di oggetti
librados: se l'applicazione utilizza direttamente librados
e fa affidamento all'enumerazione di oggetti, è possibile che la suddivisione in livelli di cache non funzioni come previsto (ciò non costituisce un problema per Object Gateway, RBD o CephFS).
La suddivisione in livelli di cache va considerata nei seguenti casi:
È necessario accedere a pool con codice di cancellazione tramite RADOS Block Device (RBD, dispositivo di blocco RADOS).
È necessario accedere a pool con codice di cancellazione iSCSI in quanto vengono ereditate le limitazioni di RBD. Per ulteriori informazioni su iSCSI, fare riferimento a Capitolo 12, Ceph iSCSI Gateway.
Si dispone di un numero limitato di spazio di memorizzazione a prestazioni elevate e una grande quantità di spazio di memorizzazione con basse prestazioni ed è necessario accedere più velocemente ai dati memorizzati.
L'agente di suddivisione in livelli di cache gestisce la migrazione dei dati tra il livello di cache e il livello di memorizzazione di supporto. Gli amministratori possono configurare la modalità di esecuzione di tale migrazione. Gli scenari principali sono due:
Nella modalità Write-back, i client Ceph scrivono i dati nel livello di cache e ricevono un messaggio ACK dal livello di cache. In tempo, viene eseguita la migrazione dei dati scritti nel livello di cache al livello di memorizzazione e i dati vengono svuotati dal livello di cache. Concettualmente, il livello di cache è sovrapposto "di fronte" al livello di memorizzazione di supporto. Quando in un client Ceph sono necessari dati che risiedono nel livello di memorizzazione, l'agente di suddivisione in livelli di memorizzazione esegue la migrazione dei dati al livello di cache in lettura, che vengono quindi inviati al client Ceph. In seguito, il client Ceph può eseguire I/O mediante l'uso del livello di cache fino a quando i dati diventano inattivi. Questo è ideale per dati mutabili, come la modifica di foto o video o per i dati transazionali.
Nella modalità di sola lettura, i dati vengono scritti dai client Ceph direttamente nel livello di supporto. In fase di lettura, gli oggetti richiesti vengono copiati da Ceph dal livello di supporto in quello di cache. Gli oggetti inattivi vengono rimossi dal livello di cache in base alla policy definita. Questo approccio è ideale per i dati immutabili, come la presentazione di immagini o video nei social network, i dati DNA o le immagini a raggi X, perché la lettura dei dati da un pool di cache che potrebbe contenere dati obsoleti è poco coerente. Non utilizzare la modalità di sola lettura per i dati mutabili.
I parametri set di accessi consentono di ottimizzare i pool di cache. Di norma, in Ceph i set di accessi sono filtri di Bloom e rappresentano un modo efficiente per la memoria di tenere traccia degli oggetti già presenti nel pool di cache.
Il set di accessi una matrice di bit utilizzata per memorizzare il risultato di un set di funzioni hash applicate sui nomi degli oggetti. Inizialmente tutti i bit sono impostati su 0
. Quando si aggiunge un oggetto al set di accessi, il rispettivo nome viene sottoposto all'hashing e il risultato viene mappato a posizioni diverse nel set di accessi, dove il valore del bit viene impostato quindi su 1
.
Per verificare l'esistenza di un oggetto nella cache, il nome oggetto viene sottoposto di nuovo all'hashing. Se un bit corrisponde a 0
, l'oggetto non è sicuramente nella cache e deve essere recuperato dallo spazio di memorizzazione offline sicura.
È possibile che i risultati di oggetti diversi vengano memorizzati nella stessa ubicazione del set di accessi. Per caso, tutti i bit possono corrispondere a 1
senza che l'oggetto sia presente nella cache. Pertanto, i set di accessi in cui viene utilizzato un filtro di Bloom possono solo indicare se un oggetto è decisamente nella cache oppure no e se deve essere recuperato dallo spazio di memorizzazione offline sicura.
Un pool di cache può presentare più set di accessi che nel tempo tengono traccia dell'accesso ai file. Con l'impostazione hit_set_count
si definisce il numero di set di accessi che vengono utilizzati e con hit_set_period
si definisce per quanto tempo viene utilizzato ciascun set di accessi. Al termine del periodo si utilizza il set di accessi successivo. Se il numero di set di accessi è esaurito, si libera la memoria del set di accessi più datato e viene creato un nuovo set di accessi. I valori di hit_set_count
e hit_set_period
moltiplicati l'uno per l'altro definiscono il lasso di tempo complessivo in cui è stato monitorato l'accesso agli oggetti.
Rispetto al numero di oggetti sottoposti ad hashing, un set di accessi basato sul filtro di Bloom è molto efficiente per la memoria. Per ridurre a sotto l'1% la probabilità di falsi positivi, sono necessari meno di 10 bit. È possibile definire la probabilità di falsi positivi con hit_set_fpp
. In base al numero di oggetti in un gruppo di posizionamento e alla probabilità di falsi positivi, Ceph calcola automaticamente le dimensioni del set di accessi.
È possibile limitare lo spazio di memorizzazione richiesto nel pool di cache con min_write_recency_for_promote
e min_read_recency_for_promote
. Se il valore è impostato a 0
, tutti gli oggetti vengono promossi al pool di cache non appena vengono letti o scritti fino a quando non vengono rimossi tutti. Qualsiasi valore maggiore di 0
definisce il numero di set di accessi in ordine di età in cui è stata eseguita la ricerca dell'oggetto. Se l'oggetto risulta presente in un set di accessi, verrà promosso al pool di cache.
Se sono disponibili uno spazio di memorizzazione grande e solo una piccola quantità di RAM, tutti gli oggetti possono essere promossi al pool di cache non appena vi si esegue l'accesso. Il set di accessi viene mantenuto piccolo. Di seguito è riportato un set di valori di configurazione di esempio:
hit_set_count = 1 hit_set_period = 3600 hit_set_fpp = 0.05 min_write_recency_for_promote = 0 min_read_recency_for_promote = 0
Se sono disponibili uno spazio di memorizzazione piccolo, ma una grande quantità di memoria paragonabile, è possibile configurare il livello di cache in modo che venga promosso al pool di cache un numero limitato di oggetti. Per un totale di 48 ore, il monitoraggio viene fornito da dodici set di accessi, ciascuno dei quali viene utilizzato per un periodo di 14.400 secondi. Se è stato eseguito l'accesso a un oggetto nelle ultime 8 ore, tale oggetto viene promosso al pool di cache. Il set di valori di configurazione di esempio è quindi il seguente:
hit_set_count = 12 hit_set_period = 14400 hit_set_fpp = 0.01 min_write_recency_for_promote = 2 min_read_recency_for_promote = 2
In questa sezione è illustrato come configurare un livello di cache SSD veloce (spazio di memorizzazione ad accesso frequente) di fronte a un disco rigido standard (spazio di memorizzazione offline sicura).
L'esempio seguente è solo a fine illustrativo ed è riportata una configurazione con una radice e una regola per la parte SSD che risiede in un singolo nodo Ceph.
Nell'ambiente di produzione, di norma nelle configurazioni del cluster sono incluse più voci relative a radice e regola per lo spazio di memorizzazione ad accesso frequente, nonché nodi misti, con entrambi i dischi SSD e SATA.
Preparare un computer host con unità veloci, come gli SSD. Questo nodo cluster fungerà da livello di cache veloce.
Trasformare il computer in un nodo Ceph tramite DeepSea. Installare il software e configurare il computer host come descritto nella Sezione 1.1, «Aggiunta di nuovi nodi cluster». Presupporre che il nome del nodo sia node-4. Tale nodo deve contenere 4 dischi OSD.
Nella mappa CRUSH si potrebbe ottenere una voce come quella seguente:
[...] host node-4 { id -5 # do not change unnecessarily # weight 0.012 alg straw hash 0 # rjenkins1 item osd.6 weight 0.003 item osd.7 weight 0.003 item osd.8 weight 0.003 item osd.9 weight 0.003 } [...]
Modificare la mappa CRUSH per il pool di memorizzazione ad accesso frequente mappato agli ODS supportati dalle unità SSD veloci. Definire una seconda gerarchia con un nodo radice per gli SSD (ad esempio "root ssd"). Modificare inoltre il peso e una regola CRUSH per gli SSD. Per ulteriori informazioni sulla mappa CRUSH, vedere http://docs.ceph.com/docs/master/rados/operations/crush-map/ (in lingua inglese).
Modificare direttamente la mappa CRUSH con gli strumenti a riga di comando, come getcrushmap
e crushtool
:
Recuperare l'attuale mappa e salvarla come c.map
:
cephadm >
sudo ceph osd getcrushmap -o c.map
Decompilare c.map
e salvarla come c.txt
:
cephadm >
crushtool -d c.map -o c.txt
Modificare c.txt
:
[...] host node-4 { id -5 # do not change unnecessarily # weight 4.000 alg straw hash 0 # rjenkins1 item osd.6 weight 1.000 item osd.7 weight 1.000 item osd.8 weight 1.000 item osd.9 weight 1.000 } root ssd { # newly added root for the SSD hot-storage id -6 alg straw hash 0 item node-4 weight 4.00 } rule ssd { ruleset 4 type replicated min_size 0 max_size 4 step take ssd step chooseleaf firstn 0 type host step emit } [...]
Compilare il file c.txt
modificato e salvarlo come ssd.map
:
cephadm >
crushtool -c c.txt -o ssd.map
Infine, installare ssd.map
come nuova mappa CRUSH:
cephadm >
sudo ceph osd setcrushmap -i ssd.map
Creare un pool di memorizzazione ad accesso frequente da utilizzare per la suddivisione in livelli di cache. A tal fine, utilizzare la nuova regola "ssd":
cephadm >
sudo ceph osd pool create hot-storage 100 100 replicated ssd
Creare il pool di memorizzazione offline sicura utilizzando la regola di default "replicated_ruleset":
cephadm >
sudo ceph osd pool create cold-storage 100 100 replicated replicated_ruleset
Quindi, la configurazione di un livello di cache comporta l'associazione di un pool di memorizzazione di supporto con un pool di cache, in questo caso, spazio di memorizzazione offline sicura (= pool di memorizzazione) con spazio di memorizzazione ad accesso frequente (= pool di cache):
cephadm >
sudo ceph osd tier add cold-storage hot-storage
Per impostare la modalità di cache a "writeback", eseguire quanto riportato di seguito:
cephadm >
sudo ceph osd tier cache-mode hot-storage writeback
Per ulteriori informazioni sulle modalità di cache, vedere Sezione 10.4, «Modalità cache».
I livelli di cache writeback si sovrappongono al livello di memorizzazione di supporto, pertanto è necessario un passaggio aggiuntivo: indirizzare tutto il traffico del client dal pool di memorizzazione al pool di cache. Per indirizzare il traffico del client direttamente al pool di cache, eseguire quanto riportato di seguito, ad esempio:
cephadm >
sudo ceph osd tier set-overlay cold-storage hot-storage
Per configurare i livelli di cache sono disponibili diverse opzioni. Utilizzare la seguente sintassi:
cephadm >
sudo ceph osd pool set cachepool key value
Nei passaggi seguenti è illustrato come configurare un pool di cache con i valori forniti nella Sezione 10.5.2.2, «Pool di cache piccolo e memoria di grandi dimensioni»
Nei livelli di cache di produzione Ceph viene utilizzato un filtro di Bloom per hit_set_type
:
cephadm >
sudo ceph osd pool set cachepool hit_set_type bloom
Con hit_set_count
e hit_set_period
si definiscono la durata di copertura di ciascun set di accesso e quanti di questi memorizzare.
cephadm >
sudo ceph osd pool set cachepool hit_set_count 12cephadm >
sudo ceph osd pool set cachepool hit_set_period 14400cephadm >
sudo ceph osd pool set cachepool target_max_bytes 1000000000000
Un numero di hit_set_count
più grande comporta un maggior consumo di RAM da parte del processo ceph-osd
.
Con min_read_recency_for_promote
si definisce il numero set di accessi in cui verificare l'esistenza di un oggetto durante un'operazione di lettura. Il risultato della verifica viene utilizzato per decidere se promuovere l'oggetto in modo asincrono. Il rispettivo valore deve essere compreso tra 0 e hit_set_count
. Se impostato a 0, l'oggetto viene promosso sempre. Se impostato 1, viene verificato l'attuale set di accessi. Inoltre, se tale oggetto rientra nel set di accessi viene promosso. In caso contrario, ciò non avviene. Per gli altri valori, viene verificato il numero esatto di set di accessi all'archivio. L'oggetto viene promosso se viene trovato in uno dei set di accessi min_read_recency_for_promote
più recenti.
È possibile impostare un parametro simile, min_write_recency_for_promote
, per l'operazione di scrittura:
cephadm >
sudo ceph osd pool set cachepool min_read_recency_for_promote 2cephadm >
sudo ceph osd pool set cachepool min_write_recency_for_promote 2
Più lungo è il periodo, più elevati sono i valori di min_read_recency_for_promote
e min_write_recency_for_promote
e maggior quantità di RAM viene utilizzata dal daemon ceph-osd
. In particolare, quando l'agente è attivo per svuotare o rimuovere oggetti dalla cache, tutti i set di accessi hit_set_count
vengono caricati nella RAM.
L'agente di suddivisione in livelli di cache svolge due funzioni principali:
L'agente identifica gli oggetti modificati e li inoltra al pool di memorizzazione per l'archiviazione a lungo termine.
L'agente identifica gli oggetti non modificati e rimuove dalla cache quelli utilizzati più di recente.
L'agente di suddivisione in livelli di cache è in grado di svuotare o rimuovere oggetti in base al numero totale di byte o al numero totale di oggetti. Per specificare un numero massimo di byte, eseguire quanto riportato di seguito:
cephadm >
sudo ceph osd pool set cachepool target_max_bytes num_of_bytes
Per specificare un numero massimo di oggetti, eseguire quanto riportato di seguito:
cephadm >
sudo ceph osd pool set cachepool target_max_objects num_of_objects
Ceph non è in grado di determinare automaticamente le dimensioni di un pool di cache, pertanto qui è richiesta la configurazione sulle dimensioni assolute. In caso contrario, lo svuotamento e la rimozione risulteranno impossibili. Se si specificano entrambi i limiti, l'agente di suddivisione in livelli di cache inizierà il processo di svuotamento o di rimozione quando viene attivata una delle due soglie.
Tutte le richieste del client verranno bloccate solo quando si raggiungono i valori indicati in target_max_bytes
o target_max_objects
.
L'agente di suddivisione in livelli di cache è in grado di svuotare o rimuovere oggetti relativi alle dimensioni del pool di cache (specificate da target_max_bytes
o target_max_objects
in Sezione 10.6.1.2.1, «Ridimensionamento assoluto»). Quando il pool di cache è costituito da una determinata percentuale di oggetti modificati, l'agente di suddivisione in livelli di cache li svuoterà nel pool di memorizzazione. Per impostare cache_target_dirty_ratio
, eseguire quanto riportato di seguito:
cephadm >
sudo ceph osd pool set cachepool cache_target_dirty_ratio 0.0...1.0
Ad esempio, se si imposta il valore a 0.4 avrà inizio lo svuotamento degli oggetti modificati quando questi raggiungono il 40% di capacità del pool di cache:
cephadm >
sudo ceph osd pool set hot-storage cache_target_dirty_ratio 0.4
Quando gli oggetti modificati raggiungono una determinata percentuale di capacità, svuotarli a una velocità più elevata. Utilizzare cache_target_dirty_high_ratio
:
cephadm >
sudo ceph osd pool set cachepool cache_target_dirty_high_ratio 0.0..1.0
Quando il pool di cache raggiunge una determinata percentuale della rispettiva capacità, l'agente di suddivisione in livelli di cache rimuoverà gli oggetti per mantenere libera la capacità. Per impostare cache_target_full_ratio
, eseguire quanto riportato di seguito:
cephadm >
sudo ceph osd pool set cachepool cache_target_full_ratio 0.0..1.0
È possibile specificare l'età minima di un oggetto modificato di recente prima che l'agente di suddivisione in livelli di cache lo svuoti nel pool di memorizzazione di supporto:
cephadm >
sudo ceph osd pool set cachepool cache_min_flush_age num_of_seconds
È possibile specificare l'età minima di un oggetto prima che questo venga rimosso dal livello di cache:
cephadm >
sudo ceph osd pool set cachepool cache_min_evict_age num_of_seconds
Nelle configurazioni dei livelli di cache è presente un filtro di Bloom denominato set di accessi. Mediante tale filtro è possibile verificare l'appartenenza di un oggetto a un set di oggetti a caldo o a freddo. Gli oggetti vengono aggiunti al set di accessi aggiungendo le registrazioni dell'orario ai rispettivi nomi.
Se i computer del cluster vengono posizionati in fusi orari diversi e le registrazioni dell'orario derivano dall'ora locale, è possibile che gli oggetti in un set di accessi presentino nomi fuorvianti costituiti da registrazioni dell'orario future o passate. Nel caso peggiore, è possibile che gli oggetti non siano affatto presenti nel set di accessi.
Per impedire che ciò si verifichi, in una configurazione del livello di cache appena creata use_gmt_hitset
è impostato per default a "1". In questo modo si forzano gli OSD a utilizzare le registrazioni dell'orario GMT (Greenwich Mean Time) quando si creano i nomi oggetto per il set di accessi.
Non modificare il valore di default "1" di use_gmt_hitset
. Se gli errori correlati a questa opzione non sono causati dalla configurazione del cluster, non modificarla mai manualmente. In caso contrario il comportamento del cluster potrebbe diventare imprevedibile.