次の依存関係を追加します
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version></dependency>
public class Test {public static void main(String[] args) {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(20);jedisPoolConfig.setMaxIdle(10);jedisPoolConfig.setMinIdle(5);// timeout,这里既是连接超时又是读写超时,从Jedis 2.8开始有区分connectionTimeout和soTimeout的构造函数JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.157.6", 6379, 3000, null);Jedis jedis = null;try {// 从redis连接池里拿出一个连接执行命令jedis = jedisPool.getResource();System.out.println(jedis.set("single", "zhuge"));System.out.println(jedis.get("single"));// 管道示例// 管道的命令执行方式:cat redis.txt | redis‐cli ‐h 127.0.0.1 ‐a password ‐ p 6379 ‐‐pipePipeline pl = jedis.pipelined();for (int i = 0; i < 10; i++) {pl.incr("pipelineKey");pl.set("zhuge" + i, "zhuge");}List<Object> results = pl.syncAndReturnAll();System.out.println(results);// lua脚本模拟一个商品减库存的原子操作// lua脚本命令执行方式:redis‐cli ‐‐eval /tmp/test.lua , 10jedis.set("product_count_10016", "15"); // 初始化商品10016的库存String script = " local count = redis.call('get', KEYS[1]) " +" local a = tonumber(count) "+" local b = tonumber(ARGV[1]) " +" if a >= b then " +" redis.call('set', KEYS[1], count‐b) "+" return 1 " +" end " +" return 0 ";System.out.println("script:"+script);Object obj = jedis.eval(script, Arrays.asList("product_count_10016"), Arrays.asList("10"));System.out.println(obj);} catch (Exception e) {e.printStackTrace();} finally {// 注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。if (jedis != null)jedis.close();}}}
クライアントは、サーバーの応答を待たずに、一度に複数のリクエストを送信できます。すべてのコマンドが送信された後、サービスの応答を一度に読み取ることができます。これにより、複数のコマンド実行、パイプラインによるネットワーク送信のオーバーヘッドを大幅に削減できます。複数のコマンドを実行するネットワーク オーバーヘッドは、実際には 1 つのコマンドを実行するネットワーク オーバーヘッドとのみ同等です。コマンドはパイプライン モードでパッケージ化されて送信されるため、redis はすべてのコマンドを処理する前にその処理結果をキャッシュする必要があることに注意してください。パッケージ化するコマンドが増えるほど、キャッシュが消費するメモリも増えます。したがって、パッケージ化するコマンドが多ければ多いほど良いというわけではありません。パイプラインで送信された各コマンドはサーバーによってすぐに実行されます。実行が失敗した場合、情報は後続の応答で取得されます。つまり、パイプラインは「すべてのコマンドが同時に成功する」というセマンティクスを表現しません。パイプライン内のコマンドは失敗し、次のコマンドは失敗します。コマンドは効果がなく、引き続き実行されます。
上記の例を参照してください。
Redis は 2.6 でスクリプト機能を開始し、開発者が Lua 言語を使用してスクリプトを作成し、それを Redis に渡して実行できるようにしました。スクリプトを使用する利点は次のとおりです:
元の 5 つのネットワーク リクエスト操作を 1 つのリクエストで完了でき、元の 5 つのリクエストのロジックは 1 回のリクエストで完了します。 Redisサーバー。スクリプトを使用すると、ネットワークの往復遅延が短縮されます。これはパイプと似ています。
Redis はスクリプト全体を全体として実行し、途中に他のコマンドが挿入されることはありません。パイプはアトミックではありませんが、redis バッチ操作コマンド (mset と同様) はアトミックです。
redis のトランザクション関数は非常に役に立たず、エラー報告時のロールバックをサポートしていませんが、redis の Lua スクリプトには通常のトランザクション関数がほとんどあり、ロール操作の場合、redis のトランザクション機能を使用したい場合は、代わりに redis lua を使用することが公式に推奨されています。
公式 Web サイトのドキュメントには次の文章があります:
Redis スクリプトは定義上トランザクションであるため、Redis トランザクションで実行できるすべてのことはスクリプトでも実行でき、通常はスクリプトはよりシンプルかつ高速になります。
Redis2.6.0 バージョン以降では、組み込みの Lua インタープリターを介して、EVAL コマンドを使用して Lua スクリプトを評価できます。 EVAL コマンドの形式
は次のとおりです:
EVAL script numkeys key [key ...] arg [arg ...]
スクリプト パラメータは、Redis サーバー コンテキストで実行される Lua スクリプト プログラムです。このスクリプトは定義されていません (また、定義すべきではありません)。
Lua 関数として。 numkeys パラメーターは、キー パラメーターの数を指定するために使用されます。キー パラメーター key [key ...] は EVAL の 3 番目のパラメーターから始まり、スクリプトで使用される Redis キー (キー) を表します。これらのキー パラメーターは、Lua のグローバル変数 KEYS 配列を介して渡すことができます。1
を使用します。アクセスするベース アドレスとして使用します (KEYS[1]、KEYS[2] など)。コマンドの最後で、キー パラメーターではない追加パラメーター arg [arg...] に、グローバル変数 ARGV 配列を介して Lua でアクセスできます。アクセス形式は KEYS 変数 (ARGV[1]、ARGV) に似ています。 [2] など) 。例:
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second2 1) "key1"3 2) "key2"4 3) "first"5 4) "second"
Amount、key1、key2 はキー パラメータで、それぞれ KEYS[1] と KEYS[2] を使用してアクセスされ、最後の 1 番目と 2 番目は追加の
パラメータで、ARGV[1] と KEYS[2] を介してアクセスできます。 ARGV[2 ] がそれらにアクセスします。 Lua スクリプトでは、redis.call() 関数を使用して Redis コマンドを実行できます。
を使用する場合は、無限ループや時間のかかる操作に注意してください。 -消費操作。操作。 redis は、単一プロセス、単一スレッドの実行スクリプトです。パイプは Redis をブロックしません。
public class Test2 {public static void main(String[] args) {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(20);jedisPoolConfig.setMaxIdle(10);jedisPoolConfig.setMinIdle(5);String masterName = "mymaster";Set<String> sentinels = new HashSet<String>();sentinels.add(new HostAndPort("192.168.157.6",26379).toString());sentinels.add(new HostAndPort("192.168.157.6",26380).toString());sentinels.add(new HostAndPort("192.168.157.6",26381).toString());// timeout,这里既是连接超时又是读写超时,从Jedis 2.8开始有区分connectionTimeout和soTimeout的构造函数JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, jedisPoolConfig, 3000, null);Jedis jedis = null;try {// 从redis连接池里拿出一个连接执行命令jedis = jedisSentinelPool.getResource();while(true) {Thread.sleep(1000);try {System.out.println(jedis.set("single", "zhuge"));System.out.println(jedis.get("single"));} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}} catch (Exception e) {e.printStackTrace();} finally {// 注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。if (jedis != null)jedis.close();}}}
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐starter‐data‐redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons‐pool2</artifactId></dependency>
server:port: 8080spring:redis:database: 0timeout: 3000sentinel: #哨兵模式master: mymaster #主服务器所在集群名称nodes: 192.168.0.60:26379,192.168.0.60:26380,192.168.0.60:26381lettuce:pool:max‐idle: 50min‐idle: 10max‐active: 100max‐wait: 1000
@RestControllerpublic class IndexController {private static final Logger logger = LoggerFactory.getLogger(IndexController.class);@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 测试节点挂了哨兵重新选举新的master节点,客户端是否能动态感知到* 新的master选举出来后,哨兵会把消息发布出去,客户端实际上是实现了一个消息监听机制,* 当哨兵把新master的消息发布出去,客户端会立马感知到新master的信息,从而动态切换访问的masterip* @throws InterruptedException*/@RequestMapping("/test_sentinel")public void testSentinel() throws InterruptedException {int i = 1;while (true){try {stringRedisTemplate.opsForValue().set("zhuge"+i, i+"");System.out.println("设置key:"+ "zhuge" + i);i++;Thread.sleep(1000);}catch (Exception e){logger.error("错误:", e);}}}}
RedisTemplate には、一般的に使用されるいくつかのインターフェイス メソッドが提供されています。
private ValueOperations<K, V> valueOps;private HashOperations<K, V> hashOps;private ListOperations<K, V> listOps;private SetOperations<K, V> setOps;private ZSetOperations<K, V> zSetOps;
redisTemplate.opsForValue();//操作字符串redisTemplate.opsForHash();//操作hashredisTemplate.opsForList();//操作listredisTemplate.opsForSet();//操作setredisTemplate.opsForZSet();//操作有序set
StringRedisTemplate はデフォルトで String シリアル化戦略を使用し、保存されたキーと値はこの戦略を使用して
シリアル化されて保存されます。 RedisTemplate はデフォルトで JDK のシリアル化戦略を使用し、保存されたキーと値はこの戦略を使用してシリアル化され、保存されます。
つまり、コンテンツが RedisTemplate で保存されている場合、コンソールで開くと多くのエンコードされた文字が表示され、理解しにくくなります。
Redis客户端命令对应的RedisTemplate中的方法列表:
public class Test3 {public static void main(String[] args) throws IOException {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(20);jedisPoolConfig.setMaxIdle(10);jedisPoolConfig.setMinIdle(5);Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();jedisClusterNode.add(new HostAndPort("192.168.0.61", 8001));jedisClusterNode.add(new HostAndPort("192.168.0.62", 8002));jedisClusterNode.add(new HostAndPort("192.168.0.63", 8003));jedisClusterNode.add(new HostAndPort("192.168.0.61", 8004));jedisClusterNode.add(new HostAndPort("192.168.0.62", 8005));jedisClusterNode.add(new HostAndPort("192.168.0.63", 8006));// timeout,这里既是连接超时又是读写超时,从Jedis 2.8开始有区分connectionTimeout和soTimeout的构造函数JedisCluster jedisCluster = new JedisCluster(jedisClusterNode, 6000, 5000, 10, "zhuge", jedisPoolConfig);try {while(true) {Thread.sleep(1000);try {System.out.println(jedisCluster.set("single", "zhuge"));System.out.println(jedisCluster.get("single"));} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}} catch (Exception e) {e.printStackTrace();} finally {// 注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。if (jedisCluster != null)jedisCluster.close();}}}
其实集群模式跟哨兵模式很类似,只不过配置文件修改一下即可
server:port: 8080spring:redis:database: 0timeout: 3000password: zhugecluster:nodes:192.168.0.61:8001,192.168.0.62:8002,192.168.0.63:8003lettuce:pool:# 连接池中的最大空闲连接max‐idle: 50# 连接池中最小空闲连接min‐idle: 10max‐active: 100# 连接池阻塞等待时间(负值表示没有限制)max‐wait: 1000
只不过 sentinel换成了 cluster,然后API什么的都是一样的。
以上がRedis Java接続方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。