Cassandra genererar gravstenar när du tar bort data. Under vissa omständigheter kan överflödiga gravstenar orsaka långa GC-pauser, latens, läsfel eller fel i högen. Denna artikel ger råd för hantering av gravstenar.
Innehållsförteckning
Vad är en gravsten?
i Cassandra rensas inte raderade data omedelbart från disken. Istället skriver Cassandra ett speciellt värde, känt som en gravsten, för att indikera att data har raderats. Tombstones förhindrar att raderade data returneras under läsningar och kommer så småningom att tillåta att data släpps via komprimering.
Tombstones är skrivningar – de går igenom den normala skrivvägen, tar plats på disken och använder sig av Cassandras konsistensmekanismer. Gravstenar kan förökas över klustret via tips och reparationer. Om ett kluster hanteras korrekt säkerställer detta att data förblir raderade även om en nod är nere när raderingen utfärdas.
gravstenar genereras av:
- ta bort satser
- ställa in TTLs
- infoga null-värden
- infoga data i delar av en samling.
vad är den normala livscykeln för gravstenar?
gravstenar skrivs med en tidsstämpel. Under ideala omständigheter kommer gravstenar (och deras tillhörande data) att släppas under kompaktioner efter en viss tid har gått.
följande tre kriterier måste uppfyllas för att gravstenar ska tas bort:
- gravstenarna skapades mer än gc_grace_seconds sedan.
- tabellen som innehåller gravstenen är inblandad i en komprimering.
- Alla sstables som kan innehålla relevanta data är inblandade i komprimeringen.
varje tabell har en inställning för gc_grace_seconds. Som standard är detta inställt på 864000, vilket motsvarar 10 dagar. Avsikten är att ge tid för klustret att uppnå konsistens via reparationer (och därmed förhindra uppståndelse av raderade data).
gravstenar kommer endast att släppas via en komprimering om alla sstables som kan innehålla relevanta data är inblandade i komprimeringen. Om mycket tid har gått mellan att skriva originaldata och utfärda raderingen blir det mindre troligt:
- Storleksvägd Komprimeringsstrategi kommer att komprimera sstables av liknande storlek tillsammans. Data tenderar att flytta till större sstables när det åldras, så gravstenen (i en ny, liten sstable) är osannolikt att komprimeras med data (i en gammal, stor sstable).
- planad Komprimeringsstrategi är uppdelad i många nivåer som komprimeras separat. Gravstenen kommer att skrivas in i nivå 0 och kommer effektivt att ’jaga’ data genom nivåerna – det borde så småningom komma ikapp.
- time-Window Compaction Strategy (eller Date-Tiered Compaction Strategy) kommer aldrig att komprimera gravstenen med data om de skrivs in i olika tidsfönster.
när orsakar gravstenar problem?
Diskanvändning
När data raderas kommer utrymmet inte att frigöras under åtminstone gc_grace-perioden som anges i tabellinställningarna. Detta kan orsaka problem om ett kluster snabbt fylls.
under vissa omständigheter kommer utrymmet aldrig att frigöras utan manuell ingrepp.
Läs prestanda
allvarliga prestandaproblem kan uppstå om läsningar stöter på ett stort antal gravstenar.
prestandaproblem är mest sannolikt att hända med följande typer av frågor:
- frågor som körs över alla partitioner i en tabell (”välj * från keyspace.tabell”)
- Range queries (”välj * från keyspace.tabell där värdet > x”, eller ”där värdet i (value1, value2,…)”
- alla frågor som bara kan köras med en ”Tillåt filtrering” – klausul.
dessa prestandaproblem uppstår på grund av beteendet hos gravstenar under läsningar. I en intervallfråga använder din Cassandra-drivrutin normalt personsökning, vilket gör att noder kan returnera ett begränsat antal svar åt gången. När cassandra-gravstenar är inblandade måste noden behålla gravstenarna som den har stött på i minnet och returnera dem till samordnaren, om en av de andra replikerna inte är medveten om att relevanta data har raderats. Gravstenarna kan inte sökas eftersom det är viktigt att returnera dem alla, så latens och minnesanvändning ökar proportionellt till antalet gravstenar som uppstått.
huruvida gravstenarna kommer att påträffas beror på hur data lagras och hämtas. Om Cassandra till exempel används för att lagra data i en kö (vilket inte rekommenderas) kan frågor stöta på tiotusentals gravstenar för att returnera några rader data.
hur kan jag diagnostisera gravstensrelaterade problem?
frågor som stöter på ett stort antal gravstenar kommer att dyka upp i loggarna. Som standard genererar en läsning som stöter på mer än tusen gravstenar en varning:
WARN org.Apache.Kassandra.dB.ReadCommand Läs 0 levande rader och 87051 tombstone celler för fråga välj * från exempel.tabell
som standard kommer att stöta på mer än 100.000 gravstenar orsaka frågan att misslyckas med en TombstoneOverwhelmingException.
för att verifiera om tombstone-läsningar orsakar prestandaproblem, kontrollera om läsningen korrelerar med en ökning av läslatens och GC-pausens varaktighet.
om det är uppenbart att gravstenar är problemen kan följande tekniker hjälpa till att begränsa problemets omfattning:
- antalet gravstenar som returneras i en viss fråga kan hittas genom att köra frågan i cqlsh med spårning aktiverad.
- statistik för antalet gravstenar som nyligen påträffats i varje tabell finns i utdata från
nodetool cfstats
. - för kluster i vår hanterade tjänst finns statistik för nyligen påträffade gravstenar på klustersidan i Mätlistor> tabellinformation. Detta inkluderar levande celler per läsning och genomsnittliga och max gravstenar per läsning, uppdelade efter nod eller tabell under en given tidsperiod.
- mer detaljerad information om lagrade gravstenar kan hittas med hjälp av IC-tools.
Hur kan jag undvika problem med gravsten?
följande alternativ kan hjälpa:
- Undvik frågor som körs på alla partitioner i tabellen (t.ex. frågor utan where-klausul eller någon fråga som kräver Tillåt filtrering).
- Alter range queries för att undvika att fråga raderade data, eller använda ett smalare dataområde. Prestandaproblem uppstår endast om gravstenarna läses och skala med antalet gravstenar som läses.
- designa datamodellen för att undvika att ta bort stora mängder data.
- Om du planerar att ta bort alla data i en tabell, trunkera eller släpp tabellen för att ta bort alla data utan att generera gravstenar.
- Använd ett standardvärde time-to-live. Detta fungerar bara effektivt om primärnyckeln för dina data är tidsbaserad, dina data skrivs i kronologisk ordning och data raderas vid ett känt datum. För att göra detta, ange en standard TTL i tabellnivåalternativen och ange en tidsbaserad komprimeringsstrategi (TimeWindowCompactionStrategy om tillgänglig, DateTieredCompactionStrategy annars). Detta kommer fortfarande att skapa gravstenar, men hela sstables kommer att släppas effektivt när TTL på allt innehåll har passerat.
Hur kan jag bli av med befintliga gravstenar?
under de flesta omständigheter är det bästa sättet att vänta på att gravstenen komprimeras normalt. Om brådskande prestanda eller diskanvändningsproblem kräver mer omedelbar åtgärd finns det två nodetool-kommandon som kan användas för att tvinga kompaktioner, vilket kan hjälpa till att släppa gravstenar. Dessa bör betraktas som en sista utväg – i ett hälsosamt kluster med en väl utformad datamodell är det inte nödvändigt att köra manuella komprimeringar.
Running nodetool compact
tvingar en komprimering av alla sstables. Detta kräver en stor mängd ledigt diskutrymme. Keyspace och tabellargument bör användas för att begränsa komprimeringen till tabellerna där gravstenar är ett problem. På tabeller där Storleksnivå Komprimeringsstrategi används, detta kommando kan leda till skapandet av en enorm sstable som aldrig kommer att ha kamrater att komprimera med; om flaggan–split-output
är tillgänglig ska den användas.
kommandotnodetool garbagecollect
är tillgängligt från Cassandra 3.10 och framåt. Detta kommando kör en serie mindre komprimeringar som också kontrollerar överlappande sstables. Det är mer CPU-intensivt och tidskrävande än nodetool compact
, men kräver mindre ledigt diskutrymme.
gravstenar kommer bara att tas bort om gc_grace_seconds har förflutit sedan gravstenarna skapades. Det avsedda syftet med gc_grace_seconds är att ge tid för reparationer för att återställa konsistensen i klustret, så var försiktig när du ändrar det – för tidigt borttagning av gravstenar kan leda till uppståndelse av raderade data. Inställningen gc_grace_seconds påverkar också utgången av tips som genereras för antydd handoff, så det är farligt att minska gc_grace_seconds under varaktigheten för det antydda Handoff-fönstret (som standard 3 timmar).
reparationer
reparationer kan fördröja eller förhindra att gravstenar släpps. När en fullständig eller stegvis reparation körs markeras de sstables som den har påverkat som reparerade; i efterföljande kompakteringar komprimeras dessa tabeller separat från sstables som inte har reparerats. Om gravstenar finns i oreparerade sstables och skuggade data finns i reparerade sstables (eller vice versa), kan data inte släppas eftersom sstables inte kan komprimeras tillsammans.
om du regelbundet kör hela eller inkrementella reparationer på klustret, bör detta inte vara för mycket av ett problem eftersom gravstenar och data så småningom kommer att sluta repareras. Men om du har en blandning av reparerade och oreparerade data, och du inte regelbundet kör reparationer, kan detta bli ett problem. sstablemetadata kan hjälpa dig att inspektera den reparerade statusen för dina sstables för att ta reda på om detta händer. Om det är, kan det vara lämpligt att ställa in alla sstables som unrepaired med sstablerepairedset så att de kan komprimeras tillsammans.
Observera att reparationer av underområden inte markerar data som reparerade.