欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis實戰(zhàn)之Lettuce的使用技巧詳解

 更新時間:2022年12月23日 10:08:49   作者:鴨血粉絲Tang  
Lettuce?是?Redis?的一款高級?Java?客戶端,與?Jedis?并列成為最熱門的客戶端之一,目前已成為?SpringBoot?2.0?版本默認的?redis?客戶端。本文主要和大家講講Lettuce的使用技巧,感興趣的可以了解一下

一、摘要

Lettuce 是 Redis 的一款高級 Java 客戶端,與 Jedis 并列成為最熱門的客戶端之一,目前已成為 SpringBoot 2.0 版本默認的 redis 客戶端。

相比老牌 Jedis,Lettuce 屬于后起之秀,不僅功能豐富,而且提供了很多新的功能特性,比如異步操作、響應(yīng)式編程等等,同時還解決了 Jedis 中線程不安全的問題。

廢話不多說了,如何使用呢?請看下文!

二、Lettuce

2.1、基本使用

首先,創(chuàng)建一個 maven 項目,引入lettuce-core包,就可以使用了。

<dependency>
??<groupId>io.lettuce</groupId>
??<artifactId>lettuce-core</artifactId>
??<version>5.3.1.RELEASE</version>
</dependency>

使用 lettuce 連接 redis,測試是否能正常聯(lián)通!

public?class?LettuceMain?{

????public?static?void?main(String[]?args)?{
????????RedisURI?redisUri?=?RedisURI.builder()
????????????????.withHost("127.0.0.1")
????????????????.withPort(6379)
????????????????.withPassword("111111")
????????????????.withTimeout(Duration.of(10,?ChronoUnit.SECONDS))
????????????????.build();
????????RedisClient?redisClient?=?RedisClient.create(redisUri);
????????StatefulRedisConnection<String,?String>?connection?=?redisClient.connect();
????????RedisCommands<String,?String>?commands?=?connection.sync();
????????System.out.println(commands.ping());
????????connection.close();
????????redisClient.shutdown();
????}
}

2.2、同步操作

基本上只要是 Jedis 支持的同步命令操作,Lettuce 都支持。

下面,我們以同步操作字符串為例,Lettuce 的 api 操作如下!

public?class?LettuceSyncMain?{

????public?static?void?main(String[]?args)?{
????????RedisURI?redisUri?=?RedisURI.builder()
????????????????.withHost("127.0.0.1").withPort(6379).withPassword("111111")
????????????????.withTimeout(Duration.of(10,?ChronoUnit.SECONDS))
????????????????.build();
????????RedisClient?redisClient?=?RedisClient.create(redisUri);
????????StatefulRedisConnection<String,?String>?connection?=?redisClient.connect();
????????//獲取同步操作命令工具
????????RedisCommands<String,?String>?commands?=?connection.sync();

????????System.out.println("清空數(shù)據(jù):"+commands.flushdb());
????????System.out.println("判斷某個鍵是否存在:"+commands.exists("username"));
????????System.out.println("新增<'username','xmr'>的鍵值對:"+commands.set("username",?"xmr"));
????????System.out.println("新增<'password','password'>的鍵值對:"+commands.set("password",?"123"));
????????System.out.println("獲取<'password'>鍵的值:"+commands.get("password"));
????????System.out.println("系統(tǒng)中所有的鍵如下:"?+?commands.keys("*"));
????????System.out.println("刪除鍵password:"+commands.del("password"));
????????System.out.println("判斷鍵password是否存在:"+commands.exists("password"));
????????System.out.println("設(shè)置鍵username的過期時間為5s:"+commands.expire("username",?5L));
????????System.out.println("查看鍵username的剩余生存時間:"+commands.ttl("username"));
????????System.out.println("移除鍵username的生存時間:"+commands.persist("username"));
????????System.out.println("查看鍵username的剩余生存時間:"+commands.ttl("username"));
????????System.out.println("查看鍵username所存儲的值的類型:"+commands.type("username"));

????????connection.close();
????????redisClient.shutdown();
????}
}

