Should I create a new Redis client for each connec

2019-02-20 08:15发布

问题:

I'm looking at this code snippet:

var addSnippet = function( req, res ) {
  getPostParams( req, function( obj ) {
      var r = redis.createClient();

      r.stream.on( 'connect', function() {
        r.incr( 'nextid' , function( err, id ) {
          r.set( 'snippet:'+id, JSON.stringify( obj ), function() {
            var msg = 'The snippet has been saved at <a href="/'+id+'">'+req.headers.host+'/'+id+'</a>';
            res.respond( msg );
          } );
        } );
      } );
    });
};

It's from here: http://howtonode.org/node-redis-fun.

I don't quite understand what's going on. From example, I figured that the Redis client is a some kind of interface between the database and the programmer, but now it seems that they are creating a new client for each code submit (the app they are building in the tutorial is accepts code snippet submits and stores them in a database)!

Also, where are Redis databases stored? In the same directory as the script? How to I change that?

I'm using Redis with Node.js.

回答1:

Uh, looks like they're creating a redis connection for each client. This is definitely not recommended.

Redis is a database. It's like MySQL. You can access it through a client, but it's a program running on your server. The datas are handled by it, so you don't have to worry about where it is. If you do worry, you can look at redis configuration. More information here: http://redis.io (the doc is really good).

To "fix" the code, and use only one client, you'd have to use it like this:

/**
 * Move this at the top, this way it's not run once per client,
 * it is run once the node program is launched.
 */
var r = redis.createClient();

var addSnippet = function( req, res ) {
  getPostParams( req, function( obj ) {    
      r.stream.on( 'connect', function() {
        r.incr( 'nextid' , function( err, id ) {
          r.set( 'snippet:'+id, JSON.stringify( obj ), function() {
            var msg = 'The snippet has been saved at <a href="/'+id+'">'+req.headers.host+'/'+id+'</a>';
            res.respond( msg );
          } );
        } );
      } );
    });
};


回答2:

Connection pooling has to be implemented otherwise the code will run into a soup. I also use redis with django-redis-backend, with a code snippet mentioned below. It will give you an idea.

class CacheConnectionPool(object):

    def __init__(self):
        self._connection_pools = {}

    def get_connection_pool(self, host='127.0.0.1', port=6379, db=1,
                            password=None, parser_class=None,
                            unix_socket_path=None):
        connection_identifier = (host, port, db, parser_class, unix_socket_path)
        if not self._connection_pools.get(connection_identifier):
            connection_class = (
                unix_socket_path and UnixDomainSocketConnection or Connection
                )
            kwargs = {
                'db': db,
                'password': password,
                'connection_class': connection_class,
                'parser_class': parser_class,
            }
            if unix_socket_path is None:
                kwargs.update({
                    'host': host,
                    'port': port,
                })
            else:
                kwargs['path'] = unix_socket_path
            self._connection_pools[connection_identifier] = redis.ConnectionPool(**kwargs)
        return self._connection_pools[connection_identifier]

pool = CacheConnectionPool()