• Stars
    star
    1,312
  • Rank 34,363 (Top 0.7 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 14 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A fully featured Memcached client build on top of Node.js. Build with scaling in mind so it will support Memcached clusters and consistent hashing.

Memcached Build Status

memcached is a fully featured Memcached client for Node.js. memcached is built with scaling, high availability and exceptional performance in mind. We use consistent hashing to store the data across different nodes. Consistent hashing is a scheme that provides a hash table functionality in a way that adding or removing a server node does not significantly change the mapping of the keys to server nodes. The algorithm that is used for consistent hashing is the same as libketama.

There are different ways to handle errors for example, when a server becomes unavailable you can configure the client to see all requests to that server as cache misses until it goes up again. It's also possible to automatically remove the affected server from the consistent hashing algorithm or provide memcached with a failover server that can take the place of the unresponsive server.

When these issues occur the memcached client will emit different events where you can subscribe to containing detailed information about the issues.

The client is configurable on different levels. There's a global configuration that you update so all your Memcached clusters will use the same failure configuration for example, but it's also possible to overwrite these changes per memcached instance.

protocol

As in other databases and message queues, this module uses the ASCII protocol to communicate with the server, which means that you can see what is send over the wire. For debugging this is easier for both the users and the developers however this also means that SASL auth is not supported because it demands the binary protocol.

Installation

npm install memcached

Setting up the client

The constructor of the memcached client take 2 different arguments server locations and options. Syntax:

var Memcached = require('memcached');
var memcached = new Memcached(Server locations, options);

Server locations

The server locations is designed to work with different formats. These formats are all internally parsed to the correct format so our consistent hashing scheme can work with it. You can either use:

  1. String, this only works if you are running a single server instance of Memcached. It's as easy a suppling a string in the following format: hostname:port. For example 192.168.0.102:11211 This would tell the client to connect to host 192.168.0.102 on port number 11211.

  2. Array, if you are running a single server you would only have to supply one item in the array. The array format is particularly useful if you are running a cluster of Memcached servers. This will allow you to spread the keys and load between the different servers. Giving you higher availability when one of your Memcached servers goes down.

  3. Object, when running a cluster of Memcached servers, some servers may allocate different amounts of memory, e.g. 128, 512, and 128mb. While by default all servers are equally important and dispatch consistently the keys between the servers (33/33/33%), it is possible to send more keys in servers having more memory. To do so, define an object whose key represents the server location and whose value represents a server weight, the default weight for a server being 1; so, for instance { '192.168.0.102:11211': 1, '192.168.0.103:11211': 2, '192.168.0.104:11211': 1 } distributes 50% of the keys on server 103, but only 25% on 104 and 25% on 102.

To implement one of the above formats, your constructor would look like this:

var memcached = new Memcached({ '192.168.0.102:11211': 1, '192.168.0.103:11211': 2, '192.168.0.104:11211': 1 });
var memcached = new Memcached([ '192.168.0.102:11211', '192.168.0.103:11211', '192.168.0.104:11211' ]);
var memcached = new Memcached('192.168.0.102:11211');

Options

Memcached accepts two option schemes. The first one inherits of all Memcached server instances while the second one is client specific and overwrites the globals. To define these options, Memcached server uses the same properties:

  • maxKeySize: 250, the maximum key size allowed.
  • maxExpiration: 2592000, the maximum expiration time of keys (in seconds).
  • maxValue: 1048576, the maximum size of a value.
  • poolSize: 10, the maximum size of the connection pool.
  • algorithm: md5, the hashing algorithm used to generate the hashRing values.
  • reconnect: 18000000, the time between reconnection attempts (in milliseconds).
  • timeout: 5000, the time after which Memcached sends a connection timeout (in milliseconds).
  • retries: 5, the number of socket allocation retries per request.
  • failures: 5, the number of failed-attempts to a server before it is regarded as 'dead'.
  • retry: 30000, the time between a server failure and an attempt to set it up back in service.
  • remove: false, if true, authorizes the automatic removal of dead servers from the pool.
  • failOverServers: undefined, an array of server_locations to replace servers that fail and that are removed from the consistent hashing scheme.
  • keyCompression: true, whether to use md5 as hashing scheme when keys exceed maxKeySize.
  • idle: 5000, the idle timeout for the connections.
  • encoding: utf8, encoding of data when socket as a readable stream

Example usage:

var memcached = new Memcached('localhost:11211', {retries:10,retry:10000,remove:true,failOverServers:['192.168.0.103:11211']});

If you wish to configure the options globally:

var Memcached = require('memcached');
// all global configurations should be applied to the .config object of the Client.
Memcached.config.poolSize = 25;

API

Public methods

memcached.touch Touches the given key.

  • key: String The key
  • lifetime: Number After how long should the key expire measured in seconds
  • callback: Function
memcached.touch('key', 10, function (err) { /* stuff */ });

memcached.get Get the value for the given key.

  • key: String, the key
  • callback: Function, the callback.
memcached.get('foo', function (err, data) {
  console.log(data);
});

memcached.gets Get the value and the CAS id.

  • key: String, the key
  • callback: Function, the callback.
memcached.gets('foo', function (err, data) {
  console.log(data.foo);
  console.log(data.cas);

  // Please note that the data is stored under the name of the given key.
});

memcached.getMulti Retrieves a bunch of values from multiple keys.

  • keys: Array, all the keys that needs to be fetched
  • callback: Function, the callback.
memcached.getMulti(['foo', 'bar'], function (err, data) {
  console.log(data.foo);
  console.log(data.bar);
});

memcached.set Stores a new value in Memcached.

  • key: String the name of the key
  • value: Mixed Either a buffer, JSON, number or string that you want to store.
  • lifetime: Number, how long the data needs to be stored measured in seconds
  • callback: Function the callback
memcached.set('foo', 'bar', 10, function (err) { /* stuff */ });

memcached.replace Replaces the value in memcached.

  • key: String the name of the key
  • value: Mixed Either a buffer, JSON, number or string that you want to store.
  • lifetime: Number, how long the data needs to be replaced measured in seconds
  • callback: Function the callback
memcached.replace('foo', 'bar', 10, function (err) { /* stuff */ });

memcached.add Add the value, only if it's not in memcached already.

  • key: String the name of the key
  • value: Mixed Either a buffer, JSON, number or string that you want to store.
  • lifetime: Number, how long the data needs to be replaced measured in seconds
  • callback: Function the callback
memcached.add('foo', 'bar', 10, function (err) { /* stuff */ });

memcached.cas Add the value, only if it matches the given CAS value.

  • key: String the name of the key
  • value: Mixed Either a buffer, JSON, number or string that you want to store.
  • lifetime: Number, how long the data needs to be replaced measured in seconds
  • cas: String the CAS value
  • callback: Function the callback
memcached.gets('foo', function (err, data) {
  memcached.cas('foo', 'bar', data.cas, 10, function (err) { /* stuff */ });
});

memcached.append Add the given value string to the value of an existing item.

  • key: String the name of the key
  • value: Mixed Either a buffer, JSON, number or string that you want to store.
  • callback: Function the callback
memcached.append('foo', 'bar', function (err) { /* stuff */ });

memcached.prepend Add the given value string to the value of an existing item.

  • key: String the name of the key
  • value: Mixed Either a buffer, JSON, number or string that you want to store.
  • callback: Function the callback
memcached.prepend('foo', 'bar', function (err) { /* stuff */ });

memcached.incr Increment a given key.

  • key: String the name of the key
  • amount: Number The increment
  • callback: Function the callback
memcached.incr('foo', 10, function (err) { /* stuff */ });

memcached.decr Decrement a given key.

  • key: String the name of the key
  • amount: Number The increment
  • callback: Function the callback
memcached.decr('foo', 10, function (err) { /* stuff */ });

memcached.del Remove the key from memcached.

  • key: String the name of the key
  • callback: Function the callback
memcached.del('foo', function (err) { /* stuff */ });

memcached.version Retrieves the version number of your server.

  • callback

memcached.flush Flushes the memcached server.

  • callback

memcached.stats Retrieves stats from your memcached server.

  • callback

memcached.settings Retrieves your stats settings.

  • callback

memcached.slabs Retrieves stats slabs information.

  • callback

memcached.items Retrieves stats items information.

  • callback

memcached.cachedump Inspect cache, see examples for a detailed explanation.

  • server
  • slabid
  • number
  • callback

memcached.end Closes all active memcached connections.

Private methods

The following methods are intended for private usage

.connect Fetches or generates a connection for the given server. The supplied callback function will receive a reference to the connection as argument. If there are issues with the server connection, we are going to respond with cache-miss pattern.

  • server: String, The server that needs a connection, the format must be confirm the server_locations specification.
  • callback: Function, The callback function that receives the net.Stre
memcached.connect( '192.168.0.103:11211', function( err, conn ){
  if( err ) throw new Error( err );
  console.log( conn.server );
});

.multi A small wrapper function that makes it easier to query multiple Memcached servers. It will return the location for each key or the complete list of servers.

  • keys: Array (optional), They keys that needs to be converted to a server.
  • callback: Function, The callback function for the data, it will be called for each key. It will be called with 4 arguments:
  1. server: String, The server location.
  2. key: String, The key associated with the server, if you didn't specify keys, this variable will be undefined.
  3. index: Number, The current index of the loop
  4. total: Number, The total amount server retrieved.
memcached.multi( false, function( server, key, index, totals ){
  if( err ) throw new Error( err );

  this.connect( server, function( err, conn ){
    console.log( "connection ready" )
  })
});

.command This is the core functionality of the memcached client. All public API's are routed through this function. It takes care of the argument validations Server retrieval ( If the server argument isn't specified ). After all data ready a connection is asked for the private connect method and the command is written to the Memcached server.

  • query: Object, The metaData object, see the Callbacks section for the specification.
  • server: String, The server the to connect. This is only needed when the metaData object doesn't contain a key property to retrieve the server from.
