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

Redis - 5 ( 18000 字 Redis 入门级教程 )

一: 补充知识

1.1 渐进式遍历

Redis 使用 scan 命令以渐进式方式遍历键,避免了直接使用 keys 命令可能引发的阻塞问题。scan 的时间复杂度为 O(1),但需要多次执行才能完成对所有键的遍历,整个过程分步进行,有效减少阻塞风险。首次执行时,scan 从游标 0 开始,当返回的下次游标为 0 时,遍历结束。每次执行 scan 会返回下次游标(cursor)和本次获取的键。不过,虽然 scan 的渐进式遍历解决了阻塞问题,但在遍历期间如果键发生变化(如增加、修改或删除),可能会导致键的重复遍历或遗漏,这一点需要在实际开发中加以考虑。

SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
2) "key:8"
3) "key:4"
4) "key:14"
5) "key:16"
6) "key:17"
7) "key:15"
8) "key:10"
9) "key:3"
10) "key:7"
11) "key:1"redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
2) "key:18"
3) "key:0"
4) "key:2"
5) "key:19"
6) "key:13"
7) "key:6"
8) "key:9"
9) "key:11"

在这里插入图片描述

1.2 数据库管理

Redis 提供了几个针对数据库操作的常用命令,包括 dbsize、select、flushdb 和 flushall。接下来将通过具体示例介绍这些命令的常见用法。

1.2.1 切换数据库

许多关系型数据库(如 MySQL)支持在一个实例下存在多个数据库,并通过字符区分数据库名称,而 Redis 则使用数字来区分数据库。Redis 默认配置中提供 16 个数据库,默认处于 0 号数据库。通过 select 0 可以切换到第一个数据库,而 select 15 则切换到最后一个数据库。不同数据库之间的数据是完全独立的,各自保存各自的键值对,互不冲突。

虽然 Redis 支持多数据库,但随着版本升级,官方并不推荐使用这一特性。如果需要完全隔离的两套键值对,更好的方案是维护多个 Redis 实例,而不是在一个实例中使用多个数据库。这是因为 Redis 对多数据库的支持较为有限,同时无论是否使用多数据库,Redis 都采用单线程模型,多个数据库之间仍需排队等待命令执行。此外,使用多数据库会增加开发、调试和运维的复杂性。因此,在实际应用中,始终使用默认的 0 号数据库通常是更好的选择。

select dbIndex

在这里插入图片描述

1.2.2 清除数据库

flushdb 和 flushall 命令用于清除数据库,区别在于 flushdb 仅清除当前数据库的数据,而 flushall 会清除所有数据库的数据。在实际应用中,除非必要,永远不要在生产环境中执行清除数据的操作,否则可能会导致严重后果。

二: 使用 Java 操作 redis 的客户端

在 Java 中操作 Redis 的客户端有很多,其中最常用且知名的是 Jedis。首先创建一个 Maven 项目,并将 Jedis 的依赖添加到 pom.xml 文件中:

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

2.1 配置端口转发

如果 Redis 服务器安装在云服务器上,而代码运行在本地主机上,为了让本地主机访问 Redis,需要在云服务器后台(如防火墙或安全组)开放 Redis 的端口到公网。但这种操作非常危险,因为可能会被黑客利用 Redis 端口入侵。为了解决这一问题,可以使用端口转发的方式,将服务器的 Redis 端口映射到本地。在 Xshell 中,可以通过相应配置实现这一功能,从而在保证安全的前提下访问远程 Redis 服务。

步骤操作说明
1右键选择云服务器的会话,点击“属性”。
2进入“隧道”选项卡,配置转发规则。
在这里插入图片描述

在这里插入图片描述

接着使用该会话连接服务器,此时访问本地的 8888 端口就相当于访问服务器的 6379 端口。需要注意的是,Xshell 必须与服务器保持连接状态,映射才能生效。

2.2 连接 Redis Server

步骤操作说明
1使用 JedisPool 描述 Redis 服务器的位置,并通过 URL 表示。
2使用 getResource 方法与 Redis 服务器建立连接。
3连接使用完毕后需要调用 close 方法关闭,或者直接使用 try 自动关闭连接。
4通过 ping 方法检测连接是否正确建立。
JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = jedisPool.getResource()) {String ping = jedis.ping(); // 这个方法会返回 PONGSystem.out.println(ping); // 输出 PONG
}

在这里插入图片描述

这个报错不影响使用,忽略即可,下面讲解一下 Java 操作 redis 的客户端的基本操作

2.3 set 和 get

当 key 不存在时,使用 get 方法获取的 value 将为 null。

public static void main(String[] args) {JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");try (Jedis jedis = jedisPool.getResource()) {testGetSet(jedis);jedis.flushDB(); // 清空数据库}
}private static void testGetSet(Jedis jedis) {jedis.set("key1", "value1"); // 设置 key1 的值为 value1jedis.set("key2", "value2"); // 设置 key2 的值为 value2String value1 = jedis.get("key1");System.out.println(value1); // 输出: value1String value2 = jedis.get("key2");System.out.println(value2); // 输出: value2String valueNull = jedis.get("noSuchKey");System.out.println(valueNull); // 输出: null
}

2.4 exists 和 del

del 方法可以删除多个 key,以可变参数列表的形式传入,返回值表示实际删除的 key 的数量。

private static void testExistsAndDel(Jedis jedis) {jedis.set("key1", "value"); // 设置 key1 的值为 valuejedis.set("key2", "value"); // 设置 key2 的值为 valuejedis.set("key3", "value"); // 设置 key3 的值为 valueboolean ret = jedis.exists("key1");System.out.println(ret); // 输出: true (key1 存在)long n = jedis.del("key1");System.out.println(n); // 输出: 1 (成功删除了 1 个 key)ret = jedis.exists("key1");System.out.println(ret); // 输出: false (key1 已被删除)n = jedis.del("key2", "key3");System.out.println(n); // 输出: 2 (成功删除了 2 个 key)ret = jedis.exists("key2");System.out.println(ret); // 输出: false (key2 已被删除)
}

2.5 keys

private static void testKeys(Jedis jedis) {jedis.set("key1", "value1"); // 设置 key1 的值为 value1jedis.set("key2", "value2"); // 设置 key2 的值为 value2jedis.set("key3", "value3"); // 设置 key3 的值为 value3jedis.set("myKey", "value4"); // 设置 myKey 的值为 value4Set<String> keys = jedis.keys("*");System.out.println(keys); // 输出: [key1, key2, key3, myKey] (匹配所有键)keys = jedis.keys("key?");System.out.println(keys); // 输出: [key1, key2, key3] (匹配 key 后面跟一个字符的键)
}

2.6 expire 和 ttl

使用 setex 方法可以在设置 key 的同时指定其过期时间,过期时间的单位为秒。

private static void testExpireAndTTL(Jedis jedis) {jedis.setex("key", 60, "value"); // 设置 key 的值为 value,并指定过期时间为 60 秒long ttl = jedis.ttl("key");System.out.println(ttl); // 输出: 剩余的过期时间,单位为秒(如:60,表示还有 60 秒过期)
}

2.7 type

private static void testType(Jedis jedis) {jedis.set("key1", "value"); // 设置 key1 的值为 valueSystem.out.println(jedis.type("key1")); // 输出: string (key1 是字符串类型)jedis.lpush("key2", "a", "b", "c"); // 向 key2 的列表中依次从左插入 a, b, cSystem.out.println(jedis.type("key2")); // 输出: list (key2 是列表类型)jedis.hset("key3", "name", "zhangsan"); // 设置 key3 的哈希字段 name 为 zhangsanSystem.out.println(jedis.type("key3")); // 输出: hash (key3 是哈希类型)jedis.sadd("key4", "111", "222", "333"); // 向 key4 的集合中添加 111, 222, 333System.out.println(jedis.type("key4")); // 输出: set (key4 是集合类型)jedis.zadd("key5", 1, "aaa"); // 向 key5 的有序集合中添加元素 aaa,分值为 1System.out.println(jedis.type("key5")); // 输出: zset (key5 是有序集合类型)
}

2.8 mget 和 mset

private static void testMSetAndMGet(Jedis jedis) {jedis.mset("key1", "value1", "key2", "value2", "key3", "value3"); // 批量设置 key-value 键值对List<String> values = jedis.mget("key1", "key2", "key3"); // 批量获取 key1, key2, key3 的值System.out.println(values); // 输出: [value1, value2, value3] (返回对应键的值列表)
}

2.9 append

