memcache 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -9
- package/dist/index.cjs +1580 -1170
- package/dist/index.d.cts +325 -134
- package/dist/index.d.ts +325 -134
- package/dist/index.js +1578 -1170
- package/package.json +25 -10
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[<img src="https://jaredwray.com/images/memcache.svg" alt="Memcache Logo" align="center">](https://memcachejs.org)
|
|
1
|
+
[<img src="https://jaredwray.com/images/memcache.svg" width="80%" height="80%" align="center" alt="Memcache Logo" align="center">](https://memcachejs.org)
|
|
2
2
|
|
|
3
3
|
[](https://codecov.io/gh/jaredwray/memcache)
|
|
4
4
|
[](https://github.com/jaredwray/memcache/actions/workflows/tests.yaml)
|
|
@@ -14,7 +14,6 @@ Nodejs Memcache Client
|
|
|
14
14
|
- [Getting Started](#getting-started)
|
|
15
15
|
- [Installation](#installation)
|
|
16
16
|
- [Basic Usage](#basic-usage)
|
|
17
|
-
- [Custom Connection](#custom-connection)
|
|
18
17
|
- [API](#api)
|
|
19
18
|
- [Constructor](#constructor)
|
|
20
19
|
- [Properties](#properties)
|
|
@@ -47,6 +46,7 @@ Nodejs Memcache Client
|
|
|
47
46
|
- [Distribution Algorithms](#distribution-algorithms)
|
|
48
47
|
- [KetamaHash (Default)](#ketamahash-default)
|
|
49
48
|
- [ModulaHash](#modulahash)
|
|
49
|
+
- [BroadcastHash](#broadcasthash)
|
|
50
50
|
- [Choosing an Algorithm](#choosing-an-algorithm)
|
|
51
51
|
- [Retry Configuration](#retry-configuration)
|
|
52
52
|
- [Basic Retry Setup](#basic-retry-setup)
|
|
@@ -59,6 +59,13 @@ Nodejs Memcache Client
|
|
|
59
59
|
- [Per-Node SASL Configuration](#per-node-sasl-configuration)
|
|
60
60
|
- [Authentication Events](#authentication-events)
|
|
61
61
|
- [Server Configuration](#server-configuration)
|
|
62
|
+
- [Auto Discovery](#auto-discovery)
|
|
63
|
+
- [Enabling Auto Discovery](#enabling-auto-discovery)
|
|
64
|
+
- [Auto Discovery Options](#auto-discovery-options)
|
|
65
|
+
- [Auto Discovery Events](#auto-discovery-events)
|
|
66
|
+
- [Legacy Command Support](#legacy-command-support)
|
|
67
|
+
- [IPv6 Support](#ipv6-support)
|
|
68
|
+
- [Benchmarks](#benchmarks)
|
|
62
69
|
- [Contributing](#contributing)
|
|
63
70
|
- [License and Copyright](#license-and-copyright)
|
|
64
71
|
|
|
@@ -198,6 +205,7 @@ const client = new Memcache({
|
|
|
198
205
|
- `retryDelay?: number` - Base delay in milliseconds between retries (default: 100)
|
|
199
206
|
- `retryBackoff?: RetryBackoffFunction` - Function to calculate backoff delay (default: fixed delay)
|
|
200
207
|
- `retryOnlyIdempotent?: boolean` - Only retry commands marked as idempotent (default: true)
|
|
208
|
+
- `autoDiscover?: AutoDiscoverOptions` - AWS ElastiCache Auto Discovery configuration (see [Auto Discovery](#auto-discovery))
|
|
201
209
|
|
|
202
210
|
## Properties
|
|
203
211
|
|
|
@@ -404,6 +412,9 @@ client.on('miss', (key) => {
|
|
|
404
412
|
- `quit` - Emitted when quit command is sent
|
|
405
413
|
- `warn` - Emitted for warning messages
|
|
406
414
|
- `info` - Emitted for informational messages
|
|
415
|
+
- `autoDiscover` - Emitted on initial auto discovery with the cluster config
|
|
416
|
+
- `autoDiscoverUpdate` - Emitted when auto discovery detects a topology change
|
|
417
|
+
- `autoDiscoverError` - Emitted when auto discovery encounters an error
|
|
407
418
|
|
|
408
419
|
## Hooks
|
|
409
420
|
|
|
@@ -573,15 +584,39 @@ const client = new Memcache({
|
|
|
573
584
|
// server2 will receive approximately 25% of keys
|
|
574
585
|
```
|
|
575
586
|
|
|
587
|
+
## BroadcastHash
|
|
588
|
+
|
|
589
|
+
BroadcastHash sends every operation to all nodes in the cluster. Instead of partitioning keys across nodes, every `getNodesByKey()` call returns all nodes, so reads and writes are broadcast to every server.
|
|
590
|
+
|
|
591
|
+
```javascript
|
|
592
|
+
import { Memcache, BroadcastHash } from 'memcache';
|
|
593
|
+
|
|
594
|
+
// Use BroadcastHash for full replication
|
|
595
|
+
const client = new Memcache({
|
|
596
|
+
nodes: ['server1:11211', 'server2:11211', 'server3:11211'],
|
|
597
|
+
hash: new BroadcastHash()
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
// Every set/get/delete hits all three nodes
|
|
601
|
+
await client.set('mykey', 'Hello!');
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
**Characteristics:**
|
|
605
|
+
- Every operation targets all nodes
|
|
606
|
+
- No key partitioning — all nodes hold the same data
|
|
607
|
+
- Reads return the first successful result from any node
|
|
608
|
+
- Writes succeed only if all nodes succeed
|
|
609
|
+
- Best for replication, broadcast invalidation, or small clusters where all nodes should be in sync
|
|
610
|
+
|
|
576
611
|
## Choosing an Algorithm
|
|
577
612
|
|
|
578
|
-
| Feature | KetamaHash | ModulaHash |
|
|
579
|
-
|
|
580
|
-
| Key redistribution on node change | Minimal (~1/n keys) | All keys may move |
|
|
581
|
-
| Complexity | Higher (virtual nodes) | Lower (simple modulo) |
|
|
582
|
-
| Performance | Slightly slower | Faster |
|
|
583
|
-
| Best for | Dynamic scaling | Fixed clusters |
|
|
584
|
-
| Weighted nodes | Yes | Yes |
|
|
613
|
+
| Feature | KetamaHash | ModulaHash | BroadcastHash |
|
|
614
|
+
|---------|------------|------------|---------------|
|
|
615
|
+
| Key redistribution on node change | Minimal (~1/n keys) | All keys may move | N/A (all nodes always) |
|
|
616
|
+
| Complexity | Higher (virtual nodes) | Lower (simple modulo) | Simplest |
|
|
617
|
+
| Performance | Slightly slower | Faster | Depends on node count |
|
|
618
|
+
| Best for | Dynamic scaling | Fixed clusters | Replication |
|
|
619
|
+
| Weighted nodes | Yes | Yes | No |
|
|
585
620
|
|
|
586
621
|
**Use KetamaHash (default) when:**
|
|
587
622
|
- Your cluster size may change dynamically
|
|
@@ -593,6 +628,11 @@ const client = new Memcache({
|
|
|
593
628
|
- You prefer simplicity over minimal redistribution
|
|
594
629
|
- You're in a testing or development environment
|
|
595
630
|
|
|
631
|
+
**Use BroadcastHash when:**
|
|
632
|
+
- You want all nodes to hold the same data
|
|
633
|
+
- You need broadcast cache invalidation across all nodes
|
|
634
|
+
- You're running a small cluster where replication is more important than partitioning
|
|
635
|
+
|
|
596
636
|
# Retry Configuration
|
|
597
637
|
|
|
598
638
|
The Memcache client supports automatic retry of failed commands with configurable backoff strategies.
|
|
@@ -877,6 +917,158 @@ To use SASL authentication, your memcached server must be configured with SASL s
|
|
|
877
917
|
|
|
878
918
|
For more details, see the [memcached SASL documentation](https://github.com/memcached/memcached/wiki/SASLHowto).
|
|
879
919
|
|
|
920
|
+
# Auto Discovery
|
|
921
|
+
|
|
922
|
+
The Memcache client supports AWS ElastiCache Auto Discovery, which automatically detects cluster topology changes and adds or removes nodes as needed. When enabled, the client connects to a configuration endpoint, retrieves the current list of cache nodes, and periodically polls for changes.
|
|
923
|
+
|
|
924
|
+
## Enabling Auto Discovery
|
|
925
|
+
|
|
926
|
+
```javascript
|
|
927
|
+
import { Memcache } from 'memcache';
|
|
928
|
+
|
|
929
|
+
const client = new Memcache({
|
|
930
|
+
nodes: [],
|
|
931
|
+
autoDiscover: {
|
|
932
|
+
enabled: true,
|
|
933
|
+
configEndpoint: 'my-cluster.cfg.use1.cache.amazonaws.com:11211',
|
|
934
|
+
},
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
await client.connect();
|
|
938
|
+
// The client automatically discovers and connects to all cluster nodes
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
If you omit `configEndpoint`, the first node in the `nodes` array is used as the configuration endpoint:
|
|
942
|
+
|
|
943
|
+
```javascript
|
|
944
|
+
const client = new Memcache({
|
|
945
|
+
nodes: ['my-cluster.cfg.use1.cache.amazonaws.com:11211'],
|
|
946
|
+
autoDiscover: {
|
|
947
|
+
enabled: true,
|
|
948
|
+
},
|
|
949
|
+
});
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
## Auto Discovery Options
|
|
953
|
+
|
|
954
|
+
The `autoDiscover` option accepts an object with the following properties:
|
|
955
|
+
|
|
956
|
+
- `enabled: boolean` - Enable auto discovery of cluster nodes (required)
|
|
957
|
+
- `pollingInterval?: number` - How often to poll for topology changes, in milliseconds (default: 60000)
|
|
958
|
+
- `configEndpoint?: string` - The configuration endpoint to use for discovery. This is typically the `.cfg` endpoint from ElastiCache. If not specified, the first node in the `nodes` array will be used
|
|
959
|
+
- `useLegacyCommand?: boolean` - Use the legacy `get AmazonElastiCache:cluster` command instead of `config get cluster` (default: false)
|
|
960
|
+
|
|
961
|
+
## Auto Discovery Events
|
|
962
|
+
|
|
963
|
+
The client emits events during the auto discovery lifecycle:
|
|
964
|
+
|
|
965
|
+
```javascript
|
|
966
|
+
const client = new Memcache({
|
|
967
|
+
nodes: [],
|
|
968
|
+
autoDiscover: {
|
|
969
|
+
enabled: true,
|
|
970
|
+
configEndpoint: 'my-cluster.cfg.use1.cache.amazonaws.com:11211',
|
|
971
|
+
},
|
|
972
|
+
});
|
|
973
|
+
|
|
974
|
+
// Emitted on initial discovery with the full cluster config
|
|
975
|
+
client.on('autoDiscover', (config) => {
|
|
976
|
+
console.log('Discovered nodes:', config.nodes);
|
|
977
|
+
console.log('Config version:', config.version);
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
// Emitted when polling detects a topology change
|
|
981
|
+
client.on('autoDiscoverUpdate', (config) => {
|
|
982
|
+
console.log('Cluster topology changed:', config.nodes);
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
// Emitted when discovery encounters an error (non-fatal, retries on next poll)
|
|
986
|
+
client.on('autoDiscoverError', (error) => {
|
|
987
|
+
console.error('Discovery error:', error.message);
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
await client.connect();
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
## Legacy Command Support
|
|
994
|
+
|
|
995
|
+
For ElastiCache engine versions older than 1.4.14, use the legacy discovery command:
|
|
996
|
+
|
|
997
|
+
```javascript
|
|
998
|
+
const client = new Memcache({
|
|
999
|
+
nodes: [],
|
|
1000
|
+
autoDiscover: {
|
|
1001
|
+
enabled: true,
|
|
1002
|
+
configEndpoint: 'my-cluster.cfg.use1.cache.amazonaws.com:11211',
|
|
1003
|
+
useLegacyCommand: true, // Uses 'get AmazonElastiCache:cluster' instead of 'config get cluster'
|
|
1004
|
+
},
|
|
1005
|
+
});
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
# IPv6 Support
|
|
1009
|
+
|
|
1010
|
+
The Memcache client fully supports IPv6 addresses using standard bracket notation in URIs.
|
|
1011
|
+
|
|
1012
|
+
## Connecting to IPv6 Nodes
|
|
1013
|
+
|
|
1014
|
+
```javascript
|
|
1015
|
+
import { Memcache } from 'memcache';
|
|
1016
|
+
|
|
1017
|
+
// IPv6 loopback
|
|
1018
|
+
const client = new Memcache('[::1]:11211');
|
|
1019
|
+
|
|
1020
|
+
// Multiple IPv6 nodes
|
|
1021
|
+
const client = new Memcache({
|
|
1022
|
+
nodes: [
|
|
1023
|
+
'[::1]:11211',
|
|
1024
|
+
'[2001:db8::1]:11211',
|
|
1025
|
+
'memcache://[2001:db8::2]:11212',
|
|
1026
|
+
],
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
await client.connect();
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
## IPv6 in Auto Discovery
|
|
1033
|
+
|
|
1034
|
+
When auto discovery returns IPv6 node addresses, the client automatically brackets them for correct URI handling:
|
|
1035
|
+
|
|
1036
|
+
```javascript
|
|
1037
|
+
const client = new Memcache({
|
|
1038
|
+
nodes: [],
|
|
1039
|
+
autoDiscover: {
|
|
1040
|
+
enabled: true,
|
|
1041
|
+
configEndpoint: '[2001:db8::1]:11211',
|
|
1042
|
+
},
|
|
1043
|
+
});
|
|
1044
|
+
|
|
1045
|
+
await client.connect();
|
|
1046
|
+
// Discovered IPv6 nodes are added as [host]:port automatically
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
## IPv6 Node IDs
|
|
1050
|
+
|
|
1051
|
+
Node IDs for IPv6 addresses use bracket notation to avoid ambiguity:
|
|
1052
|
+
|
|
1053
|
+
```javascript
|
|
1054
|
+
const client = new Memcache({
|
|
1055
|
+
nodes: ['[::1]:11211', '[2001:db8::1]:11212'],
|
|
1056
|
+
});
|
|
1057
|
+
|
|
1058
|
+
console.log(client.nodeIds);
|
|
1059
|
+
// ['[::1]:11211', '[2001:db8::1]:11212']
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
# Benchmarks
|
|
1063
|
+
|
|
1064
|
+
These are provided to show a simple benchmark against current libraries. This is not robust but it is something we update regularly to make sure we are keeping performant.
|
|
1065
|
+
|
|
1066
|
+
| name | summary | ops/sec | time/op | margin | samples |
|
|
1067
|
+
|------------------------------|:---------:|----------:|----------:|:--------:|----------:|
|
|
1068
|
+
| memcache set/get (v1.4.0) | 🥇 | 3K | 350µs | ±0.19% | 10K |
|
|
1069
|
+
| memcached set/get (v2.2.2) | -2.9% | 3K | 361µs | ±0.16% | 10K |
|
|
1070
|
+
| memjs set/get (v1.3.2) | -12% | 3K | 398µs | ±0.17% | 10K |
|
|
1071
|
+
|
|
880
1072
|
# Contributing
|
|
881
1073
|
|
|
882
1074
|
Please read our [Contributing Guidelines](./CONTRIBUTING.md) and also our [Code of Conduct](./CODE_OF_CONDUCT.md).
|