当前位置:网站首页>How to correctly use vertx to operate redis (3.9.4 with source code analysis)
How to correctly use vertx to operate redis (3.9.4 with source code analysis)
2022-07-01 19:37:00 【Natural player】
1 origin
It's really a special experience .
Increased knowledge reserves :Vert.x Asynchronous connection Redis And operate Redis.
What happened :
The team needs to develop offline algorithm middleware , Integrated into the business side background service ,
The sentinel mode is used in the original middleware Redis, Now we need to add new logic ,
Operate in cluster mode Redis, Middleware is based on Vert.x 3.5.1 A version supporting cluster connection has been modified ,
Meet cluster connection and operation . Everything is wonderful , The test passed .
therefore , Test native Vertx Higher version (>3.8.x) Cluster connection , This is the beginning of the nightmare ,
Because I built it myself Redis The cluster has password authentication ,
therefore , Used Vert.x Different versions of the test cannot be connected , as it cannot be helped , Can only , Get rid of Redis Password authentication of the cluster ,
however ,3.8.x Still unable to connect ,
Last , Used 3.9.4, Successful connection , And completed successfully Redis operation ,
I'd like to share with you as follows , Help developers in need in the future .
important clause :
Vert.x edition :3.9.4
Measured in this paper : Monomers Redis And clusters Redis, And the test results are given ;
Because there is no sentinel environment , therefore , Sentinel mode is not tested , Although the connection example is given , But there are no test results .
2 Vert.x rely on
<!-- https://mvnrepository.com/artifact/io.vertx/vertx-core -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>3.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.vertx/vertx-redis-client -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-redis-client</artifactId>
<version>3.9.4</version>
</dependency>
3 Redis Address base
For unified management Redis Address , Use enumeration management ,
Add... Later Redis Connection configuration , Extract from this enumeration Library ,
The code is as follows :
package com.monkey.java_study.common.enums;
/** * Redis Address base . * * @author xindaqi * @since 2022-07-01 11:10 */
public enum RedisAddressEnum {
// Redis The cluster address
CLUSTER_NODE_1("redis://192.168.211.129:9001"),
CLUSTER_NODE_2("redis://192.168.211.129:9002"),
CLUSTER_NODE_3("redis://192.168.211.129:9003"),
CLUSTER_NODE_4("redis://192.168.211.129:9004"),
CLUSTER_NODE_5("redis://192.168.211.129:9005"),
CLUSTER_NODE_6("redis://192.168.211.129:9006"),
// stand-alone Redis Address
STANDALONE_NODE("redis://:[email protected]/0"),
;
private String address;
RedisAddressEnum(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
}
4 Redis colony
4.1 Configure the address and related parameters :RedisOptions
Vert.x 3.9.4 There are two ways to configure Redis Address ,
Respectively :addConnectionString and setEndpoints,
meanwhile , You can specify the connection type , Cluster is :RedisClientType.CLUSTER
Particular attention : When connecting in cluster mode , The cluster must not be configured with password authentication , Otherwise, you cannot connect to Redis colony
- addConnectionString The way
This way , Add addresses one by one . Address format :redis://ip:port
/** * Redis Cluster connection configuration :addConnectionString The way * * @return Redis Cluster configuration */
private static RedisOptions setClusterRedisAddressOneByOne() {
return new RedisOptions()
.setType(RedisClientType.CLUSTER)
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_1.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_2.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_3.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_4.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_5.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_6.getAddress());
}
- setEndpoints The way
Batch addition Redis Address ,endpoints The type ofList<String>
, Therefore, you can batch add .
/** * Redis Cluster connection configuration :setEndpoints The way * * @return Redis Cluster configuration */
private static RedisOptions setClusterRedisAddressBatch() {
List<String> redisAddressList = Stream.of(
RedisAddressEnum.CLUSTER_NODE_1.getAddress(),
RedisAddressEnum.CLUSTER_NODE_2.getAddress(),
RedisAddressEnum.CLUSTER_NODE_3.getAddress(),
RedisAddressEnum.CLUSTER_NODE_4.getAddress(),
RedisAddressEnum.CLUSTER_NODE_5.getAddress(),
RedisAddressEnum.CLUSTER_NODE_6.getAddress()).collect(Collectors.toList());
return new RedisOptions()
.setType(RedisClientType.CLUSTER)
.setEndpoints(redisAddressList);
}
4.2 Source code : Connection type
from Vert.x3.9.4 Source code is known ,Redis There are three types of client connections :STANDALONE( Monomers )、SENTINEL( sentry ) and CLUSTER( colony ),
The source code is shown in the figure below .
Location :io.vertx.redis.client.RedisClientType
4.3 Other default parameters
To configure Redis After the cluster connection address , You can connect directly Redis colony ,
because ,Vert.x3.9.4 At initialization , Default values are automatically configured , Such as :
maxWaitingHandler、maxPoolSize and maxPoolWaiting etc. , The source code is shown in the figure below ,
By default , Connect Redis The type of is monomer (RedisClientType.STANDALONE),
The default in sentinel mode is not to use the slave node :RedisSlaves.NEVER.
Location :io.vertx.redis.client.RedisOptions#init
Why are these parameters loaded , because ,RedisOptions Constructor for :
Location :io.vertx.redis.client.RedisOptions#RedisOptions()
4.4 establish Redis client
The creation example is as follows , By passing in Vertx.vertx() and redisOptions( The parameter object configured above ),
Can get Redis client , Getting the client is the same as Redis Establish a connection ,
Then you can finish CURD operation .
Redis.createClient(Vertx.vertx(), redisOptions);
4.5 Source code :Redis.createClient
Vert.x 3.9.4 establish Redis The client source code is shown in the figure below ,
We can know from the source code , The creation process will be based on type Choose different client types ( Monomers 、 Sentinels and groups ).
Location :io.vertx.redis.client.Redis#createClient(io.vertx.core.Vertx, io.vertx.redis.client.RedisOptions)
4.6 Redis operation :RedisAPI
Vert.x 3.9.4 adopt RedisAPI operation Redis data ,
The test sample is as follows , Use Vert.x You know , Asynchronous operations ,
therefore , Read data using Vetx.x threading :vert.x-eventloop-thread-0
/** * Read data from Redis * * @param redisClient Redis client * @param key Redis Key to query in */
public void readDataFromCluster(Redis redisClient, String key) {
RedisAPI redisAPI = RedisAPI.api(redisClient);
redisAPI.get(key, res -> {
if (res.succeeded()) {
String value = String.valueOf(res.result());
logger.info(">>>>>>>>Read data from redis cluster (key, value)->:({},{})", key, value);
} else {
logger.error(">>>>>>>>Redis cluster read data error:", res.cause());
}
});
}
4.7 Complete example
package com.monkey.java_study.thirdparty.vertx_test;
import com.monkey.java_study.common.enums.RedisAddressEnum;
import io.vertx.core.Vertx;
import io.vertx.redis.client.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** * Vert.x Connect Redis Cluster service and data reading test . * * @author xindaqi * @since 2022-06-30 12:16 */
public class VertxClusterOpRedisTest {
private static final Logger logger = LoggerFactory.getLogger(VertxClusterOpRedisTest.class);
/** * Redis Cluster clients */
private static final Redis redisClient;
/** * Redis Connection configuration */
private static final RedisOptions redisOptions;
static {
redisOptions = setClusterRedisAddressBatch();
redisClient = Redis.createClient(Vertx.vertx(), redisOptions);
}
/** * Redis Cluster connection configuration :addConnectionString The way * * @return Redis Cluster configuration */
private static RedisOptions setClusterRedisAddressOneByOne() {
return new RedisOptions()
.setType(RedisClientType.CLUSTER)
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_1.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_2.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_3.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_4.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_5.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_6.getAddress());
}
/** * Redis Cluster connection configuration :setEndpoints The way * * @return Redis Cluster configuration */
private static RedisOptions setClusterRedisAddressBatch() {
List<String> redisAddressList = Stream.of(
RedisAddressEnum.CLUSTER_NODE_1.getAddress(),
RedisAddressEnum.CLUSTER_NODE_2.getAddress(),
RedisAddressEnum.CLUSTER_NODE_3.getAddress(),
RedisAddressEnum.CLUSTER_NODE_4.getAddress(),
RedisAddressEnum.CLUSTER_NODE_5.getAddress(),
RedisAddressEnum.CLUSTER_NODE_6.getAddress()).collect(Collectors.toList());
return new RedisOptions()
.setType(RedisClientType.CLUSTER)
.setEndpoints(redisAddressList);
}
public Redis getRedisClient() {
return redisClient;
}
/** * Read data from Redis * * @param redisClient Redis client * @param key Redis Key to query in */
public void readDataFromCluster(Redis redisClient, String key) {
RedisAPI redisAPI = RedisAPI.api(redisClient);
redisAPI.get(key, res -> {
if (res.succeeded()) {
String value = String.valueOf(res.result());
logger.info(">>>>>>>>Read data from redis cluster (key, value)->:({},{})", key, value);
} else {
logger.error(">>>>>>>>Redis cluster read data error:", res.cause());
}
});
}
public static void main(String[] args) {
VertxClusterOpRedisTest vertxOpRedisTest = new VertxClusterOpRedisTest();
vertxOpRedisTest.readDataFromCluster(vertxOpRedisTest.getRedisClient(), "name");
}
}
4.8 test result
The test results show that ,Vert.x 3.9.4 operation Redis Using asynchronous threads :vert.x-enventloop-thread-0,
And finish reading the results .
5 Redis Monomers
With the foundation of the above cluster configuration ,
Configuring monomer connection and sentinel connection is relatively easy to understand ,
Give a complete example directly , The code is as follows :
It should be noted that : To configure Redis You need to configure the database as needed 0-15,
Connection type selection :RedisClientType.STANDALONE,
If it is a monomer, you can not choose , because RedisOptions The default value is :RedisClientType.STANDALONE.
Address format :redis://username:[email protected]:port/db
Parameter description :
Serial number | Parameters | describe |
---|---|---|
1 | username | No, you can leave it blank |
2 | password | Redis Connect the password , No, you can leave it blank |
3 | ip | Redis Running host IP |
4 | port | Redis port |
5 | db | Redis Database number ,0-15 One of them |
Specially :
If there is only password but no user name , It should be configured like this :redis://:[email protected]:port/db
5.1 Complete example
package com.monkey.java_study.thirdparty.vertx_test;
import com.monkey.java_study.common.enums.RedisAddressEnum;
import io.vertx.core.Vertx;
import io.vertx.redis.client.Redis;
import io.vertx.redis.client.RedisAPI;
import io.vertx.redis.client.RedisClientType;
import io.vertx.redis.client.RedisOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** * Vert.x Connect Redis Single service and data reading test . * * @author xindaqi * @since 2022-06-30 12:16 */
public class VertxStandaloneOpRedisTest {
private static final Logger logger = LoggerFactory.getLogger(VertxStandaloneOpRedisTest.class);
/** * Redis Monomer client */
private static final Redis redisClient;
/** * Redis Connection configuration */
private static final RedisOptions redisOptions;
static {
redisOptions = setStandaloneRedisAddress();
redisClient = Redis.createClient(Vertx.vertx(), redisOptions);
}
/** * To configure Redis Monomer connection address * * @return Redis Monomer configuration */
private static RedisOptions setStandaloneRedisAddress() {
return new RedisOptions()
.setType(RedisClientType.STANDALONE)
.addConnectionString(RedisAddressEnum.STANDALONE_NODE.getAddress());
}
public Redis getRedisClient() {
return redisClient;
}
/** * Read data from Redis * * @param redisClient Redis client * @param key Redis Key to query in */
public void readDataFromStandalone(Redis redisClient, String key) {
RedisAPI redisAPI = RedisAPI.api(redisClient);
redisAPI.get(key, res -> {
if (res.succeeded()) {
String value = String.valueOf(res.result());
logger.info(">>>>>>>>Read data from redis standalone (key, value)->:({},{})", key, value);
} else {
logger.error(">>>>>>>>Redis standalone read data error:", res.cause());
}
});
}
public static void main(String[] args) {
VertxStandaloneOpRedisTest vertxOpRedisTest = new VertxStandaloneOpRedisTest();
vertxOpRedisTest.readDataFromStandalone(vertxOpRedisTest.getRedisClient(), "name");
}
}
5.2 test result
6 Sentinel mode
Empathy , The complete example is as follows ,
It should be noted that , The type is configured as :RedisClientType.SENTINEL,
At the same time, you need to configure the name and role of the main service , namely
MasterName(“my_test”) and Role(RedisRole.MASTER),
Because there are no sentinels for testing Redis, therefore , Here is only a configuration example ,
There is no actual test .
package com.monkey.java_study.thirdparty.vertx_test;
import com.monkey.java_study.common.enums.RedisAddressEnum;
import io.vertx.core.Vertx;
import io.vertx.redis.client.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** * Vert.x Connect Redis Sentinel service and data reading test . * * @author xindaqi * @since 2022-06-30 12:16 */
public class VertxSentinelOpRedisTest {
private static final Logger logger = LoggerFactory.getLogger(VertxSentinelOpRedisTest.class);
/** * Redis Sentinel client */
private static final Redis redisClient;
/** * Redis Connection configuration */
private static final RedisOptions redisOptions;
static {
redisOptions = setSentinelRedisAddressOneByOne();
redisClient = Redis.createClient(Vertx.vertx(), redisOptions);
}
/** * Redis Sentry connection configuration :addConnectionString The way * * @return Redis Cluster configuration */
private static RedisOptions setSentinelRedisAddressOneByOne() {
return new RedisOptions()
.setType(RedisClientType.SENTINEL)
.setMasterName("my_test")
.setRole(RedisRole.MASTER)
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_1.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_2.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_3.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_4.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_5.getAddress())
.addConnectionString(RedisAddressEnum.CLUSTER_NODE_6.getAddress());
}
/** * Redis Sentry connection configuration :setEndpoints The way * * @return Redis Cluster configuration */
private static RedisOptions setSentinelRedisAddressBatch() {
List<String> redisAddressList = Stream.of(
RedisAddressEnum.CLUSTER_NODE_1.getAddress(),
RedisAddressEnum.CLUSTER_NODE_2.getAddress(),
RedisAddressEnum.CLUSTER_NODE_3.getAddress(),
RedisAddressEnum.CLUSTER_NODE_4.getAddress(),
RedisAddressEnum.CLUSTER_NODE_5.getAddress(),
RedisAddressEnum.CLUSTER_NODE_6.getAddress()).collect(Collectors.toList());
return new RedisOptions()
.setType(RedisClientType.SENTINEL)
.setMasterName("my_test")
.setRole(RedisRole.MASTER)
.setEndpoints(redisAddressList);
}
public Redis getRedisClient() {
return redisClient;
}
/** * Read data from Redis * * @param redisClient Redis client * @param key Redis Key to query in */
public void readDataFromSentinel(Redis redisClient, String key) {
RedisAPI redisAPI = RedisAPI.api(redisClient);
redisAPI.get(key, res -> {
if (res.succeeded()) {
String value = String.valueOf(res.result());
logger.info(">>>>>>>>Read data from redis sentinel (key, value)->:({},{})", key, value);
} else {
logger.error(">>>>>>>>Redis sentinel read data error:", res.cause());
}
});
}
public static void main(String[] args) {
VertxSentinelOpRedisTest vertxOpRedisTest = new VertxSentinelOpRedisTest();
vertxOpRedisTest.readDataFromSentinel(vertxOpRedisTest.getRedisClient(), "name");
}
}
7 Summary
Vert.x 3.9.4 Connect and operate Redis The core :
(1) To configure Redis Connection address , adopt RedisOptions, When instantiating this class , There are default parameters ;
(2)Vert.x3.9.4 Provided Redis The client cannot connect to the one that requires password authentication Redis colony , however , You can connect monomers that need password authentication Redis;
(3) Create a connection to use Redis.createClient, The method is based on type Select the corresponding Redis client : colony (cluster)、 sentry (sentinel) Monomer (standalone);
(4) operation Redis Use RedisAPI complete ;
(5)Vert.x operation Redis It is completed through asynchronous threads :Vert.x The thread of , Such as vert.x-eventloop-thread-0.
边栏推荐
- torch.nn.functional.interpolate函数
- 博途V16 获取系统时间转换成字符串
- Collation of open source protocols of open source frameworks commonly used in Web Development
- 音视频、编解码相关电子书、小工具,打包奉送!
- A brief understanding of white box encryption technology
- MFC中如何重绘CListCtrl的表头
- Collect Tiktok video
- 精耕渠道共謀發展 福昕攜手偉仕佳傑開展新產品培訓大會
- [pytorch record] distributed training dataparallel and distributeddataparallel of the model
- Write it down once Net travel management background CPU Explosion Analysis
猜你喜欢
Solidity - 合约结构 - 错误(error)- ^0.8.4版本新增
Actual combat of flutter - fast implementation of audio and video call application
赋能「新型中国企业」,SAP Process Automation 落地中国
Intensive cultivation of channels for joint development Fuxin and Weishi Jiajie held a new product training conference
DTD modeling
Nacos configuration file publishing failed, please check whether the parameters are correct solution
如何正确使用Vertx操作Redis(3.9.4带源码分析)
原生js打造日程表-支持鼠标滚轮滚动选择月份-可以移植到任何框架中
【森城市】GIS数据漫谈(一)
任务:拒绝服务DoS
随机推荐
论文泛读【FiLM: Visual Reasoning with a General Conditioning Layer】
Shell高级进阶
[info() method in org.slf4j.logger]
Contos 7 set up SFTP to create users, user groups, and delete users
线程的并行、并发、生命周期
A brief understanding of white box encryption technology
MFC中如何重绘CListCtrl的表头
The difference between indexof and includes
博途V16 获取系统时间转换成字符串
Lean thinking: source, pillar, landing. I understand it after reading this article
Ffmpeg audio related commands
Reading the paper [learning to discretely compose reasoning module networks for video captioning]
torch.nn.functional.interpolate函数
智慧防疫系统为建筑工地复工复产提供安全保障
音视频、编解码相关电子书、小工具,打包奉送!
【Go ~ 0到1 】 第四天 6月30 defer,结构体,方法
Solidity - contract structure - error - ^0.8.4 NEW
Native JS creates a calendar - supports mouse wheel scrolling to select months - and can be ported to any framework
[go ~ 0 to 1] day 4 June 30 defer, structure, method
EasyGBS网络不稳定情况下重复请求视频拉流问题的优化