memcached.command({
  key: 'key', callback: function(){ console.dir( arguments ); },

  // validate the arguments
  validate: [[ 'key', String ], [ 'callback', Function ]],

  // used for the query
  type: 'delete',
  command: 'delete key'
});

.connectionIssue A internal function for logging issues with connections. As there can be various of ways that an error occurs we need solid issue manager to handle all these cases. For example server could crash or the Memcached server could respond with SERVER ERROR <broken>.

  • error: String, The actual error message.
  • Stream: net.Stream, A reference to the connection stream where the error occurred on.
  • callback: Function (optional), The callback function of a potential request, it will be marked as cache miss if it was provided
memcached.connectionIssue( "Server down", connectionReference );

Callbacks

Each method requires a callback function. Once this function get executed there will be 2 variables applied:

  • error: A error response if something went wrong while retrieving data from the Memcached server. Depending on the type of request this will either be an string or an Array with multiple errors.
  • response: The actual result from the Memcached server. If the response is false or undefined than a cache miss occurred. Cache misses will also occur when there is an error. So you might want to check on errors first.

When we have a successful response, the context of the callback function will shift to a metaData object. The metaData object contains all information that we used to generate the request for the Memcached server. The metaData object contains the following properties:

  • start: Date in milliseconds when the request was received
  • execution: Total execution time for the request, including response parsing.
  • callback: Reference to the callback function
  • type: The type of Memcached command
  • command: The compiled command that was send through the sockets
  • validate: The properties of metaData object that needs type validation.

