当前位置: 首页 > article >正文

java使用jedis连接redis

在 Java 中操作 Redis 通常使用 Jedis 或 Lettuce 这两个库。Jedis简单易用,适合大部分使用场景,Lettuce支持异步和反应式编程,适合需要高并发和非阻塞操作的应用。这里使用jedis来连接redis操作。

添加依赖

    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>3.6.3</version>
    </dependency>

使用jedis操作redis和使用jdbc操作数据库差不多,jedis将redis的命令行操作指令都封装到一个Jedis类里。操作方法名也基本上和redis的命令行命令相同。

获取Jedis对象

获取Jedis对象可以直接通过其构造函数获取连接

Jedis jedis = new Jedis("localhost",6379);

熟悉数据库jdbc操作的肯定知道,在实际使用中一般对应这种数据库连接使用连接池,来提高操作效率。jedis也有对应的JedisPool来创建连接池。

JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(3);
config.setMinIdle(1);
config.setMaxTotal(5);

JedisPool pool = new JedisPool(config,"localhost", 6379, 3000, null);
Jedis jedis = pool.getResource();

连接池和其它连接池一样,有最大连接数、空闲数等几个固定参数配置。

基本数据类型操作

jedis封装的操作方法基本上和redis 命令行命令是一一对应,还是来简单看下基本操作

String

//设置key
jedis.set("name","hello");
//获取key
System.out.println(jedis.get("name"));
//设置一个不存在的key
Long setnx = jedis.setnx("22222", "1");

List

//添加元素
jedis.lpush("lang","java");
jedis.lpush("lang","c","python","go","php","js");
//获取元素
System.out.println(jedis.lpop("lang"));
//根据范围获取元素列表
List<String> list = jedis.lrange("lang", 0, 2);
System.out.println(list);

Hash

//设置元素
jedis.hset("user:001","name","test01");
jedis.hset("user:001","code","001");

jedis.hset("user:002",new HashMap<String, String>(){{
put("name","test02");
put("code","002");
put("date","2024-09-04");
}}
);
//获取元素
System.out.println(jedis.hget("user:002","name"));
//删除某个属性
Long hdel = jedis.hdel("user:002", "date");

Set

//添加元素
jedis.sadd("color",new String[]{"red","blue","green"});
jedis.sadd("color","yellow");
//集合中元素数量
System.out.println(jedis.scard("color"));
//元素是否在集合中
System.out.println(jedis.sismember("color","pink"));
//从集合中取指定数量的元素
List<String> color1 = jedis.srandmember("color", 1);
System.out.println(jedis.spop("color"));;
//取集合所有元素
Set<String> color = jedis.smembers("color");
System.out.println(color);

Sorted Set

//添加元素
jedis.zadd("zset",1,"one");
jedis.zadd("zset",2,"two");
jedis.zadd("zset",new HashMap<String,Double>(){{
put("three",3d);
put("four",4d);
}});
//获取元素
Set<String> zset = jedis.zrange("zset", 0, 2);
System.out.println(zset);
连接sentinel
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(3);
config.setMinIdle(1);
config.setMaxTotal(5);

String masterName = "";
Set<String> stlSet = new HashSet<>(){{
add(new HostAndPort("127.0.0.1",26379).toString()) ;
add(new HostAndPort("127.0.0.1",26380).toString()) ;
add(new HostAndPort("127.0.0.1",26381).toString()) ;
}};

JedisSentinelPool pool = new JedisSentinelPool(masterName,stlSet,config,3000,null);
Jedis jedis = pool.getResource();

使用上面的数据连接池来进行数据操作