2.3、異步操作

除此之外,Lettuce 還支持異步操作,將上面的操作改成異步處理,結(jié)果如下!

public?class?LettuceASyncMain?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????RedisURI?redisUri?=?RedisURI.builder()
????????????????.withHost("127.0.0.1").withPort(6379).withPassword("111111")
????????????????.withTimeout(Duration.of(10,?ChronoUnit.SECONDS))
????????????????.build();
????????RedisClient?redisClient?=?RedisClient.create(redisUri);
????????StatefulRedisConnection<String,?String>?connection?=?redisClient.connect();
????????//獲取異步操作命令工具
????????RedisAsyncCommands<String,?String>?commands?=?connection.async();

????????System.out.println("清空數(shù)據(jù):"+commands.flushdb().get());
????????System.out.println("判斷某個鍵是否存在:"+commands.exists("username").get());
????????System.out.println("新增<'username','xmr'>的鍵值對:"+commands.set("username",?"xmr").get());
????????System.out.println("新增<'password','password'>的鍵值對:"+commands.set("password",?"123").get());
????????System.out.println("獲取<'password'>鍵的值:"+commands.get("password").get());
????????System.out.println("系統(tǒng)中所有的鍵如下:"?+?commands.keys("*").get());
????????System.out.println("刪除鍵password:"+commands.del("password").get());
????????System.out.println("判斷鍵password是否存在:"+commands.exists("password").get());
????????System.out.println("設(shè)置鍵username的過期時間為5s:"+commands.expire("username",?5L).get());
????????System.out.println("查看鍵username的剩余生存時間:"+commands.ttl("username").get());
????????System.out.println("移除鍵username的生存時間:"+commands.persist("username").get());
????????System.out.println("查看鍵username的剩余生存時間:"+commands.ttl("username").get());
????????System.out.println("查看鍵username所存儲的值的類型:"+commands.type("username").get());

????????connection.close();
????????redisClient.shutdown();
????}
}

2.4、響應(yīng)式編程

Lettuce 除了支持異步編程以外,還支持響應(yīng)式編程,Lettuce 引入的響應(yīng)式編程框架是Project Reactor,如果沒有響應(yīng)式編程經(jīng)驗可以先自行了解一下,訪問地址https://projectreactor.io/。

響應(yīng)式編程使用案例如下:

public?class?LettuceMain?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????RedisURI?redisUri?=?RedisURI.builder()
????????????????.withHost("127.0.0.1").withPort(6379).withPassword("111111")
????????????????.withTimeout(Duration.of(10,?ChronoUnit.SECONDS))
????????????????.build();
????????RedisClient?redisClient?=?RedisClient.create(redisUri);
????????StatefulRedisConnection<String,?String>?connection?=?redisClient.connect();
????????//獲取響應(yīng)式API操作命令工具
????????RedisReactiveCommands<String,?String>?commands?=?connection.reactive();

????????Mono<String>?setc?=?commands.set("name",?"mayun");
????????System.out.println(setc.block());
????????Mono<String>?getc?=?commands.get("name");
????????getc.subscribe(System.out::println);
????????Flux<String>?keys?=?commands.keys("*");
????????keys.subscribe(System.out::println);

????????//開啟一個事務(wù),先把count設(shè)置為1,再將count自增1
????????commands.multi().doOnSuccess(r?->?{
????????????commands.set("count",?"1").doOnNext(value?->?System.out.println("count1:"?+??value)).subscribe();
????????????commands.incr("count").doOnNext(value?->?System.out.println("count2:"?+??value)).subscribe();
????????}).flatMap(s?->?commands.exec())
????????????????.doOnNext(transactionResult?->?System.out.println("transactionResult:"?+?transactionResult.wasDiscarded())).subscribe();

????????Thread.sleep(1000?*?5);
????????connection.close();
????????redisClient.shutdown();
????}
}

2.5、發(fā)布和訂閱

