Redisは、バックエンドアプリケーションの背後にある安全なネットワークで動作するように設計されています。クライアントアプリケーションは、Redisに直接接続することは想定されていません。そのため、Redisは2層アプリケーションには適していません。
それでもRedisを使用したい場合は、いくつかのオプションがあります。 RedisサーバーをHTTPインターフェースにカプセル化できます。これは、nginxredis2モジュールが提供するものです。同様の(そしてnginxに依存しない)webdisも見てみたいと思うかもしれません。 Webdisはいくつかのアクセス制御メカニズムを提供します。ドキュメントを参照してください。
別の解決策は、あなたが提案したように、トンネルを確立することです。私はこれにnginxを使用しませんが、単なる古いSSHを使用します。 RedisサーバーがマシンB(ポート6379)で実行され、クライアントがマシンAで実行されていると仮定します。
マシンAでは、次のコマンドを実行できます:
ssh [email protected]_B -L 7008:host_B:6379 -N
ローカルポート7008(任意選択)からAからBへのトンネルを開き、待機します。ユーザーはホストBで宣言され、そのパスワードがわかっている必要があります。別のセッションで、まだホストAで、次を実行できます:
redis-cli -p 7008 ping
標準のRedisクライアントが使用されていることに注意してください。トンネルは、認証、暗号化、およびオプションでクライアントの透過的な方法での圧縮を処理します。
これで、クライアントはJavaアプリケーションになり、SSHコマンドを実行してトンネルをセットアップしたくない場合があります。うまくいけば、Jschパッケージを使用して、Javaから直接トンネルを開くことができます。ジェダイの例を次に示します。
import redis.clients.jedis.*;
import java.util.*;
import com.jcraft.jsch.*;
public class TestTunnel {
Jedis jedis;
Session session;
JSch jsch = new JSch();
int port;
// None of the following should be hardcoded
static String USER = "user"; // SSH user on the redis server host
static String PASSWD = "XXXXXXXX"; // SSH user password
static String HOST = "192.168.1.62"; // Redis server host
static int PORT = 6379; // Redis server port
public TestTunnel() {
try {
// Open the SSH session
session = jsch.getSession( USER, HOST, 22 );
session.setPassword( PASSWD );
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
config.put("Compression", "yes");
config.put("ConnectionAttempts","3");
session.setConfig(config);
session.connect();
// Setup port forwarding from localhost to the Redis server
// Local port is ephemeral (given by the OS)
// Jedis connects to localhost using the local port
port = session.setPortForwardingL( 0, HOST, PORT );
jedis = new Jedis( "127.0.0.1", port );
} catch ( JSchException e ) {
// Proper error handling omitted
System.out.println(e);
}
}
public void disconnect() {
jedis.disconnect();
try {
session.delPortForwardingL( port );
session.disconnect();
} catch ( JSchException e ) {
// Proper error handling omitted
System.out.println(e);
}
}
public void mytest( int n ) {
for ( int k = 0; k < n; k++) {
jedis.set("k" + k, "value"+k);
}
System.out.println("Read: "+jedis.get("k0") );
}
public static void main(String[] args) {
TestTunnel obj = new TestTunnel();
obj.mytest(10);
obj.disconnect();
}
}
正常に動作しますが、トンネルによるオーバーヘッドがありますのでご注意ください。ネットワークが遅い場合(たとえばインターネット)、オーバーヘッドは非常に低くなります。高速LAN(1 GbE)では、それははるかに顕著です。トンネルを使用すると、遅延が最大3倍になる可能性があります。 Redisサーバーが維持できる最大スループットも影響を受けます。サーバー側では、sshdデーモンはCPUをいくらか使用します(Redis自体よりも多く)。
とはいえ、2層アプリケーションでは生のパフォーマンスはそれほど重要ではないと思います。