Jedis jedis = pool.getResource();
System.out.println(jedis.get("name"));
try {
Thread.sleep(1000000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
jedis.close();
pool.close();

这里线程暂停一下,然后在服务器上查看连接信息,客户端ip是192.168.1.101

# netstat -anp|grep '192.168.1.101'
tcp        0      0 172.31.164.136:26381    192.168.1.101:4077    ESTABLISHED 336/./src/redis-sen
tcp        0      0 172.31.164.136:26380    192.168.1.101:36303   ESTABLISHED 327/./src/redis-sen
tcp        0      0 172.31.164.136:26382    192.168.1.101:2049    ESTABLISHED 345/./src/redis-sen
tcp        0      0 172.31.164.136:6381     192.168.1.101:15977   ESTABLISHED 32080/./src/redis-s

这里看到客户端程序和sentinel三个端口服务(26380,26381,26382)建立了连接,这是没问题的。然后还有一条6381的连接,6381是master节点的服务端口。也就是Sentinel 实例负责监控 Redis 集群中的 master 和 slave 节点,Sentinel 实例负责监控 Redis 集群中的 master 和 slave 节点。客户端根据 Sentinel 提供的 master 节点信息,与 master 节点建立连接。所有读写操作都会通过这个连接进行。

下面来模拟一个故障转移例子:

1、首先客户端使用循环不断从连接池中获取连接执行操作

        while (true){
            Jedis jedis = pool.getResource();
            System.out.println(jedis.get("name"));
            System.out.println("server信息:"+jedis.getClient().getHost()+":"+jedis.getClient().getPort());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }
            jedis.close();
        }

2、看下此时的sentinel状态

127.0.0.1:26381> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.101:6382,slaves=2,sentinels=3

这个时候主节点是6382,状态是ok

3、启动客户端程序

观察日志信息

server信息:192.168.1.101:6382
server信息:192.168.1.101:6382
server信息:192.168.1.101:6382
server信息:192.168.1.101:6382

这里一切正常,连接的是master 6382。

4、停止master

./src/redis-cli -p 6382
127.0.0.1:6382> shutdown

先观察服务器sentinel状态

127.0.0.1:26381> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.101:6382,slaves=2,sentinels=3

127.0.0.1:26381> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=sdown,address=192.168.1.101:6382,slaves=2,sentinels=3
127.0.0.1:26381> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=odown,address=192.168.1.101:6382,slaves=2,sentinels=3
127.0.0.1:26381> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.101:6380,slaves=2,sentinels=3

这里看下master的状态。首先原主节点6382经历了sdown和odown两个状态。

sdown:(Subjectively Down)主观下线。当一个 Redis Sentinel 实例检测到主节点可能出现了问题时,它将主节点标记为 sdown。这表示 Sentinel 对主节点的状态有怀疑,但还没有确认。此时,Sentinel 会继续监控主节点,并试图获取更多的确认信息。

odown:(Objectively Down)客观下线。当达到配置中的 quorum(即至少有足够多的 Sentinel 实例)确认主节点真的不可用时,主节点会被标记为 odownodown 状态是经过多个 Sentinel 实例确认的客观下线状态。此时,Sentinel 会触发故障转移流程。

故障转移之后选择了6380作为master。

客户端

在停掉原master后,客户端会有一段时间无法获取连接,Connection refused。等到故障转移之后自动连接到新master 6380上。

连接cluster

使用jedis提供的JedisCluster对象来操作cluster

JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(3);
config.setMinIdle(1);
config.setMaxTotal(5);

String host = "192.168.1.101";
Set<HostAndPort> clusterNodes = new HashSet<HostAndPort>(){{
  add(new HostAndPort(host,7001));
  add(new HostAndPort(host,7002));
  add(new HostAndPort(host,7003));
}};

JedisCluster cluster = new JedisCluster(clusterNodes,5000,10000,3,null,config);
System.out.println(cluster.get("name"));

http://www.kler.cn/a/292562.html

相关文章:

  • [JAVAEE] 面试题(四) - 多线程下使用ArrayList涉及到的线程安全问题及解决
  • 高效稳定!新加坡服务器托管方案助力企业全球化布局
  • Cyberchef配合Wireshark提取并解析HTTP/TLS流量数据包中的文件
  • 【自用】0-1背包问题与完全背包问题的Java实现
  • Linux 函数在多个地方被同时调用时,函数中的变量如何管理,确保互不影响
  • MacOS 本地生成SSH key并关联Github
  • Mac剪贴板管理器:扩展你的复制粘贴能力
  • 卷积公式的几何学理解
  • 硬件工程师笔试面试——继电器
  • windows清理图标缓存
  • 如何实现对窗口window的viewtree进行dump Hierarchy-安卓framework实战开发
  • HarmonyOS开发实战( Beta5版)状态管理优秀实践
  • 二、搭建网站服务器超详细步骤——部署轻量应用服务器(Centos)
  • ceph中pg与pool关系
  • SQL常见100面试题解析
  • vs2019编译opencv+contribute+gpu
  • 【华为OD】2024D卷——查找众数与中位数
  • MacBook真的不能打游戏吗?Mac打游戏会损坏电脑吗?苹果电脑怎么玩游戏
  • 如何在 Java 中实现线程安全的单例模式?
  • 前端宝典二十七:React Native最佳实践实例推荐
  • 强化网络安全:通过802.1X协议保障远程接入设备安全认证
  • 迭代器 Iterator 是什么?
  • Linux修改docker默认存储目录(/var/lib)
  • Twitter上品牌安全指标的关键显示错误已修正
  • 2024跨境旺季营销:哪个平台是流量之王?
  • Ribbon负载均衡底层原理