private static void testAppend(Jedis jedis) {jedis.append("key", "aaa"); // 向 key 的值后追加字符串 aaaString value = jedis.get("key");System.out.println(value); // 输出: aaa (key 的当前值)jedis.append("key", "bbb"); // 向 key 的值后追加字符串 bbbvalue = jedis.get("key");System.out.println(value); // 输出: aaabbb (key 的当前值)
}

2.10 getrange 和 setrange

需要注意 getrange 方法的区间是闭区间

private static void testGetRangeAndSetRange(Jedis jedis) {jedis.set("key", "abcdefg"); // 设置 key 的值为 "abcdefg"String value = jedis.getrange("key", 1, 4); // 获取 key 的值中从索引 1 到 4 的子串(闭区间)System.out.println(value); // 输出: bcdejedis.setrange("key", 0, "xyz"); // 从索引 0 开始,用 "xyz" 替换 key 的值部分内容value = jedis.get("key");System.out.println(value); // 输出: xyzdefg
}

2.11 setnx

private static void testSetnx(Jedis jedis) {long n = jedis.setnx("key", "value"); // 如果 key 不存在,则设置 key 的值为 "value"System.out.println(n); // 输出: 1 (key 不存在,设置成功)String value = jedis.get("key");System.out.println(value); // 输出: value (当前 key 的值)n = jedis.setnx("key", "value2"); // 如果 key 已存在,不会修改值System.out.println(n); // 输出: 0 (key 已存在,设置失败)value = jedis.get("key");System.out.println(value); // 输出: value (key 的值仍为原来的值)
}

2.12 psetex

通过 pttl 获取的结果不一定正好是 1000 毫秒,因为 pttl 本身存在时间开销。

private static void testPsetexAndPttl(Jedis jedis) {jedis.psetex("key", 1000, "value"); // 设置 key 的值为 "value",并指定过期时间为 1000 毫秒long ttl = jedis.pttl("key"); // 获取 key 剩余的过期时间(单位:毫秒)System.out.println(ttl); // 输出: 一个接近 1000 的数值(因为存在时间开销,不一定正好是 1000)
}

2.13 incr 和 decr

private static void testIncrAndDecr(Jedis jedis) {jedis.set("key", "0"); // 设置 key 的初始值为 "0"jedis.incr("key"); // 将 key 的值自增 1System.out.println(jedis.get("key")); // 输出: 1 (当前 key 的值)jedis.decr("key"); // 将 key 的值自减 1System.out.println(jedis.get("key")); // 输出: 0 (当前 key 的值)
}

2.14 incrby 和 decrby

private static void testIncrByAndDecrBy(Jedis jedis) {jedis.set("key", "0"); // 设置 key 的初始值为 "0"jedis.incrBy("key", 10); // 将 key 的值增加 10System.out.println(jedis.get("key")); // 输出: 10 (当前 key 的值)jedis.decrBy("key", 5); // 将 key 的值减少 5System.out.println(jedis.get("key")); // 输出: 5 (当前 key 的值)
}

2.15 lpush 和 lpop

private static void testLpushAndLpop(Jedis jedis) {long n = jedis.lpush("key", "1", "2", "3", "4"); // 从左侧依次插入 4, 3, 2, 1System.out.println(n); // 输出: 4 (列表中元素的总数量)String value = jedis.lpop("key"); // 从左侧弹出第一个元素System.out.println(value); // 输出: 4 (第一个弹出的元素)value = jedis.lpop("key"); // 弹出下一个元素System.out.println(value); // 输出: 3value = jedis.lpop("key"); // 弹出下一个元素System.out.println(value); // 输出: 2value = jedis.lpop("key"); // 弹出下一个元素System.out.println(value); // 输出: 1value = jedis.lpop("key"); // 列表为空时,再次弹出System.out.println(value); // 输出: null (列表为空)
}

2.16 rpush 和 rpop

private static void testRpushAndRpop(Jedis jedis) {long n = jedis.rpush("key", "1", "2", "3", "4"); // 从右侧依次插入 1, 2, 3, 4System.out.println(n); // 输出: 4 (列表中元素的总数量)String value = jedis.rpop("key"); // 从右侧弹出第一个元素System.out.println(value); // 输出: 4 (第一个弹出的元素)value = jedis.rpop("key"); // 弹出下一个元素System.out.println(value); // 输出: 3value = jedis.rpop("key"); // 弹出下一个元素System.out.println(value); // 输出: 2value = jedis.rpop("key"); // 弹出下一个元素System.out.println(value); // 输出: 1value = jedis.rpop("key"); // 列表为空时,再次弹出System.out.println(value); // 输出: null (列表为空)
}

