mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
No Close method and basic pooling
This commit is contained in:
parent
0ab4808153
commit
32eb50917e
|
@ -869,7 +869,6 @@ func DecodeWriteRequest(r io.Reader) (*prompb.WriteRequest, error) {
|
||||||
|
|
||||||
comp := createComp()
|
comp := createComp()
|
||||||
reqBuf, err := comp.Decompress(compressed)
|
reqBuf, err := comp.Decompress(compressed)
|
||||||
comp.Close()
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"compress/lzw"
|
"compress/lzw"
|
||||||
"io"
|
"io"
|
||||||
|
"sync"
|
||||||
|
|
||||||
reS2 "github.com/klauspost/compress/s2"
|
reS2 "github.com/klauspost/compress/s2"
|
||||||
reSnappy "github.com/klauspost/compress/snappy"
|
reSnappy "github.com/klauspost/compress/snappy"
|
||||||
|
@ -19,13 +20,12 @@ import (
|
||||||
type Compression interface {
|
type Compression interface {
|
||||||
Compress(data []byte) ([]byte, error)
|
Compress(data []byte) ([]byte, error)
|
||||||
Decompress(data []byte) ([]byte, error)
|
Decompress(data []byte) ([]byte, error)
|
||||||
Close() error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// hacky globals to easily tweak the compression algorithm and run some benchmarks
|
// hacky globals to easily tweak the compression algorithm and run some benchmarks
|
||||||
type CompAlgorithm int
|
type CompAlgorithm int
|
||||||
|
|
||||||
var UseAlgorithm = SnappyAlt
|
var UseAlgorithm = Snappy
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Snappy CompAlgorithm = iota
|
Snappy CompAlgorithm = iota
|
||||||
|
@ -44,6 +44,21 @@ const (
|
||||||
BrotliDefault
|
BrotliDefault
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// sync.Pool-ed createComp
|
||||||
|
var compPool = sync.Pool{
|
||||||
|
// New optionally specifies a function to generate
|
||||||
|
// a value when Get would otherwise return nil.
|
||||||
|
New: func() interface{} { return createComp() },
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPooledComp() Compression {
|
||||||
|
return compPool.Get().(Compression)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PutPooledComp(c Compression) {
|
||||||
|
compPool.Put(c)
|
||||||
|
}
|
||||||
|
|
||||||
var createComp func() Compression = func() Compression {
|
var createComp func() Compression = func() Compression {
|
||||||
switch UseAlgorithm {
|
switch UseAlgorithm {
|
||||||
case Snappy:
|
case Snappy:
|
||||||
|
@ -89,10 +104,6 @@ func (n *noopCompression) Decompress(data []byte) ([]byte, error) {
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *noopCompression) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type snappyCompression struct {
|
type snappyCompression struct {
|
||||||
buf []byte
|
buf []byte
|
||||||
}
|
}
|
||||||
|
@ -106,11 +117,12 @@ func (s *snappyCompression) Compress(data []byte) ([]byte, error) {
|
||||||
return compressed, nil
|
return compressed, nil
|
||||||
}
|
}
|
||||||
func (s *snappyCompression) Decompress(data []byte) ([]byte, error) {
|
func (s *snappyCompression) Decompress(data []byte) ([]byte, error) {
|
||||||
uncompressed, err := snappy.Decode(nil, data)
|
s.buf = s.buf[0:cap(s.buf)]
|
||||||
return uncompressed, err
|
uncompressed, err := snappy.Decode(s.buf, data)
|
||||||
|
if len(uncompressed) > cap(s.buf) {
|
||||||
|
s.buf = uncompressed
|
||||||
}
|
}
|
||||||
func (s *snappyCompression) Close() error {
|
return uncompressed, err
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type snappyAltCompression struct {
|
type snappyAltCompression struct {
|
||||||
|
@ -126,11 +138,12 @@ func (s *snappyAltCompression) Compress(data []byte) ([]byte, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
func (s *snappyAltCompression) Decompress(data []byte) ([]byte, error) {
|
func (s *snappyAltCompression) Decompress(data []byte) ([]byte, error) {
|
||||||
uncompressed, err := reSnappy.Decode(nil, data)
|
s.buf = s.buf[0:cap(s.buf)]
|
||||||
return uncompressed, err
|
uncompressed, err := reSnappy.Decode(s.buf, data)
|
||||||
|
if len(uncompressed) > cap(s.buf) {
|
||||||
|
s.buf = uncompressed
|
||||||
}
|
}
|
||||||
func (s *snappyAltCompression) Close() error {
|
return uncompressed, err
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type s2Compression struct {
|
type s2Compression struct {
|
||||||
|
@ -146,12 +159,12 @@ func (s *s2Compression) Compress(data []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *s2Compression) Decompress(data []byte) ([]byte, error) {
|
func (s *s2Compression) Decompress(data []byte) ([]byte, error) {
|
||||||
uncompressed, err := reS2.Decode(nil, data)
|
s.buf = s.buf[0:cap(s.buf)]
|
||||||
return uncompressed, err
|
uncompressed, err := reS2.Decode(s.buf, data)
|
||||||
|
if len(uncompressed) > cap(s.buf) {
|
||||||
|
s.buf = uncompressed
|
||||||
}
|
}
|
||||||
|
return uncompressed, err
|
||||||
func (s *s2Compression) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type zstdCompression struct {
|
type zstdCompression struct {
|
||||||
|
@ -190,20 +203,19 @@ func (z *zstdCompression) Compress(data []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (z *zstdCompression) Decompress(data []byte) ([]byte, error) {
|
func (z *zstdCompression) Decompress(data []byte) ([]byte, error) {
|
||||||
reader := bytes.NewReader(data)
|
decoder, err := reZstd.NewReader(nil)
|
||||||
decoder, err := reZstd.NewReader(reader)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer decoder.Close()
|
z.buf = z.buf[:0]
|
||||||
return io.ReadAll(decoder)
|
buf, err := decoder.DecodeAll(data, z.buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if len(buf) > cap(z.buf) {
|
||||||
func (z *zstdCompression) Close() error {
|
z.buf = buf
|
||||||
if z.w != nil {
|
|
||||||
return z.w.Close()
|
|
||||||
}
|
}
|
||||||
return nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type gzipCompression struct {
|
type gzipCompression struct {
|
||||||
|
@ -249,10 +261,19 @@ func (g *gzipCompression) Decompress(data []byte) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return decompressedData, nil
|
return decompressedData, nil
|
||||||
}
|
|
||||||
|
|
||||||
func (g *gzipCompression) Close() error {
|
// TODO: debug this
|
||||||
return nil
|
// r := bytes.NewReader(data)
|
||||||
|
// var err error
|
||||||
|
// if g.r == nil {
|
||||||
|
// g.r, err = gzip.NewReader(r)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// g.r.Reset(r)
|
||||||
|
// defer g.r.Close()
|
||||||
|
// return io.ReadAll(g.r)
|
||||||
}
|
}
|
||||||
|
|
||||||
type lzwCompression struct {
|
type lzwCompression struct {
|
||||||
|
@ -287,10 +308,6 @@ func (l *lzwCompression) Decompress(data []byte) ([]byte, error) {
|
||||||
return io.ReadAll(r)
|
return io.ReadAll(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *lzwCompression) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type flateCompression struct {
|
type flateCompression struct {
|
||||||
level int
|
level int
|
||||||
buf []byte
|
buf []byte
|
||||||
|
@ -333,14 +350,11 @@ func (f *flateCompression) Decompress(data []byte) ([]byte, error) {
|
||||||
return io.ReadAll(r)
|
return io.ReadAll(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *flateCompression) Close() error {
|
|
||||||
return f.w.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
type brotliCompression struct {
|
type brotliCompression struct {
|
||||||
quality int
|
quality int
|
||||||
buf []byte
|
buf []byte
|
||||||
w *brotli.Writer
|
w *brotli.Writer
|
||||||
|
r *brotli.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *brotliCompression) Compress(data []byte) ([]byte, error) {
|
func (b *brotliCompression) Compress(data []byte) ([]byte, error) {
|
||||||
|
@ -366,13 +380,11 @@ func (b *brotliCompression) Compress(data []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *brotliCompression) Decompress(data []byte) ([]byte, error) {
|
func (b *brotliCompression) Decompress(data []byte) ([]byte, error) {
|
||||||
reader := bytes.NewReader(data)
|
if b.r == nil {
|
||||||
r := brotli.NewReader(reader)
|
b.r = brotli.NewReader(nil)
|
||||||
return io.ReadAll(r)
|
|
||||||
}
|
}
|
||||||
|
b.r.Reset(bytes.NewReader(data))
|
||||||
func (b *brotliCompression) Close() error {
|
return io.ReadAll(b.r)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// func compressSnappy(bytes []byte, buf *[]byte) ([]byte, error) {
|
// func compressSnappy(bytes []byte, buf *[]byte) ([]byte, error) {
|
||||||
|
|
111
storage/remote/compression_test.go
Normal file
111
storage/remote/compression_test.go
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
package remote
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestCompressions(t *testing.T) {
|
||||||
|
data := []byte("Hello World")
|
||||||
|
tc := []struct {
|
||||||
|
name string
|
||||||
|
algo CompAlgorithm
|
||||||
|
}{
|
||||||
|
{"Snappy", Snappy},
|
||||||
|
{"SnappyAlt", SnappyAlt},
|
||||||
|
{"S2", S2},
|
||||||
|
{"ZstdFast", ZstdFast},
|
||||||
|
{"ZstdDefault", ZstdDefault},
|
||||||
|
{"ZstdBestComp", ZstdBestComp},
|
||||||
|
{"GzipFast", GzipFast},
|
||||||
|
{"GzipComp", GzipComp},
|
||||||
|
{"Lzw", Lzw},
|
||||||
|
{"FlateFast", FlateFast},
|
||||||
|
{"FlateComp", FlateComp},
|
||||||
|
{"BrotliFast", BrotliFast},
|
||||||
|
{"BrotliComp", BrotliComp},
|
||||||
|
{"BrotliDefault", BrotliDefault},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range tc {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
UseAlgorithm = c.algo
|
||||||
|
comp := createComp()
|
||||||
|
compressed, err := comp.Compress(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
decompressed, err := comp.Decompress(compressed)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if string(decompressed) != string(data) {
|
||||||
|
t.Fatalf("decompressed data is not equal to original data")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkCompressions(b *testing.B) {
|
||||||
|
data := makeUncompressedWriteRequestBenchData(b)
|
||||||
|
bc := []struct {
|
||||||
|
name string
|
||||||
|
algo CompAlgorithm
|
||||||
|
}{
|
||||||
|
{"Snappy", Snappy},
|
||||||
|
{"SnappyAlt", SnappyAlt},
|
||||||
|
{"S2", S2},
|
||||||
|
{"ZstdFast", ZstdFast},
|
||||||
|
{"ZstdDefault", ZstdDefault},
|
||||||
|
{"ZstdBestComp", ZstdBestComp},
|
||||||
|
{"GzipFast", GzipFast},
|
||||||
|
{"GzipComp", GzipComp},
|
||||||
|
{"Lzw", Lzw},
|
||||||
|
{"FlateFast", FlateFast},
|
||||||
|
{"FlateComp", FlateComp},
|
||||||
|
{"BrotliFast", BrotliFast},
|
||||||
|
{"BrotliComp", BrotliComp},
|
||||||
|
{"BrotliDefault", BrotliDefault},
|
||||||
|
}
|
||||||
|
comps := make(map[CompAlgorithm]Compression)
|
||||||
|
for _, c := range bc {
|
||||||
|
UseAlgorithm = c.algo
|
||||||
|
comp := createComp()
|
||||||
|
comps[c.algo] = comp
|
||||||
|
// warmup
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
compressed, _ := comp.Compress(data)
|
||||||
|
// if err != nil {
|
||||||
|
// b.Fatal(err)
|
||||||
|
// }
|
||||||
|
_, _ = comp.Decompress(compressed)
|
||||||
|
// if err != nil {
|
||||||
|
// b.Fatal(err)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range bc {
|
||||||
|
b.Run("compress-"+c.name, func(b *testing.B) {
|
||||||
|
comp := comps[c.algo]
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err := comp.Compress(data)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("decompress-"+c.name, func(b *testing.B) {
|
||||||
|
comp := comps[c.algo]
|
||||||
|
compressed, err := comp.Compress(data)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err = comp.Decompress(compressed)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -547,7 +547,6 @@ func (t *QueueManager) sendMetadataWithBackoff(ctx context.Context, metadata []p
|
||||||
// Build the WriteRequest with no samples.
|
// Build the WriteRequest with no samples.
|
||||||
comp := createComp()
|
comp := createComp()
|
||||||
req, _, err := buildWriteRequest(nil, metadata, pBuf, comp)
|
req, _, err := buildWriteRequest(nil, metadata, pBuf, comp)
|
||||||
comp.Close()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1371,7 +1370,6 @@ func (s *shards) runShard(ctx context.Context, shardID int, queue *queue) {
|
||||||
buf []byte
|
buf []byte
|
||||||
comp = createComp()
|
comp = createComp()
|
||||||
)
|
)
|
||||||
defer comp.Close()
|
|
||||||
if s.qm.sendExemplars {
|
if s.qm.sendExemplars {
|
||||||
max += int(float64(max) * 0.1)
|
max += int(float64(max) * 0.1)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue