可以检索在 redis-cli 中手动设置的值,但无法通过 Spring Boot 中的 Redis Reactive 设置新键
Can retrieve values manually set in redis-cli but unable to set new keys through Redis Reactive in Spring Boot
我正在使用Spring Webflux + Reactive Redis,我的目标是将Redis用作文件缓存。
一开始我试图用 ~100MB 的 ByteBuffer 设置一个密钥,但没有成功。我用调试器仔细检查以确保文件确实被读入内存,而且确实如此。我想“也许 Redis 不喜欢“大”字符串?”所以我尝试了下面的代码,仍然没有骰子。以为这可能是与 ACL 相关的问题,但我检查了一下,默认用户可以访问所有内容。 “也许 Spring 无法访问 Redis?”不,我检查了 redis-cli 中的 MONITOR 输出,并且 GET 命令接收得很好,但是没有 SET 命令的迹象。有什么建议吗?
这是我的控制器:
@RequestMapping(value = "/prime", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Mono<String> prime() {
reactiveStringCommands.set(ByteBuffer.wrap("testkey2".getBytes()), ByteBuffer.wrap("test".getBytes()));
return reactiveStringCommands.get(ByteBuffer.wrap("testkey".getBytes())).map(bb -> new String(bb.array()));
}
application.properties中的相关设置:
spring.redis.host=localhost
spring.redis.password=<password>
spring.redis.port=6379
redis-cli输出(testkey在CLI中手动设置,没有testkey2的迹象):
127.0.0.1:6379> keys *
1) "testkey"
127.0.0.1:6379> ACL list
1) "user default on #<password> ~* +@all"
127.0.0.1:6379> monitor
OK
1610406175.250768 [0 172.17.0.1:39104] "GET" "testkey"
编辑:忘记提及没有堆栈跟踪,也没有任何类型的错误输出到控制台。
响应式的第一条规则:在您订阅之前什么都不会发生。
虽然如果您从命令式的角度来看您的代码看起来不错,但从反应式的角度来看它是不正确的。
您看不到 set 命令的影响的原因是没有任何订阅它。
您需要做的是将这两个语句连接在一起,如下所示:
public Mono<String> prime() {
return reactiveStringCommands.set(ByteBuffer.wrap("testkey2".getBytes()), ByteBuffer.wrap("test".getBytes()))
.then(reactiveStringCommands.get(ByteBuffer.wrap("testkey".getBytes())).map(bb -> new String(bb.array())));
}
这样 Spring 将在内部订阅生成的 Mono
,后者又将订阅链中的所有 operators/steps(包括 set 命令)。
我正在使用Spring Webflux + Reactive Redis,我的目标是将Redis用作文件缓存。
一开始我试图用 ~100MB 的 ByteBuffer 设置一个密钥,但没有成功。我用调试器仔细检查以确保文件确实被读入内存,而且确实如此。我想“也许 Redis 不喜欢“大”字符串?”所以我尝试了下面的代码,仍然没有骰子。以为这可能是与 ACL 相关的问题,但我检查了一下,默认用户可以访问所有内容。 “也许 Spring 无法访问 Redis?”不,我检查了 redis-cli 中的 MONITOR 输出,并且 GET 命令接收得很好,但是没有 SET 命令的迹象。有什么建议吗?
这是我的控制器:
@RequestMapping(value = "/prime", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Mono<String> prime() {
reactiveStringCommands.set(ByteBuffer.wrap("testkey2".getBytes()), ByteBuffer.wrap("test".getBytes()));
return reactiveStringCommands.get(ByteBuffer.wrap("testkey".getBytes())).map(bb -> new String(bb.array()));
}
application.properties中的相关设置:
spring.redis.host=localhost
spring.redis.password=<password>
spring.redis.port=6379
redis-cli输出(testkey在CLI中手动设置,没有testkey2的迹象):
127.0.0.1:6379> keys *
1) "testkey"
127.0.0.1:6379> ACL list
1) "user default on #<password> ~* +@all"
127.0.0.1:6379> monitor
OK
1610406175.250768 [0 172.17.0.1:39104] "GET" "testkey"
编辑:忘记提及没有堆栈跟踪,也没有任何类型的错误输出到控制台。
响应式的第一条规则:在您订阅之前什么都不会发生。
虽然如果您从命令式的角度来看您的代码看起来不错,但从反应式的角度来看它是不正确的。
您看不到 set 命令的影响的原因是没有任何订阅它。
您需要做的是将这两个语句连接在一起,如下所示:
public Mono<String> prime() {
return reactiveStringCommands.set(ByteBuffer.wrap("testkey2".getBytes()), ByteBuffer.wrap("test".getBytes()))
.then(reactiveStringCommands.get(ByteBuffer.wrap("testkey".getBytes())).map(bb -> new String(bb.array())));
}
这样 Spring 将在内部订阅生成的 Mono
,后者又将订阅链中的所有 operators/steps(包括 set 命令)。