Comment utiliser la laitue dans Redis
1. Résumé
Lettuce est un client Java avancé pour Redis. C'est l'un des clients les plus populaires aux côtés de Jedis. Il est désormais devenu le client Redis par défaut pour la version SpringBoot 2.0.
Par rapport aux anciens Jedis, Lettuce est une étoile montante. Elle est non seulement riche en fonctions, mais offre également de nombreuses nouvelles fonctionnalités, telles que les opérations asynchrones, la programmation réactive, etc., et résout également les problèmes. problème d'insécurité du fil dans la question Jedis.
2. Lettuce
2.1 Utilisation de base
Tout d'abord, créez un projet maven et introduisez le lettuce-core
. paquet, vous pouvez l'utiliser. lettuce-core
包,就可以使用了。
<dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>5.3.1.RELEASE</version> </dependency>
使用 lettuce 连接 redis,测试是否能正常联通!
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("清空数据:"+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("系统中所有的键如下:" + commands.keys("*")); System.out.println("删除键password:"+commands.del("password")); System.out.println("判断键password是否存在:"+commands.exists("password")); System.out.println("设置键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 还支持异步操作,将上面的操作改成异步处理,结果如下!
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("清空数据:"+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("系统中所有的键如下:" + commands.keys("*").get()); System.out.println("删除键password:"+commands.del("password").get()); System.out.println("判断键password是否存在:"+commands.exists("password").get()); System.out.println("设置键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、响应式编程
Lettuce 除了支持异步编程以外,还支持响应式编程,Lettuce 引入的响应式编程框架是Project Reactor
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(); //获取响应式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); //开启一个事务,先把count设置为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(); } }
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); //获取发布订阅操作命令工具 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(); } }
public class LettuceMain {
public static void main(String[] args) throws Exception {
ClientResources resources = DefaultClientResources.builder()
.ioThreadPoolSize(4) //I/O线程数
.computationThreadPoolSize(4) //任务线程数
.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)//连接激活之前是否执行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", "关羽");
System.out.println(commands.get("name"));
connection.close();
client.shutdown();
resources.shutdown();
}
}
Copier après la connexion
2.3. Opération asynchrone De plus, Lettuce prend également en charge le fonctionnement asynchrone. Changez l'opération ci-dessus en traitement asynchrone. public class LettuceMain { public static void main(String[] args) throws Exception { ClientResources resources = DefaultClientResources.builder() .ioThreadPoolSize(4) //I/O线程数 .computationThreadPoolSize(4) //任务线程数 .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)//连接激活之前是否执行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", "关羽"); System.out.println(commands.get("name")); connection.close(); client.shutdown(); resources.shutdown(); } }
public class LettuceMain { public static void main(String[] args) throws Exception { ClientResources resources = DefaultClientResources.builder() .ioThreadPoolSize(4) //I/O线程数 .computationThreadPoolSize(4) //任务线程数 .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)//连接激活之前是否执行PING命令 .validateClusterNodeMembership(true)//是否校验集群节点的成员关系 .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(); } }
Project Reactor, si vous n'avez aucune expérience en programmation réactive, vous pouvez d'abord vous renseigner vous-même. Les cas d'utilisation de la programmation réactive sont les suivants : 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();
}
}
Copier après la connexion2.5, publication et abonnement Lettuce prend également en charge la publication et l'abonnement de messages Redis, des cas d'implémentation spécifiques Comme suit : public class LettuceMain {
public static void main(String[] args) throws Exception {
//这里只需要配置一个节点的连接信息,不一定需要是主节点的信息,从节点也可以;可以自动发现主从节点
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);
//从节点读取数据
connection.setReadFrom(ReadFrom.REPLICA);
RedisCommands<String, String> commands = connection.sync();
commands.set("name", "张飞");
System.out.println(commands.get("name"));
connection.close();
client.shutdown();
}
}
Copier après la connexion
2.6. Configuration des ressources et des paramètres du client Lettuce Le cadre de communication du client intègre les opérations d'E/S non bloquantes de Netty, les paramètres des ressources du client et les performances, la concurrence et les événements de Lettuce. Le traitement est étroitement lié. Si vous n'êtes pas particulièrement familier avec la configuration des paramètres client, il n'est pas recommandé de modifier les valeurs par défaut de manière intuitive sans expérience, et de simplement conserver la configuration par défaut. Dans un environnement hors cluster, le cas de configuration spécifique est le suivant : public class LettuceMain {
public static void main(String[] args) throws Exception {
//集群节点
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);
//从节点读取数据
connection.setReadFrom(ReadFrom.REPLICA);
RedisCommands<String, String> commands = connection.sync();
commands.set("name", "张飞");
System.out.println(commands.get("name"));
connection.close();
client.shutdown();
}
}
Copier après la connexion Dans un environnement cluster, le cas de configuration spécifique est le suivant : public class LettuceMain {
public static void main(String[] args) throws Exception {
//集群节点
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);
//从节点读取数据
connection.setReadFrom(ReadFrom.REPLICA);
RedisCommands<String, String> commands = connection.sync();
commands.set("name", "赵云");
System.out.println(commands.get("name"));
connection.close();
client.shutdown();
}
}
Copier après la connexion
2.7, configuration du pool de threadsLa connexion Lettuce est conçue pour être thread-safe, de sorte qu'une connexion peut être partagée par plusieurs threads en même temps, les connexions lettuce sont automatiquement reconnectées par défaut. L'utilisation d'une seule connexion peut essentiellement répondre aux besoins de l'entreprise. Dans la plupart des cas, il n'est pas nécessaire de configurer un pool de connexions et plusieurs connexions n'amélioreront pas les performances de l'opération. Mais dans certains scénarios particuliers, tels que les opérations de transaction, l'utilisation d'un pool de connexions serait une meilleure solution. Alors, comment configurer le pool de threads ? 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", "关羽");
System.out.println(commands.get("name"));
//选择从节点,只读
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();
}
}
Copier après la connexion2.8. Configuration en mode maître-esclave #🎜🎜##🎜🎜#redis utilise généralement le mode de réplication maître-esclave pour construire une architecture à haute disponibilité. plusieurs nœuds esclaves synchronisent automatiquement les dernières données du nœud maître. #🎜🎜##🎜🎜#Lettuce prend en charge la découverte automatique des informations sur les nœuds en mode maître-esclave, puis leur enregistrement local. La configuration spécifique est la suivante : #🎜🎜#rrreee#🎜🎜# Bien sûr, nous pouvons également spécifier manuellement le. nœud de cluster à charger, comme détaillé La configuration est la suivante : #🎜🎜#rrreee#🎜🎜#2.9, Configuration du mode Sentinel#🎜🎜##🎜🎜# Le mode Sentinel est également un point fort de Redis pour atteindre une haute disponibilité du service. une configuration spécifique est implémentée comme suit : #🎜🎜#rrreee# 🎜🎜#2.10, Configuration du mode cluster cluster#🎜🎜##🎜🎜#Le mode cluster cluster est un modèle d'architecture à haute disponibilité introduit plus tard. Il utilise principalement le partitionnement pour stocker les données. . La configuration spécifique est la suivante : #🎜🎜 #rrreeeCe qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Le mode Redis Cluster déploie les instances Redis sur plusieurs serveurs grâce à la rupture, à l'amélioration de l'évolutivité et de la disponibilité. Les étapes de construction sont les suivantes: Créez des instances de redis étranges avec différents ports; Créer 3 instances Sentinel, Moniteur Redis Instances et basculement; Configurer les fichiers de configuration Sentinel, ajouter des informations d'instance Redis de surveillance et des paramètres de basculement; Configurer les fichiers de configuration d'instance Redis, activer le mode de cluster et spécifier le chemin du fichier d'informations de cluster; Créer un fichier nœuds.conf, contenant des informations de chaque instance redis; Démarrez le cluster, exécutez la commande CREATE pour créer un cluster et spécifiez le nombre de répliques; Connectez-vous au cluster pour exécuter la commande d'informations de cluster pour vérifier l'état du cluster; faire

