Repository navigation
Memcached v1.5.0
This release adds opt-in Memcached cluster discovery, refreshable routing, and connection pools that follow topology changes. It also reduces allocation pressure in rendezvous selection and pool reuse, fixes standalone CLI/example builds, and moves the GUI to cmd/gui.
Breaking changes: v1.5.0 is not source-compatible with v1.4.0 for users of the resolver, picker, address, or public hash APIs. The module/import path remains github.com/yeqown/memcached; there is no /v2 migration. Read the migration notes before upgrading. The New constructor and client command signatures remain available.
go get github.com/yeqown/memcached@v1.5.0New features and fixes
- Add
resolver.NewAutoDiscoveryfor the ASCIIconfig get clusterextension used by AWS ElastiCache and Google Memorystore. Discovery is explicitly enabled; ordinary clients still use static resolution by default. - Add
NewWithContext,WithResolveTimeout, resolver-controlled refresh scheduling, and discovery/topology telemetry. - Retain the last usable topology when background discovery fails. Reuse pools for unchanged node identities, drain removed nodes, and let borrowed connections finish their requests.
- Reserve pool capacity before dialing, wake waiting borrowers on state changes, and close idle connections when pools shut down. Data connections are created on demand.
- Restore standalone CLI and example builds and check them in CI. CLI release binaries now accept the version supplied by the release linker flags.
- Fix the shared error variable race in the concurrent example.
- Move the GUI from
guitocmd/guiand tighten GUI input types/accessibility semantics. - Refresh dependencies and migrate lint tooling to golangci-lint v2. Go 1.26.0 is required.
- Expand self-contained tests, Memcached compatibility checks, and routing/lifecycle documentation.
Breaking changes and migration
| Previous API | v1.5.0 migration |
|---|---|
Root Addr, NewAddr, Resolver, Picker, and Builder |
Use resolver.Addr, resolver.NewAddr(network, address), resolver.Resolver, and picker.Picker from the new subpackages. Construct pickers directly. |
| Address priority/metadata helpers | Removed. resolver.Addr contains only Network and Address; node identity is the network/address pair. |
WithPickBuilder and root *PickBuilder constructors |
Use WithPicker(picker.NewCRC32HashPicker()), WithPicker(picker.NewMurmur3HashPicker(seed)), or WithPicker(picker.NewRendezvousHashPicker(seed)). |
Resolve(string) ([]*Addr, error) |
Implement Resolve(context.Context, string) (resolver.ResolveResult, *time.Time, error) and Close() error. Results include a Generation uint64; a nil next refresh time stops refreshes. Each resolver belongs to one client, which closes it. |
Public hash package and Murmur3 digest |
Removed. Callers importing this package must migrate to another hash implementation or the new picker constructors. |
Custom pickers must support concurrent calls and changing address snapshots.
Behavior changes to account for during rollout:
- Rendezvous key placement changes, even with the same node addresses and seed, because scoring uses node identity rather than priority. Expect cache misses after upgrading; this release does not migrate cached values or replay requests.
- Retrieval commands route by their first key. All keys supplied to multi-key
GetsorGetAndTouchesmust belong to the same node; these commands do not scatter/gather across nodes. - Static resolution validates address syntax and rejects duplicate identities and invalid address forms. Parsing no longer performs DNS lookups.
- CRC32/Murmur3 pickers retain modulo routing; changing cluster membership can remap many keys.
- GUI build/run paths now start at
cmd/gui.
To enable discovery while keeping the existing module path:
import (
"time"
"github.com/yeqown/memcached"
"github.com/yeqown/memcached/picker"
"github.com/yeqown/memcached/resolver"
)
client, err := memcached.New("configuration-endpoint:11211",
memcached.WithResolver(resolver.NewAutoDiscovery(time.Minute)),
memcached.WithResolveTimeout(5*time.Second),
memcached.WithPicker(picker.NewRendezvousHashPicker(1)),
)See usage and API migration and topology lifecycle.
Performance
- Warm, uncontended pool reuse allocates no notification channels: 0 B and 0 allocations per operation in the pool microbenchmark. Waiting borrowers still allocate as needed.
- A fresh release handle replaces the per-borrow closure and separate synchronization object. One handle allocation remains, preserving concurrent cleanup and panic semantics.
- Default rendezvous selection uses stack scratch space for common inputs and makes zero heap allocations in the 10/50-node microbenchmarks. Larger inputs fall back to the heap; custom hashes continue to receive independent input buffers.
- In local Apple M2 / Go 1.26 measurements, default rendezvous selection improved from approximately 658 to 252 ns/op at 10 nodes and 3.03 to 1.21 microseconds/op at 50 nodes compared with the previous main implementation.
- The topology implementation still adds some request/pool overhead compared with v1.4.0: a warm Get measured 11 allocations rather than 9. End-to-end latency measurements were noisy; no production latency improvement is claimed.
Discovery I/O runs outside the request path. Each discovery client adds a refresh loop/timer and a discovery connection. Connection limits apply per node, so total capacity grows with cluster size.
Compatibility and validation
- Root unit tests and real Memcached 1.6.37 integration tests passed with the race detector. CI checks lint, tests, standalone builds, and daemon compatibility.
- All nine runnable examples were exercised against a local TCP/UDP Memcached daemon with the race detector. The concurrent example completed 10,000 Set/Get pairs. Standalone and workspace execution were checked.
- The deprecated SASL example was compiled only; live SASL authentication was not tested.
- AWS/GCP discovery was validated with protocol fixtures and topology integration tests; live cloud services were not tested. Ordinary upstream Memcached does not implement
config get cluster. - This release does not add DNS/SRV/Kubernetes discovery, legacy AWS discovery-command fallback, or TLS/authentication settings for the discovery connection.
Changes: PR #43, plus documentation improvements in #39 and #42.
Full diff: v1.4.0...v1.5.0