Ga naar hoofdinhoud

Onderhoud en probleemoplossing

Ister is ontworpen om voor zichzelf te zorgen: caches worden opgeschoond, de continue-watching-lijst herstelt zichzelf, en mislukt achtergrondwerk wordt bewaard voor inspectie. Dit hoofdstuk behandelt de bewegende delen die je moet kennen, wat je moet back-uppen en de gebruikelijke verdachten wanneer iets er raar uitziet.

Geplande taken

TaakModuleSchema (standaard)Wat hij doet
Cache-opschoningdiskdagelijks, 04:30verwijdert cachebestanden waar geen databaserij naar verwijst ("zombies"); laat podcastdownloads ouder dan podcast-retention-days (30) verlopen, tenzij iemand middenin een aflevering zit
Tmp-transcode-opschoningtranscoderdagelijks, 04:30dezelfde sweep voor de tijdelijke HLS-transcodemap
Pre-transcodeworkerelke 15 minwarmt HLS-uitvoer op voor wat gebruikers waarschijnlijk als volgende afspelen
Continue-watching-rebuildworker's nachts, 03:30herberekent de continue-watching-lijst van elke gebruiker vanaf nul; verwijdert items waarvan de media weg is
Podcast-verversingworkerelk uurhaalt elke geabonneerde feed op, zet downloads van nieuwe afleveringen in de queue
Transcode-cache-sweeptranscoderelke 15 minverwijdert afgeronde HLS-uitvoer ouder dan cache-retention-hours (2 u), met respect voor de keep_until-markering van elke sessie — dít is de sweep die tussen de dagelijkse runs door daadwerkelijk HLS-ruimte vrijmaakt
Streamtoken-verloopdatabaseelk uurverwijdert verlopen HLS-/afbeeldings-streamtokens
Afspeelsessie-sweepcoreelke 15 slaat verlopen client-afspeelsessies uit het live register verdwijnen
Node-token-verversingtranscoderelke 12 uververst de tokens waarmee nodes zich bij elkaar authenticeren

Belangrijk: de cache-opschoning wordt geleverd met app.ister.server.cache-cleanup.dry-run=true — standaard logt hij alleen wat hij zou verwijderen. Draai een deploy of twee, controleer of de logregels er verstandig uitzien, en zet dan CACHE_CLEANUP_DRY_RUN=false om daadwerkelijk schijfruimte terug te winnen. Hij komt nooit aan bestanden jonger dan CACHE_CLEANUP_MIN_AGE (24u), en nooit aan je media.

Dezelfde dagelijkse run ruimt ook verkleinde artwork op (TMP_DIR/image-thumbs/, de kleinere varianten die clients voor grid-tegels opvragen). Die zijn goedkoop opnieuw te maken — één decode bij het volgende verzoek — dus ze krijgen hun eigen, langere inactiviteitsvenster: IMAGE_THUMBNAIL_MAX_IDLE (30 dagen). Een miniatuur verdwijnt als niemand die artwork binnen dat venster heeft bekeken, of als de afbeelding zelf uit de database weg is.

Back-up

PostgreSQL is de enige bron van waarheid — het is het enige dat je moet back-uppen (plus je mediabestanden, die sowieso van jou zijn; de server wijzigt ze nooit). Al het andere is opnieuw op te bouwen:

DataWaarHerstel
Afbeeldingscache, podcastdownloadsCACHE_DIRre-scan / refreshMetadata; podcasts worden opnieuw gedownload
HLS-segmentenTMP_DIRworden op verzoek opnieuw getranscodeerd
Typesense-indexTypesense-volumeéén rebuildSearchIndex-mutation
RabbitMQ-queuesbrokervluchtig werk; een verloren bericht vertraagt hooguit metadata tot de volgende scan

Dus: pg_dump op een schema, en doe geen moeite om de caches te back-uppen.

Monitoring

  • Actuator op poort 8081: /actuator/health voor probes, /actuator/prometheus om te scrapen.
  • Dead-letter-queue — mislukte achtergrondevents worden met backoff opnieuw geprobeerd en belanden daarna in de RabbitMQ-queue app.ister.server.dead-letter, met de exception bewaard in de berichtheaders. Houd de diepte in de gaten (RabbitMQ-management-UI op 15672, of Prometheus); een groeiende dead-letter-queue is het vroegste teken dat scannen of het ophalen van metadata faalt.
  • Live activiteit — de GraphQL-subscription serverActivity (zichtbaar op de activiteitenpagina van de client) toont waar elke node op dit moment mee bezig is, inclusief de queue-dieptes (queueStats) — voor een routinematige "loopt de achterstand leeg?"-check heb je de RabbitMQ-UI niet nodig.
  • Poortbotsing om op te letten: de actuator luistert op 8081, wat ook een populaire poort is om een node op te publiceren (het meegeleverde multi-node-composebestand publiceert node 1 op hostpoort 8081). Houd de managementpoort strikt intern — de endpoints zijn niet-geauthenticeerd (Configuratie).

Eenmalige upgrade-stappen

Crop-detectie en intro-/outro-detectie (V37/V38) vullen zich bij bij de eerste scan na de upgrade. De eerste scanLibraries-run analyseert elk bestaand videobestand opnieuw (zwarte-balken-cropdetectie) en fingerprint elke aflevering (intro-/outro-detectie) — veruit het zwaarste onderdeel van de upgrade op een grote bibliotheek, en het concurreert met gewoon transcoderen om CPU. Ontsnappingsluiken om het uit te stellen: app.ister.server.crop-detect-backfill=false en app.ister.server.segment-detect-backfill=false; nieuwe bestanden worden hoe dan ook geanalyseerd.