2.17 lrange

private static void testLrange(Jedis jedis) {jedis.rpush("key", "1", "2", "3", "4"); // 从右侧依次插入 1, 2, 3, 4List<String> values = jedis.lrange("key", 1, 3); // 获取列表中从索引 1 到 3 的元素(闭区间)System.out.println(values); // 输出: [2, 3, 4] (索引范围内的元素)
}

2.18 blpop

blpop 返回的结果是一个二元组形式的 List,其中索引 [0] 表示 key,索引 [1] 表示 value。将超时时间设置为 0 表示阻塞等待,直到有数据可弹出。在执行 blpop 的同时,可以通过另一个 redis-cli 客户端插入数据,便可实时查看 blpop 的返回结果。

private static void testBLpop(Jedis jedis) {while (true) {List<String> values = jedis.blpop(0, "key"); // 阻塞等待,从列表 key 中弹出第一个元素System.out.println(values); // 输出: [key, value] (返回包含 key 和弹出的值的二元组)}
}

2.19 brpop

private static void testBRpop(Jedis jedis) {System.out.println("开始调用 brpop"); // 提示 brpop 调用开始while (true) {List<String> values = jedis.brpop(0, "key"); // 阻塞等待,从列表 key 中从右侧弹出元素System.out.println(values); // 输出: [key, value] (返回包含 key 和弹出的值的二元组)}
}

2.20 lindex

private static void testLindex(Jedis jedis) {jedis.rpush("key", "1", "2", "3", "4"); // 从右侧依次插入 1, 2, 3, 4String value = jedis.lindex("key", 2); // 获取列表 key 中索引为 2 的元素System.out.println(value); // 输出: 3 (索引 2 对应的元素)
}

2.21linsert

linsert 方法通过指定插入位置标识 ListPosition.BEFORE 或 ListPosition.AFTER,决定新元素是插入到目标元素之前还是之后。

private static void testLinsert(Jedis jedis) {jedis.rpush("key", "a", "b", "c", "d"); // 从右侧依次插入 a, b, c, djedis.linsert("key", ListPosition.BEFORE, "c", "100"); // 在元素 c 之前插入 100List<String> values = jedis.lrange("key", 0, -1); // 获取列表 key 中所有元素System.out.println(values); // 输出: [a, b, 100, c, d] (列表中插入后的结果)
}

2.22 llen

private static void testLlen(Jedis jedis) {jedis.rpush("key", "a", "b", "c", "d"); // 从右侧依次插入 a, b, c, dlong n = jedis.llen("key"); // 获取列表 key 的长度System.out.println(n); // 输出: 4 (列表中元素的总数量)
}

2.23 hset 和 hget

private static void testHsetAndHget(Jedis jedis) {jedis.hset("key", "name", "zhangsan"); // 设置哈希表 key 中字段 name 的值为 zhangsanjedis.hset("key", "age", "20"); // 设置哈希表 key 中字段 age 的值为 20String name = jedis.hget("key", "name"); // 获取哈希表 key 中字段 name 的值System.out.println(name); // 输出: zhangsanString age = jedis.hget("key", "age"); // 获取哈希表 key 中字段 age 的值System.out.println(age); // 输出: 20
}

2.24 hexists 和 hdel

private static void testHexistsAndHdel(Jedis jedis) {jedis.hset("key", "name", "zhangsan"); // 设置哈希表 key 中字段 name 的值为 zhangsanboolean ok = jedis.hexists("key", "name"); // 检查哈希表 key 中是否存在字段 nameSystem.out.println(ok); // 输出: true (字段 name 存在)jedis.hdel("key", "name"); // 删除哈希表 key 中字段 nameok = jedis.hexists("key", "name"); // 再次检查哈希表 key 中是否存在字段 nameSystem.out.println(ok); // 输出: false (字段 name 已被删除)
}

2.25 hkeys 和 hvals

private static void testHkeysAndHvalues(Jedis jedis) {jedis.hset("key", "name", "zhangsan"); // 设置哈希表 key 中字段 name 的值为 zhangsanjedis.hset("key", "age", "20"); // 设置哈希表 key 中字段 age 的值为 20Set<String> keys = jedis.hkeys("key"); // 获取哈希表 key 中所有字段名System.out.println(keys); // 输出: [name, age] (哈希表中的字段名集合)List<String> values = jedis.hvals("key"); // 获取哈希表 key 中所有字段的值System.out.println(values); // 输出: [zhangsan, 20] (哈希表中的字段值集合)
}

2.26 hmget

private static void testHmget(Jedis jedis) {jedis.hset("key", "name", "zhangsan"); // 设置哈希表 key 中字段 name 的值为 zhangsanjedis.hset("key", "age", "20"); // 设置哈希表 key 中字段 age 的值为 20List<String> values = jedis.hmget("key", "name", "age"); // 批量获取哈希表 key 中字段 name 和 age 的值System.out.println(values); // 输出: [zhangsan, 20] (字段对应的值集合)
}

2.27 hlen

private static void testHlen(Jedis jedis) {jedis.hset("key", "name", "zhangsan"); // 设置哈希表 key 中字段 name 的值为 zhangsanjedis.hset("key", "age", "20"); // 设置哈希表 key 中字段 age 的值为 20long n = jedis.hlen("key"); // 获取哈希表 key 中字段的数量System.out.println(n); // 输出: 2 (字段的总数量)
}

2.28 hincrby 和 hincrbyfloat

private static void testHIncrByAndIncrByFloat(Jedis jedis) {jedis.hset("key", "age", "20"); // 设置哈希表 key 中字段 age 的值为 20long n = jedis.hincrBy("key", "age", 10); // 将哈希表 key 中字段 age 的值增加 10System.out.println(n); // 输出: 30 (增加后的值)String value = jedis.hget("key", "age"); // 获取哈希表 key 中字段 age 的值System.out.println(value); // 输出: 30double dn = jedis.hincrByFloat("key", "age", 0.5); // 将哈希表 key 中字段 age 的值增加 0.5System.out.println(dn); // 输出: 30.5 (增加后的值)value = jedis.hget("key", "age"); // 再次获取哈希表 key 中字段 age 的值System.out.println(value); // 输出: 30.5
}

2.29 sadd 和 smembers

private static void testSaddAndSmembers(Jedis jedis) {jedis.sadd("key", "aaa", "bbb", "ccc"); // 向集合 key 中添加元素 aaa, bbb, cccSet<String> members = jedis.smembers("key"); // 获取集合 key 中的所有成员System.out.println(members); // 输出: [aaa, bbb, ccc] (集合中的所有成员,顺序可能无序)
}

2.30 srem 和 sismember

private static void testSremAndSismember(Jedis jedis) {jedis.sadd("key", "aaa", "bbb", "ccc"); // 向集合 key 中添加元素 aaa, bbb, cccboolean ok = jedis.sismember("key", "aaa"); // 检查集合 key 中是否包含元素 aaaSystem.out.println(ok); // 输出: true (aaa 存在于集合中)long n = jedis.srem("key", "aaa", "bbb"); // 从集合 key 中删除元素 aaa 和 bbbSystem.out.println(n); // 输出: 2 (成功删除的元素个数)ok = jedis.sismember("key", "aaa"); // 再次检查集合 key 中是否包含元素 aaaSystem.out.println(ok); // 输出: false (aaa 已被删除)
}

2.31 scard

private static void testScard(Jedis jedis) {jedis.sadd("key", "aaa", "bbb", "ccc"); // 向集合 key 中添加元素 aaa, bbb, ccclong n = jedis.scard("key"); // 获取集合 key 中的元素数量System.out.println(n); // 输出: 3 (集合中元素的总数量)
}

2.32 sinter

private static void testSinter(Jedis jedis) {jedis.sadd("key1", "aaa", "bbb", "ccc"); // 向集合 key1 中添加元素 aaa, bbb, cccjedis.sadd("key2", "aaa", "bbb", "ddd"); // 向集合 key2 中添加元素 aaa, bbb, dddSet<String> results = jedis.sinter("key1", "key2"); // 获取 key1 和 key2 的交集System.out.println(results); // 输出: [aaa, bbb] (两个集合的交集元素)
}

2.33 sunion

private static void testSunion(Jedis jedis) {jedis.sadd("key1", "aaa", "bbb", "ccc"); // 向集合 key1 中添加元素 aaa, bbb, cccjedis.sadd("key2", "aaa", "bbb", "ddd"); // 向集合 key2 中添加元素 aaa, bbb, dddSet<String> results = jedis.sunion("key1", "key2"); // 获取 key1 和 key2 的并集System.out.println(results); // 输出: [aaa, bbb, ccc, ddd] (两个集合的并集元素)
}

2.34 sdiff

private static void testSdiff(Jedis jedis) {jedis.sadd("key1", "aaa", "bbb", "ccc"); // 向集合 key1 中添加元素 aaa, bbb, cccjedis.sadd("key2", "aaa", "bbb", "ddd"); // 向集合 key2 中添加元素 aaa, bbb, dddSet<String> results = jedis.sdiff("key1", "key2"); // 获取 key1 和 key2 的差集 (key1 中有但 key2 中没有的元素)System.out.println(results); // 输出: [ccc] (key1 中独有的元素)
}

2.35 zadd 和 zrange

private static void testZaddAndZrange(Jedis jedis) {jedis.zadd("key", 100, "吕布"); // 向有序集合 key 中添加成员 吕布,分值为 100jedis.zadd("key", 98, "赵云"); // 向有序集合 key 中添加成员 赵云,分值为 98jedis.zadd("key", 95, "典韦"); // 向有序集合 key 中添加成员 典韦,分值为 95jedis.zadd("key", 92, "关羽"); // 向有序集合 key 中添加成员 关羽,分值为 92jedis.zadd("key", 70, "刘备"); // 向有序集合 key 中添加成员 刘备,分值为 70List<String> members = jedis.zrange("key", 0, 4); // 获取 key 中索引范围 0 到 4 的成员System.out.println(members); // 输出: [刘备, 关羽, 典韦, 赵云, 吕布] (按照分值从低到高排序的成员)List<Tuple> membersWithScore = jedis.zrangeWithScores("key", 0, 4); // 获取 key 中索引范围 0 到 4 的成员及其分值System.out.println(membersWithScore); // 输出: [刘备=70.0, 关羽=92.0, 典韦=95.0, 赵云=98.0, 吕布=100.0]
}

2.36 zrem 和 zcard

private static void testZremAndZcard(Jedis jedis) {jedis.zadd("key", 100, "吕布"); // 向有序集合 key 中添加成员 吕布,分值为 100jedis.zadd("key", 98, "赵云"); // 向有序集合 key 中添加成员 赵云,分值为 98jedis.zadd("key", 95, "典韦"); // 向有序集合 key 中添加成员 典韦,分值为 95jedis.zadd("key", 92, "关羽"); // 向有序集合 key 中添加成员 关羽,分值为 92jedis.zadd("key", 70, "刘备"); // 向有序集合 key 中添加成员 刘备,分值为 70long n = jedis.zcard("key"); // 获取有序集合 key 中的成员数量System.out.println(n); // 输出: 5 (集合中总的成员数量)n = jedis.zrem("key", "吕布", "赵云"); // 从有序集合 key 中移除成员 吕布 和 赵云System.out.println(n); // 输出: 2 (成功移除的成员数量)n = jedis.zcard("key"); // 再次获取有序集合 key 中的成员数量System.out.println(n); // 输出: 3 (移除成员后的总数量)
}

2.37 zcount

private static void testZcount(Jedis jedis) {jedis.zadd("key", 100, "吕布"); // 向有序集合 key 中添加成员 吕布,分值为 100jedis.zadd("key", 98, "赵云"); // 向有序集合 key 中添加成员 赵云,分值为 98jedis.zadd("key", 95, "典韦"); // 向有序集合 key 中添加成员 典韦,分值为 95jedis.zadd("key", 92, "关羽"); // 向有序集合 key 中添加成员 关羽,分值为 92jedis.zadd("key", 70, "刘备"); // 向有序集合 key 中添加成员 刘备,分值为 70long n = jedis.zcount("key", 92, 98); // 获取分值在 92 到 98 范围内的成员数量,闭区间System.out.println(n); // 输出: 3 (关羽、典韦、赵云 分值在该范围内)
}

2.38 zpopmax 和 zpopmin

private static void testZpopmaxAndZpopmin(Jedis jedis) {jedis.zadd("key", 100, "吕布"); // 向有序集合 key 中添加成员 吕布,分值为 100jedis.zadd("key", 98, "赵云"); // 向有序集合 key 中添加成员 赵云,分值为 98jedis.zadd("key", 95, "典韦"); // 向有序集合 key 中添加成员 典韦,分值为 95jedis.zadd("key", 92, "关羽"); // 向有序集合 key 中添加成员 关羽,分值为 92jedis.zadd("key", 70, "刘备"); // 向有序集合 key 中添加成员 刘备,分值为 70Tuple tuple = jedis.zpopmax("key"); // 弹出有序集合 key 中分值最高的成员System.out.println(tuple); // 输出: 吕布=100.0 (分值最高的成员及其分值)tuple = jedis.zpopmin("key"); // 弹出有序集合 key 中分值最低的成员System.out.println(tuple); // 输出: 刘备=70.0 (分值最低的成员及其分值)
}

2.39 zrank

private static void testZrank(Jedis jedis) {jedis.zadd("key", 100, "吕布"); // 向有序集合 key 中添加成员 吕布,分值为 100jedis.zadd("key", 98, "赵云"); // 向有序集合 key 中添加成员 赵云,分值为 98jedis.zadd("key", 95, "典韦"); // 向有序集合 key 中添加成员 典韦,分值为 95jedis.zadd("key", 92, "关羽"); // 向有序集合 key 中添加成员 关羽,分值为 92jedis.zadd("key", 70, "刘备"); // 向有序集合 key 中添加成员 刘备,分值为 70long n = jedis.zrank("key", "赵云"); // 获取成员 赵云 在有序集合 key 中的排名(从低到高)System.out.println(n); // 输出: 3 (赵云 的排名,从 0 开始)n = jedis.zrevrank("key", "赵云"); // 获取成员 赵云 在有序集合 key 中的排名(从高到低)System.out.println(n); // 输出: 1 (赵云 的排名,从 0 开始)
}

2.40 zscore

private static void testZscore(Jedis jedis) {jedis.zadd("key", 100, "吕布"); // 向有序集合 key 中添加成员 吕布,分值为 100jedis.zadd("key", 98, "赵云"); // 向有序集合 key 中添加成员 赵云,分值为 98jedis.zadd("key", 95, "典韦"); // 向有序集合 key 中添加成员 典韦,分值为 95jedis.zadd("key", 92, "关羽"); // 向有序集合 key 中添加成员 关羽,分值为 92jedis.zadd("key", 70, "刘备"); // 向有序集合 key 中添加成员 刘备,分值为 70double score = jedis.zscore("key", "赵云"); // 获取成员 赵云 在有序集合 key 中的分值System.out.println(score); // 输出: 98.0 (赵云 的分值)
}

2.41 zincrby

private static void testZincrby(Jedis jedis) {jedis.zadd("key", 100, "吕布"); // 向有序集合 key 中添加成员 吕布,分值为 100double n = jedis.zincrby("key", 10, "吕布"); // 增加成员 吕布 的分值 10System.out.println(n); // 输出: 110.0 (吕布 的新分值)n = jedis.zincrby("key", -20, "吕布"); // 减少成员 吕布 的分值 20System.out.println(n); // 输出: 90.0 (吕布 的新分值)
}

2.42 zinterstore

private static void testZinterstore(Jedis jedis) {jedis.zadd("key1", 100, "吕布"); // 向有序集合 key1 中添加成员 吕布,分值为 100jedis.zadd("key1", 98, "赵云"); // 向有序集合 key1 中添加成员 赵云,分值为 98jedis.zadd("key1", 95, "典韦"); // 向有序集合 key1 中添加成员 典韦,分值为 95jedis.zadd("key2", 100, "吕布"); // 向有序集合 key2 中添加成员 吕布,分值为 100jedis.zadd("key2", 98, "赵云"); // 向有序集合 key2 中添加成员 赵云,分值为 98jedis.zadd("key2", 92, "关羽"); // 向有序集合 key2 中添加成员 关羽,分值为 92long n = jedis.zinterstore("key3", "key1", "key2"); // 将 key1 和 key2 的交集存储到 key3 中System.out.println(n); // 输出: 2 (交集中成员的数量)List<Tuple> tuples = jedis.zrangeWithScores("key3", 0, -1); // 获取 key3 中的所有成员及其分值System.out.println(tuples); // 输出: [赵云=196.0, 吕布=200.0] (交集成员及其分值)
}

2.43 zunionstore

private static void testZunionstore(Jedis jedis) {jedis.zadd("key1", 100, "吕布"); // 向有序集合 key1 中添加成员 吕布,分值为 100jedis.zadd("key1", 98, "赵云"); // 向有序集合 key1 中添加成员 赵云,分值为 98jedis.zadd("key1", 95, "典韦"); // 向有序集合 key1 中添加成员 典韦,分值为 95jedis.zadd("key2", 100, "吕布"); // 向有序集合 key2 中添加成员 吕布,分值为 100jedis.zadd("key2", 98, "赵云"); // 向有序集合 key2 中添加成员 赵云,分值为 98jedis.zadd("key2", 92, "关羽"); // 向有序集合 key2 中添加成员 关羽,分值为 92long n = jedis.zunionstore("key3", "key1", "key2"); // 将 key1 和 key2 的并集存储到 key3 中System.out.println(n); // 输出: 4 (并集中成员的数量)List<Tuple> tuples = jedis.zrangeWithScores("key3", 0, -1); // 获取 key3 中的所有成员及其分值System.out.println(tuples); // 输出: [典韦=95.0, 关羽=92.0, 赵云=196.0, 吕布=200.0] (并集成员及其分值)
}

三: 访问集群

使用 JedisCluster 类可以访问 Redis 集群,替代单节点模式下使用的 Jedis 类。在创建 JedisCluster 实例时,需要将多个节点的地址配置进去。JedisCluster 提供的方法与 Jedis 基本一致,都与 Redis 命令一一对应,具体使用细节此处不再演示。

public static void main(String[] args) {// 创建一个存储 Redis 集群节点的集合Set<HostAndPort> nodes = new HashSet<>();nodes.add(new HostAndPort("172.30.0.101", 6379));nodes.add(new HostAndPort("172.30.0.102", 6379));nodes.add(new HostAndPort("172.30.0.103", 6379));nodes.add(new HostAndPort("172.30.0.104", 6379));nodes.add(new HostAndPort("172.30.0.105", 6379));nodes.add(new HostAndPort("172.30.0.106", 6379));nodes.add(new HostAndPort("172.30.0.107", 6379));nodes.add(new HostAndPort("172.30.0.108", 6379));nodes.add(new HostAndPort("172.30.0.109", 6379));// 创建 JedisCluster 实例并执行操作try (JedisCluster jedisCluster = new JedisCluster(nodes)) {jedisCluster.set("k1", "111"); // 设置键 k1 的值为 111String value = jedisCluster.get("k1"); // 获取键 k1 的值System.out.println(value); // 输出: 111}
}

注意,由于代码需要访问整个 Redis 集群,Windows 主机无法直接访问 Docker 容器的 IP 地址,因此无法在 Windows 上直接运行程序。需要将程序打包成 JAR 文件,上传到 Linux 环境中,并在 Linux 上运行程序以实现对 Redis 集群的访问。

java -jar [jar包名]

http://www.mrgr.cn/news/82377.html

相关文章:

  • FreeRTOS Lwip Socket APi TCP Server 1对多
  • Conda清理缓存
  • 【74HC192减法24/20/72进制】2022-5-17
  • HTML——20 自定义属性
  • Vue项目整合与优化
  • linux的线程同步(条件变量和锁)
  • @Cacheable 注解爆红(不兼容的类型。实际为 java. lang. String‘,需要 ‘boolean‘)
  • 如何在notepad++里面,修改注释颜色
  • 2021年福建公务员考试申论试题(县级卷)
  • 4.Web安全——JavaScript基础
  • Unity2022接入Google广告与支付SDK、导出工程到Android Studio使用JDK17进行打包完整流程与过程中的相关错误及处理经验总结
  • BGP(Border Gateway Protocol)路由收集器
  • Python 数据可视化的完整指南
  • 拼多多手势验证码/某多多手势验证码
  • vscode,eslint的报错影响编译
  • 基于VSCode软件框架的RISC-V IDE MRS2正式上线发布
  • python: generate model and DAL using Oracle
  • 25年1月更新。Windows 上搭建 Python 开发环境:PyCharm 安装全攻略(文中有安装包不用官网下载)
  • 行为模式2.命令模式------灯的开关
  • 【数据库系统概论】绪论--复习
  • STM32 拓展 电源控制
  • 实际开发中,常见pdf|word|excel等文件的预览和下载
  • 前言(1)
  • flink cdc oceanbase(binlog模式)
  • 二、AI知识(神经网络)
  • Speedtest 测试客户的上/下行带宽