Commit cbbfd405 authored by Kirill Smelkov's avatar Kirill Smelkov

slapos/recipe/redis: Add support for UNIX sockets

It is well known that UNIX sockets are faster than TCP over loopback.

E.g. on my machine according to lmbench[1] they have ~ 2 times
lower latency and ~ 2-3 times more throughput compared to TCP over
loopback:

    *Local* Communication latencies in microseconds - smaller is better
    ---------------------------------------------------------------------
    Host                 OS 2p/0K  Pipe AF     UDP  RPC/   TCP  RPC/ TCP
                            ctxsw       UNIX         UDP         TCP conn
    --------- ------------- ----- ----- ---- ----- ----- ----- ----- ----
    teco      Linux 4.2.0-1  13.8  29.2 26.8  45.0  47.9  48.5  55.5  45.

    *Local* Communication bandwidths in MB/s - bigger is better
    -----------------------------------------------------------------------------
    Host                OS  Pipe AF    TCP  File   Mmap  Bcopy  Bcopy  Mem   Mem
                                 UNIX      reread reread (libc) (hand) read write
    --------- ------------- ---- ---- ---- ------ ------ ------ ------ ---- -----
    teco      Linux 4.2.0-1 1084 4353 1493 2329.1 3720.7 1613.8 1109.2 3402 1404.

The same ratio holds for our std shuttle servers.

API to work with unix sockets is essentially the same as with TCP/UDP.
Because of that it is easy to support both TCP and UNIX socket in one
software, and this way a lot of software support unix sockets out of the
box, including Redis.

Because of lower latencies and higher throughput, for performance
reasons, it makes sense to interconnect services on one machine via unix
sockets and talk via TCP only to outside world.

Here we add support for unix sockets to Redis recipe.

[1] http://www.bitmover.com/lmbench/

/reviewed-by @kazuhiko  (on !27)
/cc @alain.takoudjou, @jerome, @vpelletier
parent 442866bc
......@@ -45,6 +45,11 @@ class Recipe(GenericBaseRecipe):
log_file=self.options['log_file'],
master_passwd=master_passwd
)
if self.options.get('unixsocket'):
unixsocket = "unixsocket %s\nunixsocketperm 700" % self.options['unixsocket']
else:
unixsocket = ""
configuration['unixsocket'] = unixsocket
config = self.createFile(config_file,
self.substituteTemplate(self.getTemplateFilename('redis.conf.in'),
......@@ -63,7 +68,8 @@ class Recipe(GenericBaseRecipe):
promise = self.createPythonScript(
promise_script,
'%s.promise.main' % __name__,
dict(host=self.options['ipv6'], port=self.options['port'])
dict(host=self.options['ipv6'], port=self.options['port'],
unixsocket = self.options.get('unixsocket') )
)
path_list.append(promise)
......
......@@ -7,8 +7,9 @@ import sys
def main(args):
host = args['host']
port = int(args['port'])
unixsocket = args['unixsocket']
try:
r = redis.Redis(host=host, port=port, db=0)
r = redis.Redis(host=host, port=port, unix_socket_path=unixsocket, db=0)
r.publish("Promise-Service","SlapOS Promise")
r.connection_pool.disconnect()
sys.exit(0)
......
......@@ -72,9 +72,7 @@ bind %(ipv6)s
# Specify the path for the Unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
# unixsocket /tmp/redis.sock
# unixsocketperm 700
%(unixsocket)s
# Close the connection after a client is idle for N seconds (0 to disable)
timeout 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment