---
id: e52d68870be3de9f644fcfc584bd8aec
author: Lemon Mint
title: 'gosuda.org/zstd: Drop-In náhrada za DataDog/zstd s kompresiou bez CGO a izoláciou pádov'
description: CGO_ENABLED=0 Knižnica Go Zstandard, ktorá spúšťa upstream C knižnicu libzstd 1.5.7 v shared-memory worker procese s API kompatibilným s DataDog/zstd, znovupoužiteľnými kontextmi a bulk batching.
language: sk
date: 2026-10-18T14:07:11.281986997Z
path: /zstd
go_package: gosuda.org/zstd
go_repourl: https://github.com/gosuda/hqq-zstd.git
category: lowlevel
---

`gosuda.org/zstd` je kompresná knižnica v Go s `CGO_ENABLED=0`, ktorá spúšťa oficiálny C engine Zstandard (`libzstd 1.5.7`) v izolovanom pracovnom procese cez zdieľanú pamäť [HQQ](https://gosuda.org/hqq). Poskytuje API ako náhradu za `github.com/DataDog/zstd` (vrátane jednorazových funkcií `Compress`/`Decompress`, streamovacích `io.Writer`/`io.Reader`, vopred spracovaných slovníkov a opakovane použiteľných kontextov bez alokácií), pričom vykonávanie C kódu zostáva úplne mimo adresného priestoru runtime jazyka Go.

```bash
go get gosuda.org/zstd@v0.3.10507
```

## Prečo má dekompresia patriť mimo vašej haldy v Go

V produkčných backendoch sa kompresia a dekompresia nachádzajú priamo na hranici nedôveryhodného vstupu. Zberače logov, message brokery, RPC brány a úložné enginy dekomprimujú každú minútu gigabajty externe dodaných rámcov.

Mnohé tímy používajúce Go volia `github.com/DataDog/zstd`, pretože sa priamo viaže na pôvodnú C knižnicu `libzstd`: C implementácia poskytuje vysokú priepustnosť na jednom jadre, kompaktné kompresné pomery pri malých záznamoch a mimo haldy umiestnené C arény (`ZSTD_CCtx` a `ZSTD_DCtx`), ktoré nezvyšujú čas prehľadávania pamäte garbage collectorom v Go.

Prepojenie `libzstd` so službou v Go cez `cgo` však prináša dva prevádzkové problémy:

1. **Trenie pri zostavovaní a nasadení**: Rovnako ako `go-sqlite3`, aj `DataDog/zstd` vyžaduje `CGO_ENABLED=1` a cieľový toolchain C kompilátora. Krížová kompilácia služieb alebo tvorba statických binárok pre `linux/arm64` či `windows/arm64` si vyžaduje externé C sysroot prostredia.
2. **Zdieľaný adresný priestor pri nedôveryhodných vstupoch**: Dekompresia poškodených alebo nepriateľských dát v rovnakom virtuálnom adresnom priestore ako váš Go server znamená, že akákoľvek chyba v natívnom C kóde alebo vo vlastnom spracovaní slovníkov môže ukončiť celý proces Go.

`gosuda.org/zstd` zachováva presný upstream C engine `libzstd 1.5.7` a známe API `github.com/DataDog/zstd`, ale presúva vykonávanie C kódu do overeného podriadeného procesu (`zstd_server`), ktorý je s vaším programom v Go prepojený cez zdieľanú pamäť zarovnanú na riadky cache.

## Náhrada za `github.com/DataDog/zstd` bez úprav kódu

Migrácia z `github.com/DataDog/zstd` vyžaduje zmenu iba importnej cesty na `"gosuda.org/zstd"`. Nie je potrebná inštalácia externých binárok ani inicializačný kód: pri prvom volaní `gosuda.org/zstd` pre vašu platformu sprístupní vnorenú binárku `zstd_server` s SLSA atestáciou, overí jej SHA-256 digest pomocou `gosuda.org/hqq/secureexec` a otvorí fond relácií zdieľanej pamäte.

```go
package main

import (
	"bytes"
	"fmt"
	"io"
	"log"

	"gosuda.org/zstd"
)

func main() {
	// 1. Jednorazové Compress / Decompress (zodpovedá github.com/DataDog/zstd)
	src := []byte("shared-memory zstd payload without cgo")
	compressed, err := zstd.CompressLevel(nil, src, zstd.BestSpeed)
	if err != nil {
		log.Fatal(err)
	}
	plain, err := zstd.Decompress(nil, compressed)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("one-shot: %d bytes -> %d bytes (%s)\n", len(src), len(compressed), plain)

	// 2. Streamovací Writer a Reader s podporou slovníkov
	var buf bytes.Buffer
	w := zstd.NewWriterLevel(&buf, zstd.DefaultCompression)
	if _, err := w.Write(src); err != nil {
		log.Fatal(err)
	}
	if err := w.Close(); err != nil {
		log.Fatal(err)
	}

	r := zstd.NewReader(&buf)
	defer r.Close()
	streamed, err := io.ReadAll(r)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("streamed: %s\n", streamed)
}
```

### Podporované platformy a vnorené binárky

Všetkých šesť cieľových platforiem obsahuje predkompilované pracovné binárky zabezpečené SHA-256 hodnotou, vnorené pomocou platformovo špecifických build tagov (`internal/embedded/embed_<goos>_<goarch>.go`):

| Cieľový OS  | Cieľová architektúra (`GOARCH`) | Vnorená binárka                 |  Veľkosť binárky | Build toolchain a pôvod                           |
| :---------- | :------------------------------ | :------------------------------ | ---------------: | :------------------------------------------------ |
| **Linux**   | `amd64`, `arm64`                | `zstd_server_linux_<arch>`      | ~770 - 880 KiB   | GCC `-O3`, SLSA Build L3 Provenance               |
| **macOS**   | `arm64`, `amd64`                | `zstd_server_darwin_<arch>`     | ~660 - 795 KiB   | AppleClang `-O3`, SLSA Build L3 Provenance        |
| **Windows** | `amd64`                         | `zstd_server_windows_amd64.exe` |        ~818 KiB  | MSVC `-O2`, SLSA Build L3 Provenance              |
| **Windows** | `arm64`                         | `zstd_server_windows_arm64.exe` |        ~551 KiB  | `zig cc -target aarch64-windows-gnu -O3`, SLSA L3 |

## Vnútri dátovej cesty cez zdieľanú pamäť

Aby `gosuda.org/zstd` udržal priepustnosť konkurencieschopnú voči `cgo` v rámci procesu, vyhýba sa serializácii cez sockety a alokáciám na haldе v kritickej ceste.

### 1. Kódovanie slotov bez alokácií (`zstd_ctx.go` a `c/zstd_hooks.c`)

Pri použití opakovane použiteľného `zstd.Ctx` (alebo keď funkcie na úrovni balíka `Compress` a `Decompress` získajú `Ctx` z interného fondu relácií) dáta prúdia priamo cez mapovaný slot `StandardLink`:

```text
Go volajúci (zstd.Ctx)                  Slot zdieľanej pamäte                 C11 worker (zstd_hooks.c)
--------------------                    ---------------------                 -------------------------
src []byte  ------------------------->  Užitočné dáta požiadavky  ---------->  ZSTD_compressCCtx(
                                                                                cctx, resp_slot, src, level)
dst []byte  <-------------------------  Užitočné dáta odpovede  <------------  Zapisuje komprimovaný rámec priamo
                                                                              do zdieľaného slotu odpovede
```

1. Generovaný klient `hqq-bindgen` skopíruje `src` priamo do namapovaného slotu požiadavky a prepne sekvenčné slovo `SeqLock`.
2. C worker číta `src` na mieste zo slotu požiadavky a ukazovateľ na užitočné dáta slotu odpovede odovzdáva priamo ako cieľový buffer do `ZSTD_compressCCtx` alebo `ZSTD_decompressDCtx`.
3. Klient v Go skopíruje výsledný slice zo slotu odpovede do `dst` slice poskytnutého volajúcim. V ustálenom stave `ctx.CompressTo(dst, src, level)` a `ctx.DecompressInto(dst, src)` vykonávajú `0 allocs/op`.

Vopred spracované slovníky (`CDict` a `DDict`) sú uložené na C workeri za 64-bitovými handle s kontrolou generácie (`handle CDict`, `handle DDict` v `zstd.idl`). Jednorazové vytvorenie slovníka cez `ctx.NewCDict(rawDict, level)` spracuje tabuľky slovníka vnútri C workera a vráti ľahký handle, ktorý sa dá znovu použiť v tisícoch volaní bez opätovného odosielania bajtov slovníka.

### 2. Amortizácia réžie IPC pomocou hromadného rámcovania (`zstd_bulk.go`)

Pri veľkých užitočných dátach (16 KiB a viac) je round trip cez zdieľanú pamäť s hodnotou približne 200 ns zanedbateľný v porovnaní s časom CPU strávenom v `libzstd`. Pri pracovných záťažiach, ktoré komprimujú tisíce malých správ s veľkosťou 100 bajtov až 1 KiB naraz, však aj 200 ns na položku sa sčíta.

`gosuda.org/zstd` poskytuje `CompressBulk` a `DecompressBulk` na `BulkCtx` (`zstd_bulk.go`), aby odstránil round trip pre každú položku:

```go
bctx, err := client.NewBulkCtx(1 << 20)
if err != nil {
	log.Fatal(err)
}
defer bctx.Close()

items := [][]byte{
	[]byte(`{"event":"login","user":101}`),
	[]byte(`{"event":"purchase","user":101,"amount":4200}`),
	[]byte(`{"event":"logout","user":101}`),
}
compressedItems, err := bctx.CompressBulk(nil, items, zstd.DefaultCompression)
```

`CompressBulk` zabalí celú dávku `[][]byte` do jedného rámca požiadavky s prefixovanými dĺžkami v zdieľanej pamäti. C worker prechádza každú položku v jazyku C (`compress_bulk` v `c/zstd_hooks.c`), zapisuje všetky komprimované rámce súvisle do slotu odpovede a vracia celú dávku v jedinom round tripe cez zdieľanú pamäť.

### 3. Prežitie ukončenia workera bez pádu volajúceho

Keďže `zstd_server` beží v samostatnom procese operačného systému, fatálne zlyhanie vnútri C workera nikdy nezhodí vašu aplikáciu v Go:

- Ak je `zstd_server` ukončený zvonka (napríklad cez `SIGKILL` alebo udalosť OOM), transportná vrstva HQQ okamžite zistí porušeného partnera a vráti typovanú chybu `*rt.TransportError` z práve prebiehajúceho volania `Compress` alebo `Decompress`.
- Funkcie na úrovni balíka (`zstd.Compress`, `zstd.Decompress`, `zstd.NewWriter`, `zstd.NewReader`) automaticky zistia, že zdieľaný predvolený worker zmizol, pri ďalšom volaní spustia novú overenú inštanciu `zstd_server` a obnovia normálnu prevádzku.

## Rozloženie repozitára

Kódová základňa oddeľuje fasádu `DataDog/zstd` na úrovni náhrady od nízkoúrovňových primitív relácií a hromadných operácií `hqq-bindgen`:

```text
gosuda.org/zstd
├── autolaunch.go / hashes.go  # API Compress/Decompress na úrovni náhrady, fond s automatickým obnovením a SHA-256 hodnoty
├── zstd_stream.go             # Streamovací Writer/Reader (NewWriterLevelDict, NewReaderDict)
├── zstd_ctx.go                # Ctx bez alokácií a obaly CDict a DDict nad hqq-bindgen
├── zstd_bulk.go               # Rámcovanie CompressBulk a DecompressBulk s jedným round tripom
├── zstd.go                    # Generovaný klient hqq-bindgen v Go pre službu zstd IDL
├── zstd.idl                   # Schéma HQQ IDL definujúca Context, CDict, DDict a RPC metódy
├── internal/embedded/         # Vnorené binárky zstd_server s //go:embed označené platformovými tagmi (6 cieľov OS/Arch)
└── c/                         # Implementácia servera v C11 (zstd_server.c, zstd_hooks.c, main.c)
```

## Začíname

Nainštalujte `gosuda.org/zstd` pomocou `go get` a používajte ho s `CGO_ENABLED=0`:

```bash
go get gosuda.org/zstd@v0.3.10507
```

- **GitHub repozitár**: [https://github.com/gosuda/hqq-zstd](https://github.com/gosuda/hqq-zstd)
- **Architektúra a benchmarky**: [docs/ARCHITECTURE.md](https://github.com/gosuda/hqq-zstd/blob/main/docs/ARCHITECTURE.md)
- **HQQ Core Runtime**: [https://gosuda.org/hqq](https://gosuda.org/hqq)