Lettuce 還支持 redis 的消息發(fā)布和訂閱,具體實現(xiàn)案例如下:

public?class?LettuceReactiveMain1?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????RedisURI?redisUri?=?RedisURI.builder()
????????????????.withHost("127.0.0.1").withPort(6379).withPassword("111111")
????????????????.withTimeout(Duration.of(10,?ChronoUnit.SECONDS))
????????????????.build();
????????RedisClient?redisClient?=?RedisClient.create(redisUri);
????????//獲取發(fā)布訂閱操作命令工具
????????StatefulRedisPubSubConnection<String,?String>?pubsubConn?=?redisClient.connectPubSub();
????????pubsubConn.addListener(new?RedisPubSubListener<String,?String>()?{
????????????@Override
????????????public?void?unsubscribed(String?channel,?long?count)?{
????????????????System.out.println("[unsubscribed]"?+?channel);
????????????}
????????????@Override
????????????public?void?subscribed(String?channel,?long?count)?{
????????????????System.out.println("[subscribed]"?+?channel);
????????????}
????????????@Override
????????????public?void?punsubscribed(String?pattern,?long?count)?{
????????????????System.out.println("[punsubscribed]"?+?pattern);
????????????}
????????????@Override
????????????public?void?psubscribed(String?pattern,?long?count)?{
????????????????System.out.println("[psubscribed]"?+?pattern);
????????????}
????????????@Override
????????????public?void?message(String?pattern,?String?channel,?String?message)?{
????????????????System.out.println("[message]"?+?pattern?+?"?->?"?+?channel?+?"?->?"?+?message);
????????????}
????????????@Override
????????????public?void?message(String?channel,?String?message)?{
????????????????System.out.println("[message]"?+?channel?+?"?->?"?+?message);
????????????}
????????});
????????RedisPubSubAsyncCommands<String,?String>?pubsubCmd?=?pubsubConn.async();
????????pubsubCmd.psubscribe("CH");
????????pubsubCmd.psubscribe("CH2");
????????pubsubCmd.unsubscribe("CH");

????????Thread.sleep(100?*?5);
????????pubsubConn.close();
????????redisClient.shutdown();
????}
}

2.6、客戶端資源與參數(shù)配置

Lettuce 客戶端的通信框架集成了 Netty 的非阻塞 IO 操作,客戶端資源的設(shè)置與 Lettuce 的性能、并發(fā)和事件處理緊密相關(guān),如果不是特別熟悉客戶端參數(shù)配置,不建議在沒有經(jīng)驗的前提下憑直覺修改默認值,保持默認配置就行。

非集群環(huán)境下,具體的配置案例如下:

public?class?LettuceMain?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????ClientResources?resources?=?DefaultClientResources.builder()
????????????????.ioThreadPoolSize(4)?//I/O線程數(shù)
????????????????.computationThreadPoolSize(4)?//任務(wù)線程數(shù)
????????????????.build();
????????RedisURI?redisUri?=?RedisURI.builder()
????????????????.withHost("127.0.0.1").withPort(6379).withPassword("111111")
????????????????.withTimeout(Duration.of(10,?ChronoUnit.SECONDS))
????????????????.build();
????????ClientOptions?options?=?ClientOptions.builder()
????????????????.autoReconnect(true)//是否自動重連
????????????????.pingBeforeActivateConnection(true)//連接激活之前是否執(zhí)行PING命令
????????????????.build();
????????RedisClient?client?=?RedisClient.create(resources,?redisUri);
????????client.setOptions(options);
????????StatefulRedisConnection<String,?String>?connection?=?client.connect();
????????RedisCommands<String,?String>?commands?=?connection.sync();
????????commands.set("name",?"關(guān)羽");
????????System.out.println(commands.get("name"));

????????connection.close();
????????client.shutdown();
????????resources.shutdown();
????}
}

集群環(huán)境下,具體的配置案例如下:

public?class?LettuceMain?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????ClientResources?resources?=?DefaultClientResources.builder()
????????????????.ioThreadPoolSize(4)?//I/O線程數(shù)
????????????????.computationThreadPoolSize(4)?//任務(wù)線程數(shù)
????????????????.build();
????????RedisURI?redisUri?=?RedisURI.builder()
????????????????.withHost("127.0.0.1").withPort(6379).withPassword("111111")
????????????????.withTimeout(Duration.of(10,?ChronoUnit.SECONDS))
????????????????.build();
????????ClusterClientOptions?options?=?ClusterClientOptions.builder()
????????????????.autoReconnect(true)//是否自動重連
????????????????.pingBeforeActivateConnection(true)//連接激活之前是否執(zhí)行PING命令
????????????????.validateClusterNodeMembership(true)//是否校驗集群節(jié)點的成員關(guān)系
????????????????.build();
????????RedisClusterClient?client?=?RedisClusterClient.create(resources,?redisUri);
????????client.setOptions(options);
????????StatefulRedisClusterConnection<String,?String>?connection?=?client.connect();
????????RedisAdvancedClusterCommands<String,?String>?commands?=?connection.sync();
????????commands.set("name",?"張飛");
????????System.out.println(commands.get("name"));

????????connection.close();
????????client.shutdown();
????????resources.shutdown();
????}
}

2.7、線程池配置

Lettuce 連接設(shè)計的時候,就是線程安全的,所以一個連接可以被多個線程共享,同時 lettuce 連接默認是自動重連的,使用單連接基本可以滿足業(yè)務(wù)需求,大多數(shù)情況下不需要配置連接池,多連接并不會給操作帶來性能上的提升。

但在某些特殊場景下,比如事物操作,使用連接池會是一個比較好的方案,那么如何配置線程池呢?

public?class?LettuceMain?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????RedisURI?redisUri?=?RedisURI.builder()
????????????????.withHost("127.0.0.1")
????????????????.withPort(6379)
????????????????.withPassword("111111")
????????????????.withTimeout(Duration.of(10,?ChronoUnit.SECONDS))
????????????????.build();
????????RedisClient?client?=?RedisClient.create(redisUri);
????????//連接池配置
????????GenericObjectPoolConfig?poolConfig?=?new?GenericObjectPoolConfig();
????????poolConfig.setMaxIdle(2);

????????GenericObjectPool<StatefulRedisConnection<String,?String>>?pool?=?ConnectionPoolSupport.createGenericObjectPool(client::connect,?poolConfig);
????????StatefulRedisConnection<String,?String>?connection?=?pool.borrowObject();
????????RedisCommands<String,?String>?commands?=?connection.sync();
????????commands.set("name",?"張飛");
????????System.out.println(commands.get("name"));

????????connection.close();
????????pool.close();
????????client.shutdown();
????}
}

2.8、主從模式配置

redis 一般采用主從復(fù)制模式,搭建高可用的架構(gòu),簡單的說就一個主節(jié)點,多個從節(jié)點,自動從主節(jié)點同步最新數(shù)據(jù)。

Lettuce 支持自動發(fā)現(xiàn)主從模式下的節(jié)點信息,然后保存到本地,具體配置如下:

public?class?LettuceMain?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????//這里只需要配置一個節(jié)點的連接信息,不一定需要是主節(jié)點的信息,從節(jié)點也可以;可以自動發(fā)現(xiàn)主從節(jié)點
????????RedisURI?uri?=?RedisURI.builder().withHost("192.168.31.111").withPort(6379).withPassword("123456").build();
????????RedisClient?client?=?RedisClient.create(uri);
????????StatefulRedisMasterReplicaConnection<String,?String>?connection?=?MasterReplica.connect(client,?StringCodec.UTF8,?uri);
????????//從節(jié)點讀取數(shù)據(jù)
????????connection.setReadFrom(ReadFrom.REPLICA);

????????RedisCommands<String,?String>?commands?=?connection.sync();
????????commands.set("name",?"張飛");
????????System.out.println(commands.get("name"));

????????connection.close();
????????client.shutdown();
????}
}

