diff --git a/CHANGELOG.md b/CHANGELOG.md index 52b746eadb6..0e547ae4269 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,7 @@ * [BUGFIX] Experimental Delete Series: Fixed a data race in Purger. #2817 * [BUGFIX] KV: Fixed a bug that triggered a panic due to metrics being registered with the same name but different labels when using a `multi` configured KV client. #2837 * [BUGFIX] Query-frontend: Fix passing HTTP `Host` header if `-frontend.downstream-url` is configured. #2880 +* [BUGFIX] Ingester: Improve time-series distribution when `-experimental.distributor.user-subring-size` is enabled. #2887 ## 1.2.0 / 2020-07-01 diff --git a/pkg/distributor/distributor.go b/pkg/distributor/distributor.go index da73d0f0dec..0e92c451c54 100644 --- a/pkg/distributor/distributor.go +++ b/pkg/distributor/distributor.go @@ -512,7 +512,7 @@ func (d *Distributor) Push(ctx context.Context, req *client.WriteRequest) (*clie // Obtain a subring if required if size := d.limits.SubringSize(userID); size > 0 { - h := client.HashAdd32(client.HashNew32(), userID) + h := client.HashAdd32a(client.HashNew32a(), userID) subRing, err = d.ingestersRing.Subring(h, size) if err != nil { return nil, httpgrpc.Errorf(http.StatusInternalServerError, "unable to create subring: %v", err) diff --git a/pkg/ingester/client/fnv.go b/pkg/ingester/client/fnv.go index 0241f16e48b..f2e3b7fb80f 100644 --- a/pkg/ingester/client/fnv.go +++ b/pkg/ingester/client/fnv.go @@ -75,3 +75,25 @@ func HashAddByte32(h uint32, b byte) uint32 { h ^= uint32(b) return h } + +// HashNew32a initializies a new fnv32a hash value. +func HashNew32a() uint32 { + return offset32 +} + +// HashAdd32a adds a string to a fnv32a hash value, returning the updated hash. +// Note this is the same algorithm as Go stdlib `sum32.Write()` +func HashAdd32a(h uint32, s string) uint32 { + for i := 0; i < len(s); i++ { + h ^= uint32(s[i]) + h *= prime32 + } + return h +} + +// HashAddByte32a adds a byte to a fnv32a hash value, returning the updated hash. +func HashAddByte32a(h uint32, b byte) uint32 { + h ^= uint32(b) + h *= prime32 + return h +}