L'utilisation de la directive Redis nécessite les étapes suivantes: Ouvrez le client Redis. Entrez la commande (Verbe Key Value). Fournit les paramètres requis (varie de l'instruction à l'instruction). Appuyez sur Entrée pour exécuter la commande. Redis renvoie une réponse indiquant le résultat de l'opération (généralement OK ou -err).

Redis utilise une architecture filetée unique pour fournir des performances élevées, une simplicité et une cohérence. Il utilise le multiplexage d'E / S, les boucles d'événements, les E / S non bloquantes et la mémoire partagée pour améliorer la concurrence, mais avec des limites de limitations de concurrence, un point d'échec unique et inadapté aux charges de travail à forte intensité d'écriture.

La meilleure façon de comprendre le code source redis est d'aller étape par étape: familiarisez-vous avec les bases de Redis. Sélectionnez un module ou une fonction spécifique comme point de départ. Commencez par le point d'entrée du module ou de la fonction et affichez le code ligne par ligne. Affichez le code via la chaîne d'appel de fonction. Familiez les structures de données sous-jacentes utilisées par Redis. Identifiez l'algorithme utilisé par Redis.

Comment effacer les données Redis: utilisez la commande flushall pour effacer toutes les valeurs de clé. Utilisez la commande flushdb pour effacer la valeur clé de la base de données actuellement sélectionnée. Utilisez SELECT pour commuter les bases de données, puis utilisez FlushDB pour effacer plusieurs bases de données. Utilisez la commande del pour supprimer une clé spécifique. Utilisez l'outil Redis-CLI pour effacer les données.

Pour afficher toutes les touches dans Redis, il existe trois façons: utilisez la commande Keys pour retourner toutes les clés qui correspondent au modèle spécifié; Utilisez la commande SCAN pour itérer les touches et renvoyez un ensemble de clés; Utilisez la commande info pour obtenir le nombre total de clés.

Pour lire une file d'attente à partir de Redis, vous devez obtenir le nom de la file d'attente, lire les éléments à l'aide de la commande LPOP et traiter la file d'attente vide. Les étapes spécifiques sont les suivantes: Obtenez le nom de la file d'attente: Nommez-le avec le préfixe de "Fitre:" tel que "Fitre: My-Quyue". Utilisez la commande LPOP: éjectez l'élément de la tête de la file d'attente et renvoyez sa valeur, telle que la file d'attente LPOP: My-Queue. Traitement des files d'attente vides: si la file d'attente est vide, LPOP renvoie NIL et vous pouvez vérifier si la file d'attente existe avant de lire l'élément.

Les étapes pour démarrer un serveur Redis incluent: Installez Redis en fonction du système d'exploitation. Démarrez le service Redis via Redis-Server (Linux / MacOS) ou Redis-Server.exe (Windows). Utilisez la commande redis-Cli Ping (Linux / MacOS) ou redis-Cli.exe Ping (Windows) pour vérifier l'état du service. Utilisez un client redis, tel que redis-cli, python ou node.js pour accéder au serveur.