當然我們也可以手動指定集群節(jié)點來加載,具體配置如下:

public?class?LettuceMain?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????//集群節(jié)點
????????List<RedisURI>?uris?=?new?ArrayList();
????????uris.add(RedisURI.builder().withHost("192.168.31.111").withPort(6379).withPassword("111111").build());
????????uris.add(RedisURI.builder().withHost("192.168.31.112").withPort(6379).withPassword("111111").build());
????????uris.add(RedisURI.builder().withHost("192.168.31.113").withPort(6379).withPassword("111111").build());

????????RedisClient?client?=?RedisClient.create();
????????StatefulRedisMasterReplicaConnection<String,?String>?connection?=?MasterReplica.connect(client,?StringCodec.UTF8,?uris);
????????//從節(jié)點讀取數(shù)據(jù)
????????connection.setReadFrom(ReadFrom.REPLICA);

????????RedisCommands<String,?String>?commands?=?connection.sync();
????????commands.set("name",?"張飛");
????????System.out.println(commands.get("name"));

????????connection.close();
????????client.shutdown();
????}
}

2.9、哨兵模式配置

哨兵模式,也是 redis 實現(xiàn)服務(wù)高可用的一大亮點,具體配置實現(xiàn)如下:

public?class?LettuceMain?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????//集群節(jié)點
????????List<RedisURI>?uris?=?new?ArrayList();
????????uris.add(RedisURI.builder().withSentinel("192.168.31.111",?26379).withSentinelMasterId("mymaster").withPassword("123456").build());
????????uris.add(RedisURI.builder().withSentinel("192.168.31.112",?26379).withSentinelMasterId("mymaster").withPassword("123456").build());
????????uris.add(RedisURI.builder().withSentinel("192.168.31.113",?26379).withSentinelMasterId("mymaster").withPassword("123456").build());

????????RedisClient?client?=?RedisClient.create();
????????StatefulRedisMasterReplicaConnection<String,?String>?connection?=?MasterReplica.connect(client,?StringCodec.UTF8,?uris);
????????//從節(jié)點讀取數(shù)據(jù)
????????connection.setReadFrom(ReadFrom.REPLICA);

????????RedisCommands<String,?String>?commands?=?connection.sync();
????????commands.set("name",?"趙云");
????????System.out.println(commands.get("name"));

????????connection.close();
????????client.shutdown();
????}
}

2.10、Cluster 集群模式配置

Cluster 集群模式,是之后推出的一種高可用的架構(gòu)模型,主要是采用分片方式來存儲數(shù)據(jù),具體配置如下:

public?class?LettuceReactiveMain4?{

????public?static?void?main(String[]?args)?throws?Exception?{
????????Set<RedisURI>?uris?=?new?HashSet<>();
????????uris.add(RedisURI.builder().withHost("192.168.31.111").withPort(7000).withPassword("123456").build());
????????uris.add(RedisURI.builder().withHost("192.168.31.112").withPort(7000).withPassword("123456").build());
????????uris.add(RedisURI.builder().withHost("192.168.31.113").withPort(7000).withPassword("123456").build());
????????uris.add(RedisURI.builder().withHost("192.168.31.114").withPort(7000).withPassword("123456").build());
????????uris.add(RedisURI.builder().withHost("192.168.31.115").withPort(7000).withPassword("123456").build());
????????uris.add(RedisURI.builder().withHost("192.168.31.116").withPort(7001).withPassword("123456").build());

????????RedisClusterClient?client?=?RedisClusterClient.create(uris);
????????StatefulRedisClusterConnection<String,?String>?connection?=?client.connect();
????????RedisAdvancedClusterCommands<String,?String>?commands?=?connection.sync();
????????commands.set("name",?"關(guān)羽");
????????System.out.println(commands.get("name"));

????????//選擇從節(jié)點,只讀
????????NodeSelection<String,?String>?replicas?=?commands.replicas();
????????NodeSelectionCommands<String,?String>?nodeSelectionCommands?=?replicas.commands();
????????Executions<List<String>>?keys?=?nodeSelectionCommands.keys("*");
????????keys.forEach(key?->?System.out.println(key));

????????connection.close();
????????client.shutdown();
????}
}

