redis / jedis

Redis Java client
MIT License
11.8k stars 3.86k forks source link

Please provide a Jedis(InetSocketAddress) constructor to support unix domain socket #492

Closed ghost closed 3 years ago

ghost commented 10 years ago

In my case, redis is only binded to uds, because it's 2x+ faster.

I found a issue about uds, but you said you would not add a jni support because some peaple does not use uds.

You don't have to care about it if you support InetSocketAddress constructor because some uds library extends InetSocketAddress.

xetorthio commented 10 years ago

Can you provide an example of uds libs that extends InetSocketAddress?

All this gives me new hopes to close a very old issue! :) On Dec 4, 2013 1:17 AM, "HackerK" notifications@github.com wrote:

In my case, redis is only binded to uds, because it's 2x+ faster.

I found a issue about uds, but you said you would not add a jni support because some peaple does not use uds.

You don't have to care about it if you support InetSocketAddress constructor because some uds library extends InetSocketAddress.

— Reply to this email directly or view it on GitHubhttps://github.com/xetorthio/jedis/issues/492 .

ghost commented 10 years ago

jUnixSocket https://code.google.com/p/junixsocket/

I use this library

This contains public class AFUNIXSocketAddress extends InetSocketAddress

pgrinchenko commented 10 years ago

@ceram1 How do you launch Redis with "only binded to UDS" ?

ghost commented 10 years ago

Simply, set port to 0

according to redis, Accept connections on the specified port, default is 6379. If port 0 is specified Redis will not listen on a TCP socket.

And, unixsocket /var/run/redis/redis.sock unixsocketperm 755

HeartSaVioR commented 10 years ago

@ceram1 @xetorthio I looked over junixsocket, (but I don't used yet).

I have tested from example code, and found that we cannot use java.io.Socket instead of AFUNIXSocket.

final File socketFile = new File(new File(System
                .getProperty("java.io.tmpdir")), "junixsocket-test.sock");

//AFUNIXSocket sock = AFUNIXSocket.newInstance();
Socket sock = new Socket();
try {
    sock.connect(new AFUNIXSocketAddress(socketFile));
} catch (AFUNIXSocketException e) {
    System.out.println("Cannot connect to server. Have you started it?");
    System.out.flush();
    throw e;
}
System.out.println("Connected");

It throws java.net.NoRouteToHostException. (Can't assign requested address) (It works perfectly with AFUNIXSocket.)

So we cannot use Jedis' current socket creation code.

public void connect() {
    if (!isConnected()) {
        try {
            socket = new Socket();
            //->@wjw_add
            socket.setReuseAddress(true);
            socket.setKeepAlive(true);  //Will monitor the TCP connection is valid
            socket.setTcpNoDelay(true);  //Socket buffer Whetherclosed, to ensure timely delivery of data
            socket.setSoLinger(true,0);  //Control calls close () method, the underlying socket is closed immediately
            //<-@wjw_add

            socket.connect(new InetSocketAddress(host, port), timeout);
            socket.setSoTimeout(timeout);
            outputStream = new RedisOutputStream(socket.getOutputStream());
            inputStream = new RedisInputStream(socket.getInputStream());
        } catch (IOException ex) {
            throw new JedisConnectionException(ex);
        }
    }
}

At least we need to inject Socket, not InetSocketAddress. And we need to check AFUNIXSocket is fully compatible to Jedis's java.io.Socket usage. (or we may have troubles to set socket options from Connection's methods)

sazzad16 commented 3 years ago

Resolved by #2151