And all the arguments you have send to the method, this depends on the method you have called.

Events

When connection issues occur we send out different notifications using the EventEmitter protocol. This can be useful for logging, notification and debugging purposes. Each event will receive details Object containing detailed information about the issues that occurred.

Details Object

The details Object contains the various of error messages that caused, the following 3 will always be present in all error events:

  • server: the server where the issue occurred on
  • tokens: a array of the parsed server string in [port, hostname] format.
  • messages: a array containing all error messages that this server received. As messages are added to the array using .push(), the first issue will at the beginning and the latest error at the end of the array.

The following properties depend on the type of event that is send. If we are still in our retry phase the details will also contain:

  • failures: the amount of failures left before we mark the server as dead.
  • totalFailures: the total amount of failures that occurred on this server, as when the server has been reconnected after it's dead the failures will be rest to defaults and messages will be removed.

If the server is dead these details will be added:

  • totalReconnectsAttempted: the total reconnects we have attempted. This is the success and failure combined.
  • totalReconnectsSuccess: the total successful reconnects we have made.
  • totalReconnectsFailed: the total failed reconnects we have made.
  • totalDownTime: the total down time that was generated. Formula: ( totalReconnectsFailed * reconnect_timeout ) + ( totalRetries * retry_timeout).

Events

There are 5 different events that the memcached client emits when connection issues occur.

  • issue: a issue occurred on one a server, we are going to attempt a retry next.
  • failure: a server has been marked as failure or dead.
  • reconnecting: we are going to attempt to reconnect the to the failed server.
  • reconnect: successfully reconnected to the memcached server.
  • remove: removing the server from our consistent hashing.

Example implementations:

var memcached = new Memcached([ '192.168.0.102:11211', '192.168.0.103:11211' ]);
memcached.on('failure', function( details ){ sys.error( "Server " + details.server + "went down due to: " + details.messages.join( '' ) ) });
memcached.on('reconnecting', function( details ){ sys.debug( "Total downtime caused by server " + details.server + " :" + details.totalDownTime + "ms")});

Compatibility

For compatibility with other libmemcached clients they need to have the behavior ketama_weighted set to true and the hash set to the same as node-memcached's algorithm.

Due to client dependent type flags it is unlikely that any types other than string will work.

Test

You may encounter several problems when run the test. Be sure you already made these preparations:

  1. Start the memcached service. (If in Mac env, you can install it via homebrew, and brew services start memcached)
  2. Start 3 memcached servers at port 11211, 11212, 11213. (You first service will start at default port 11211, so you need to start 2 other servers manually. memcached -p 11212 -d, memcached -p 11213 -d)
  3. Run export MEMCACHED__HOST=localhost in your terminal. (This will make sure that the test case use localhost as your memcached server IP address other than it's default IP)

Contributors

This project wouldn't be possible without the hard work of our amazing contributors. See the contributors tab in Github for an up to date list of contributors.

Thanks for all your hard work on this project!

License

The driver is released under the MIT license. See the LICENSE for more information.

More Repositories

1

useragent

Useragent parser for Node.js, ported from browserscope.org
JavaScript
886
star
2

node-hashring

hashring is a consistent hashing algorithm for Node.js that is compatible with libketama and python's hash_ring package
JavaScript
349
star
3

versions

Versions, A small module for creating a flexible CDN application
JavaScript
204
star
4

licensing

Discover the license footprint of your application
JavaScript
87
star
5

jackpot

Jackpot, tcp connection pooling for Node.js
JavaScript
75
star
6

creditcard

Creditcard number parsing, validation and information extraction
JavaScript
60
star
7

npmjs

An alternative npm registry client that I like.
JavaScript
49
star
8

argh

argh is a extremely light weight option/argument/process.argv parser for Node.js. It only parses options, nothing more than that.
JavaScript
45
star
9

FlashPolicyFileServer

A simple Flash Policy File Server for node
JavaScript
39
star
10

diagnostics

Tools for debugging your node.js modules
JavaScript
34
star
11

load

Load JavaScript files that do not use the bloat module patterns
JavaScript
24
star
12

cluster.exception

Exception handler for cluster
JavaScript
23
star
13

kuler

Color your terminal using CSS/hex color codes
JavaScript
21
star
14

realtimeplatform.github.com

TBA
21
star
15

licenses

Retrieve accurate license information for a given npm package.
JavaScript
21
star
16

fs.notify

File change notification that doesn't suck hairy monkey balls and just works.
JavaScript
19
star
17

canihaz

canihaz, lazy installing node.js modules
JavaScript
19
star
18

expirable

Expirable cache for node.js, FUCKING AWESOME YO!
JavaScript
18
star
19

mana

Mana allows api-oriented clients greater stability and high availability in demanding distributed battles and boss fights.
JavaScript
16
star
20

fingerprinting

Produce a unique string for any given resource, commonly used in cache busting practices.
JavaScript
11
star
21

nodejsconfit-2011

Demo's from nodejsconf 2011
JavaScript
11
star
22

find-package-json

Find package.json files in parent directories using an iterator based API. Keep searching till you find the one you're looking for or when you run out of folders to search in.
JavaScript
11
star
23

renderme

Render README files that people use on Github
JavaScript
10
star
24

one-time

Run the supplied function exactly one time (once).
JavaScript
9
star
25

.files

The . files, vim & build commands etc
Vim Script
9
star
26

shrinkwrap

npm shrinkwrap parsing, generation and comparison
JavaScript
9
star
27

text-hex

Create a hash from a string of text and transforms it to a color
JavaScript
8
star
28

env-variable

Cross platform environment variables with process.env, window.name, location.hash and localStorage fallbacks
JavaScript
7
star
29

commenting

Wrap content in a comment that is valid for a given file type.
JavaScript
7
star
30

node-bisection

Bisection algorithm for node.js
JavaScript
7
star
31

fn.name

Extract the name from a function.
JavaScript
7
star
32

senpai

Notice me senpai! A graceful degrading notification system for browsers.
JavaScript
7
star
33

memcached-stream

High performance streaming memcached protocol parser for Node.js. Code name: flaming-octo-bear
JavaScript
6
star
34

node-algorithms

A series of algorithms ported to JavaScript to be used on Node.js
JavaScript
5
star
35

koekje

A sessionStorage interface for cookies
JavaScript
5
star
36

uni

uni[versal] command line
JavaScript
5
star
37

ansidown

Convert a subset of markdown do a somewhat ANSI compatible output
JavaScript
5
star
38

failover

cluster-fuck management
JavaScript
4
star
39

Spry-Configurator

Spry files configurator and combinator. Version 2.0 is currently running on config-spry-it.com
JavaScript
4
star
40

gjallarhorn

Child process management without blasting your server in to pieces.
JavaScript
3
star
41

setup-env

Automated, feature detected, environment setup for your test suite
JavaScript
3
star
42

jQuery-scrollector

Navigate to elements using hashtag based CSS3 selectors,
JavaScript
3
star
43

odoyle

Micro Rules Engine powered by a simple JSON structure
JavaScript
3
star
44

connected

Simple wrapper to ensure that your `server.listen` calls receive an err like all regular callback signatures.
JavaScript
3
star
45

woohoo

WooHoo is Celebration as a Service.
JavaScript
3
star
46

assign

Map/Reduce promise like returned API -- Really not way to properly describe this module..
JavaScript
3
star
47

YUNO-UPDATE

Y U NO update your browser
JavaScript
3
star
48

enabled

Check if a certain flag is enabled.
JavaScript
3
star
49

colorspace

Generate HEX colors for a given namespace.
JavaScript
3
star
50

mono-repos

Highly opinionated set of utilities to orchestrate and administrate mono repositories.
JavaScript
3
star
51

queueback

Callback queue system for optimizing your HTTP requests
JavaScript
3
star
52

require-poisoning

Cache-Poisoning applied to Node.js require statements so you inject your own modules
JavaScript
3
star
53

rip-out

Rip out properties from an object that you don't want to have included in the cloned result.
JavaScript
2
star
54

setHeader

Protect headers from being overridden before they are written to response.
JavaScript
2
star
55

Outside

Go Outside to chat
JavaScript
2
star
56

package-link

npm link that doesn't suck
JavaScript
2
star
57

shrubbery

Shrubbery is small Map() backed plugin registry
JavaScript
2
star
58

treason

Cheating on React's JSX by using JSON
JavaScript
2
star
59

booting

Async Initialization Process
JavaScript
2
star
60

darknode

HTTP/Docker interface for Darkweb/yolo
JavaScript
2
star
61

storage-engine

EventEmitter abstraction on top the React-Native AsyncStorage API
JavaScript
2
star
62

connection-parse

Simple TCP connection string parser
JavaScript
2
star
63

enu

Extract enumerable and non-enumerable properties from an object.
JavaScript
2
star
64

node-browserscope

Browerscope.org results based on user agent queries
JavaScript
2
star
65

dollars

The "write less, do more, save dollars" library
JavaScript
2
star
66

timbers

Shiver me timbers! A tool to map short CLI argument to long CLI arguments
JavaScript
1
star
67

debug.css

debug.css
1
star
68

argh-matey

Argh Matey allows you to easily find the right cli command using language processing.
JavaScript
1
star
69

truth

Data is the only source of truth.
JavaScript
1
star
70

sparklet

Sparklet is a sparkline pagelet for BigPipe
JavaScript
1
star
71

window.name

A module which exposes sessionStorage API for storing data in the window.name
JavaScript
1
star
72

parser

Redis based IRC protocol parser based on lua scripting
Lua
1
star
73

platform-specific

Platform specific information for isomorphic applications
JavaScript
1
star
74

nock-knock

Advanced router handling for nock
JavaScript
1
star
75

dotfig

Configuration extraction from dot files or package.json fields
JavaScript
1
star
76

Spry-UI-ProgressBar

Progress bar widget for the Spry Framework
JavaScript
1
star
77

orbited

JavaScript
1
star
78

all-the-things

Random development of all the things, which should not be published yet, but does need to be tested
JavaScript
1
star
79

zoidberg

Flow control? Why not zoidberg
JavaScript
1
star
80

Spry-YQL-DataSet

YQL for Spry Data Sets
JavaScript
1
star
81

send-help

Generate developer friendly output of a help command based on a given object structure.
JavaScript
1
star