三、小結(jié)

Lettuce 相比老牌的 Jedis 客戶端,功能更加強大,不僅解決了線程安全的問題,還支持異步和響應(yīng)式編程,支持集群,Sentinel,管道和編碼器等等功能。

以上介紹的可能只是冰山一角,如果想要了解更多的信息,可以訪問它的官網(wǎng)地址:https://lettuce.io/

到此這篇關(guān)于Redis實戰(zhàn)之Lettuce的使用技巧詳解的文章就介紹到這了,更多相關(guān)Redis Lettuce內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis教程(十):持久化詳解

    Redis教程(十):持久化詳解

    這篇文章主要介紹了Redis教程(十):持久化詳解,本文講解了Redis提供了哪些持久化機制、RDB機制的優(yōu)勢和劣勢、AOF機制的優(yōu)勢和劣勢、其它等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • Redis 對比 Memcached 并在 CentOS 下進行安裝配置詳解

    Redis 對比 Memcached 并在 CentOS 下進行安裝配置詳解

    Redis 是一個開源、支持網(wǎng)絡(luò)、基于內(nèi)存、鍵值對的 Key-Value 數(shù)據(jù)庫,本篇文章主要介紹了Redis 對比 Memcached 并在 CentOS 下進行安裝配置詳解,有興趣的可以了解一下。
    2016-11-11
  • Redis三種集群搭建配置(主從集群、哨兵集群、分片集群)

    Redis三種集群搭建配置(主從集群、哨兵集群、分片集群)

    本文主要介紹了Redis三種集群搭建配置,包括主從集群、哨兵集群、分片集群,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Redis 實現(xiàn)隊列原理的實例詳解

    Redis 實現(xiàn)隊列原理的實例詳解

    這篇文章主要介紹了Redis 實現(xiàn)隊列原理的實例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • redis?key鍵過期刪除策略及淘汰機制探究

    redis?key鍵過期刪除策略及淘汰機制探究

    這篇文章主要為大家介紹了redis?key鍵過期刪除策略及淘汰機制探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Redis?Server啟動過程的詳細步驟

    Redis?Server啟動過程的詳細步驟

    本文主要介紹了Redis?Server啟動過程的詳細步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Redis IP地址的綁定的實現(xiàn)

    Redis IP地址的綁定的實現(xiàn)

    這篇文章主要介紹了Redis IP地址的綁定的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 基于Redis實現(xiàn)分布式鎖以及任務(wù)隊列

    基于Redis實現(xiàn)分布式鎖以及任務(wù)隊列

    這篇文章主要介紹了基于Redis實現(xiàn)分布式鎖以及任務(wù)隊列,需要的朋友可以參考下
    2015-11-11
  • Springboot/Springcloud項目集成redis進行存取的過程解析

    Springboot/Springcloud項目集成redis進行存取的過程解析

    大家都知道Redis支持五種數(shù)據(jù)類型:string(字符串),hash(哈希),list(列表),set(集合),zset(sorted set:有序集合),本文重點給大家介紹Springboot/Springcloud項目集成redis進行存取的過程,需要的朋友參考下吧
    2021-12-12
  • Redis主從架構(gòu)和高可用性實現(xiàn)過程

    Redis主從架構(gòu)和高可用性實現(xiàn)過程

    本文詳細介紹了使用Redis主從架構(gòu)和Linux虛擬服務(wù)器(LVS)實現(xiàn)高可用性的方法,并回顧了最近完成的Redis集群遷移部署過程,主從架構(gòu)通過復(fù)制數(shù)據(jù)來提高性能和數(shù)據(jù)冗余,而LVS用于實現(xiàn)負載均衡和故障切換,感興趣的朋友跟隨小編一起看看吧
    2024-09-09

最新評論