// data & ai · giornale tecnico MILANO ● LIVE 00:00:00

Huge pages in ClickHouse Managed Postgres: come tenere piatte le page table

ClickHouse spiega come configura le huge pages nel suo Managed Postgres per evitare che shared_buffers diventi una tassa di page table per connessione. Con benchmark su hardware reale.

Perché le huge pages contano per Postgres? Il sistema operativo distribuisce memoria in pagine da 4KB e la CPU tiene una piccola cache di traduzioni virtuale-fisico, il TLB. Una huge page è la stessa memoria in unità molto più grandi (2MB o 1GB), così una singola voce di page table copre fino a 262.144 volte più spazio. In un post di ingegneria, ClickHouse spiega come configura le huge pages nel suo Managed Postgres e mostra l’effetto su hardware reale.

Il punto è che Postgres è particolarmente sensibile alla dimensione delle pagine. La sua cache, shared_buffers, è un unico segmento di shared memory e ogni backend la mappa attraverso le proprie page table. Con pagine da 4KB, una cache da 100GB costa a ogni backend circa 200MB di voci di page table: 100 connessioni bruciano 20GB di RAM solo in page table, mentre con huge pages da 2MB si scende a decine di MB. Inoltre il TLB copre solo pochi MB della cache a 4KB, mentre ogni pagina da 2MB dà uno slot con 512 volte la portata, mantenendo il working set caldo nel TLB.

Tre accorgimenti per farlo tenere in produzione

ClickHouse indica tre pezzi. Riservare le pagine presto: un quarto della memoria della macchina è riservato come huge pages (rispecchiando la regola shared_buffers = 25% della RAM), prima ancora che Postgres parta e dopo aver svuotato le cache e compattato la memoria, perché le huge pages si riservano in modo affidabile solo con memoria non frammentata. Rifiutare di partire senza: Postgres è fissato a huge_pages = 'on', così o ottiene le pagine o non parte; il default 'try' ripiega silenziosamente su 4KB senza lasciare traccia nei log. Dimensionare shared_buffers alla pagina: il segmento di shared memory è più grande di shared_buffers (include buffer descriptor, WAL buffer, lock table), quindi si misura l’overhead reale con postgres -C shared_memory_size e lo si sottrae, arrotondando a blocchi da 8KB.

La prova sull’hardware

Su una singola EC2 r7i.4xlarge (16 vCPU, 128GB), Postgres 16 con shared_buffers = 32GB e una tabella pgbench da 15,6GB caricata in cache, ClickHouse ha campionato il contatore PageTables a 25, 50, 100 e 200 connessioni. Con pagine da 4KB le page table crescono di 31,1MB per connessione e raggiungono 6,1GB a 200 connessioni; con huge pages da 2MB le stesse 200 connessioni costano 111MB, circa 0,5MB per connessione. Anche il throughput si muove, meno drasticamente: pgbench select-only a 100 client ha registrato 373.083 TPS su 4KB contro 418.087 TPS su 2MB, una differenza del 12% sulla stessa macchina.

  • Le huge pages trasformano shared_buffers da una tassa di page table per connessione in una cache piatta e TLB-friendly.
  • Il cambiamento strutturale è nella memoria: page table che scalano linearmente con le connessioni contro page table che restano piatte.
  • Riservare il pool prima della frammentazione e usare huge_pages = 'on' fa fallire al boot una configurazione rotta, invece di degradare in silenzio.

Fonte: How we configure huge pages in ClickHouse Managed Postgres — https://clickhouse.com/blog/huge-pages-clickhouse-managed-postgres

Condividi X Facebook LinkedIn WhatsApp Email

// scritto da

Fernando

Hai qualcosa da aggiungere? Unisciti alla discussione.

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Altri dell'autore

dalla stessa firma