Artiesten worden samengevoegd bij de eerste start na migratie V43. Tot dan kon één artiest meerdere keren bestaan — "ABBA" naast "Abba", en "X feat. Y" als derde artiest die noch X noch Y kon zien. V43 herschrijft de feat.-namen naar hun primaire artiest (en crediteert de gast op de betrokken nummers), voegt de dubbelen samen tot één persoon en legt de identiteit vast op de naam zonder hoofdlettergevoeligheid. Kijkgeschiedenis en ratings blijven behouden: waar twee rijen botsen, winnen de verste voortgang en de hoogste rating. De migratie is niet omkeerbaar — maak eerst een back-up (zie Back-up).

Draai daarna één keer de GraphQL-mutation rebuildSearchIndex: de samengevoegde personen laten verouderde documenten in Typesense achter. Featured gasten in bestanden die nooit in een artiestenrij stonden, komen mee met een gewone hersan.

Uitgebreide TMDB-metadata (V45) vereist een eenmalige backfill. Genres, community-rating, speelduur, tagline, keuring, trailer, studio's/netwerken, collectie en keywords worden alleen opgehaald wanneer de film-/show-/afleveringshandlers draaien; bestaande items blijven dus leeg tot een verversing. Draai na de upgrade één keer de GraphQL-mutation refreshMetadata (mode MISSING, de standaard): die pakt elke film en show op waarvan de verrijkingskolommen nooit gevuld zijn. Speelduur/stemmen van afleveringen hebben zo'n marker niet — ververs bestaande afleveringen met refreshMetadata(mode: FORCE, libraryId: …) per showbibliotheek (of refreshShow per show). De zoekindex volgt automatisch (geen rebuildSearchIndex nodig — de genre_<tag>-velden bestaan al in het collectieschema).

Scan één keer opnieuw na de artwork-naamfix. Lokale artwork-bestanden met folder, poster of artist in de naam werden vroeger stilletjes door de scanner genegeerd; ze worden nu geaccepteerd (zie Naamconventies). Draai na de upgrade één keer scanLibraries om bestanden op te pikken die eerdere scans oversloegen.

Force-verversingen laten verweesde afbeeldingsbestanden achter. De FORCE-flow en de per-item refresh*-mutations verwijderen afbeeldings-rijen en downloaden artwork onder nieuwe namen; de oude cachebestanden worden opgeruimd door de dagelijkse cache-opschoning — die alleen logt tot CACHE_CLEANUP_DRY_RUN=false (zie hierboven).

Probleemoplossing

Geen metadata na een scan (kale bestandsnamen, geen posters) — vrijwel altijd een ontbrekende of verkeerde TMDB-key (app.ister.server.TMDB.apikey, een API read access token): zonder die wordt het ophalen van metadata overgeslagen. Stel hem in en draai dan refreshMetadata om aan te vullen. Controleer ook de dead-letter-queue op rate-limit- of netwerkfouten.

Afspelen start nooit / geen transcode — de server kan FFmpeg niet draaien. Controleer of FFMPEG_DIR naar een map wijst met ffmpeg en ffprobe (in de officiële image staan ze in /usr/bin). Probeer bij problemen met hardwareversnelling eerst HLS_HWACCEL=none om de GPU-opstelling (device-mapping, render-groep) van de pipeline te isoleren.

Item ontbreekt in (of blijft hangen in) continue watching — de lijst is voorberekend; als een client voortgang via een ongebruikelijk pad heeft weggeschreven, kan hij achterlopen. De nachtelijke rebuild (03:30) repareert dit; hij draait ook eenmalig bij het opstarten wanneer de tabel leeg is.

Zoeken geeft een fout ("Search is not configured on this server") — TYPESENSE_ENABLED staat op false. Staat zoeken wél aan maar is het leeg, dan is Typesense onbereikbaar of is er na het inschakelen nooit geherindexeerd. Zie Zoeken.

Een node weigert te starten met "Directory X name is already used by an other node" — twee nodes claimen dezelfde directorynaam. Het opstarten breekt bewust af; hernoem één kant (of repareer de gekopieerde configuratie) — zie Multi-node.

Lokaal artwork verschijnt niet — de bestandsnaam van de afbeelding moet een van cover, folder, poster, artist (poster/cover) of thumb, background (backdrop) bevatten; al het andere wordt genegeerd. Zie Naamconventies.

Een handler blijft dezelfde bestanden herverwerken — de klassieke interactie met RabbitMQ's consumer_timeout: een bericht waarvan het werk langer duurt dan de 30-minuten-consumer-timeout van de broker wordt opnieuw in de queue gezet en begint opnieuw, eindeloos. De standaardwaarden beschermen hiertegen (prefetch=1, sweeps in chunks — zie de commentaren in core.properties en disk.properties); heb je een chunkgrootte verhoogd of de broker-timeout verlaagd, zet dat dan terug.

Geen skip-intro-knop op sommige afleveringen — intro-/outro-detectie vergelijkt afleveringen binnen een seizoen en stempelt per bestand een detectorversie-markering. Een seizoen verspreid over meerdere nodes paart alleen de afleveringen die lokaal op elke node staan, en een node met één losse aflevering detecteert niets. Zie Scannen en analyse.

Schijf loopt vol — controleer of de cache-opschoning nog in dry-run staat (zie hierboven), en kijk naar de grootte van CACHE_DIR/TMP_DIR in verhouding tot podcastretentie en pre-transcode-activiteit.

Nieuwe bestanden verschijnen niet — er is geen filesystem-watcher; draai scanLibraries. Worden bestanden wel gevonden maar verkeerd geclassificeerd, vergelijk hun paden dan met de verwachte indeling.

Voor een dieper begrip van elk van deze subsystemen begin je bij het architectuuroverzicht.