在 Redis 的 Lettuce(4.x) 中,如何减少往返行程并使用一个命令的输出作为另一个命令的输入,尤其是 Georadius

     2023-02-23     263

关键词:

【中文标题】在 Redis 的 Lettuce(4.x) 中,如何减少往返行程并使用一个命令的输出作为另一个命令的输入,尤其是 Georadius【英文标题】:In Lettuce(4.x) for Redis how to reduce round trips and use output of one command as input for another command, especially for Georadius 【发布时间】:2015-12-12 13:26:10 【问题描述】:

我看过这个pass results to another command in redis 并通过命令行使用此命令效果很好:

src/redis-cli keys '*' | xargs src/redis-cli mget

但是我们怎样才能通过 Lettuce 达到同样的效果(我开始尝试 4.0.2.Final)

在以下情况下,解决方案也特别重要:

假设我们正在使用地理定位功能,我们添加了一组“my-location-category”位置 使用 GEOADD

GEOADD "category-1" 8.6638775 49.5282537 "location-id:1" 8.3796281 48.9978127 "location-id:2" 8.665351 49.553302 "location-id:3"

接下来,假设我们执行 GeoRadius 以获取“类别 1”的 8.6582361 49.5285495 10 公里半径范围内的位置

现在当我们得到“location-id:1”和“location-id:3”时

鉴于我已经为上述键“location-id:1”和“location-id:3”设置了值

我想通过管道命令执行 GEORADIUS 以及对所有匹配结果执行 mget。

Redis 是否提供这样做的功能?

和/或我们如何通过 Lettuce 客户端库来实现这一点,而无需先手动迭代 GEORADIUS 的结果,然后再进行手动管理。

对于使用它的程序来说,这将是更有效的性能。

有谁知道我们如何做到这一点?

更新 这是我上面讨论的场景的管道命令:

src/redis-cli GEORADIUS "category-1" 8.6582361 49.5285495 10 km | xargs src/redis-cli mget

现在我们需要知道如何通过生菜来做到这一点

【问题讨论】:

永远不要使用KEYS,总是使用SCAN 感谢您让我了解 SCAN。 现在我已经更正了问题的标题,以真正代表我的意思。 :=) 【参考方案1】:

重要提示:切勿使用KEYS,如果必须,请始终使用SCAN

这不是关于生菜或 Java 的真正问题,所以我实际上可以回答:)

您要做的是使用读取操作 (GEORADIUS) 的结果作为另一个读取操作 (MGET) 的输入(键名)。这种类型的流程不能流水线化,好吧,正因为如此 - 流水线化意味着您不需要立即获得操作的答案,但在您的情况下,您确实需要。

但是。

由于您正在使用 MGET 读取字符串键,因此您不妨将所有内容非规范化(记住,我们是 NoSQL)并将这些键的内容存储在排序集的成员中,例如:

GEOADD "category-1" 8.6638775 49.5282537 "location-id:1:moredata:evenmoredata:maybe a JSON document here:orperhapsmsgpack"

这将允许您通过一个GEORADIUS 调用获取位置及其“数据”。当然,location:1 数据的任何更新都需要在所有类别中完成。

关于 Lua 脚本的说明:虽然 Lua 脚本在这种情况下肯定可以来回保存,但任何此类脚本都将违反最佳实践/不是集群安全的。

【讨论】:

我计划使用它的方式是 Webapp 使用键“location-id:1”和 JSON data 进行 CRUD 只有那些需要 GEO 位置的人才能转到 GEOADD“category-1 " "location-id:1" 同样使用更多,所以下次更新使用键 "location-id:1",id 值是恒定的。 , 经纬度不是。如果 lang-long 更改,我将没有较早的值来从该类别的地理列表中删除较早的值并添加一个新值。因此,我觉得一些标准化会有所帮助。另外考虑到我们现在的 RAM 有限 :) 我愿意接受想法,在这种情况下你会建议什么?【参考方案2】:

在四处挖掘和研究 Lua 脚本之后,我的结论是,按照 Itamar Haber 的建议,只能通过 Lua 脚本来以这种方式删除往返。

我最终创建了一个 lua 脚本文件 (myscript.lua),如下所示

local locationKeys = redis.call('GEORADIUS', 'category-1', '8.6582361', '49.5285495', '10', 'km' ) 
if unpack(locationKeys) == nil then
    return nil
else
    return redis.call('MGET', unpack(locationKeys))
end

** 当然我们应该向它发送参数...这只是一个 poc :)

现在你可以通过命令执行它了

src/redis-cli EVAL "$(cat myscript.lua)" 0

然后,为了减少将整个脚本发送到 Redis 执行的网络开销,我们可以选择将脚本注册到 Redis。

Redis 将为我们提供一个 sha1 消化的代码,以供该脚本将来参考,可用于该脚本的下一次调用。

这可以通过以下方式完成:

src/redis-cli SCRIPT LOAD "$(cat myscript.lua)"

这应该返回一个类似这样的sha1代码:49730aa2ed3034ee48f818e486tpbdf1b500b19e

可以使用此代码完成下一次调用 例如

src/redis-cli evalsha 49730aa2ed3034ee48f818e486b2bdf1b500b19e 0

然而这里可悲的是,只有当 redis 实例正在运行时,才会记住 sha1 摘要。如果重新启动,则 sha1 摘要丢失。然后再次执行 SCRIPT LOAD。如果脚本中没有任何变化,那么 sha1-digest 代码将是相同的。

理想情况下,通过客户端 api 使用时,我们应该首先尝试 evalsha,如果返回“无匹配脚本”错误,然后作为后备执行脚本加载,并再次获取 sha1 代码,并创建其内部映射并使用该 sha1 代码进行进一步调用。

这可以通过生菜很好地完成。我可以找到那些方法。希望这可以很好地了解问题的解决方案。

【讨论】:

读完这个***.com/questions/16692233/… 现在我知道为什么Redis 不记得脚本了。但可能的一种解决方案是创建一个脚本文件来启动 redis 服务器,然后开始加载所有必需的脚本。这将模拟相同的效果。但是我还没有尝试过......我觉得这应该可以工作。

springboot中redis的lettuce客户端和jedis客户端

1、引入客户端依赖<!--jedis客户端依赖--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><!--默认使用lettuce客户端--><dependency> 查看详情

Jedis 和 Lettuce 异步能力

】Jedis和Lettuce异步能力【英文标题】:JedisandLettuceasyncabilities【发布时间】:2015-12-2718:10:10【问题描述】:我在Akka中使用redis,所以我不需要阻塞调用。生菜内置了异步未来调用。但是Jedis是Redis推荐的客户端。有人可以告诉我我... 查看详情

(二)连接redis,lettuce与jedis客户端

参考技术ARedis优势从SpringBoot2.x开始Lettuce已取代Jedis成为首选Redis的客户端。当然SpringBoot2.x仍然支持Jedis,并且你可以任意切换客户端。使用Lecttuce需要再引用一个包配置org.springframework.boot.autoconfigure.data.redis.RedisProperties中集成了Je... 查看详情

redis网络波动,jedis/lettuce是阻塞还是失败?

...考技术ARedis服务器环境:单点配置Redis客户端环境:Jedis/Lettuce配置配置信息如下:Jedis连接工厂的配置:lettuce连接工厂的配置:无论是Jedis客户端还是Lettuce客户端,当Redis服务器恢复后,均无需重启项目,项目的Redis访问请求即... 查看详情

springboot整合redis

...目!说明:在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce?Jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedispool连接池!更像BIO模式Lettuce:采用netty,实例可以在多个线程中进行共享,... 查看详情

redis-lettuce连接池(代码片段)

...以有效的保护和控制资源的使用。两个框架比较突出的是Lettuce和jedis。Lettuce和jedis的都是连接RedisServer的客户端,Jedis在实现上是直连redisserver,多线程环境下非线程安全,除非使用连接池,为每个redis实例增加物... 查看详情

无法连接到 Redis;嵌套异常是 io.lettuce.core.RedisConnectionException:

】无法连接到Redis;嵌套异常是io.lettuce.core.RedisConnectionException:【英文标题】:UnabletoconnecttoRedis;nestedexceptionisio.lettuce.core.RedisConnectionException:【发布时间】:2021-06-0716:47:53【问题描述】:我是docker新手,我正在尝试在容器上运行... 查看详情

springboot第六章springboot集成redis(代码片段)

...一个独立的服务器。java中著名的客户端:Jedis,lettuce,RedissonSpring、SpringBoot中有一个RedisTemplate(StringRedisTemplate)处理和redis交互。Redis推荐都是在Linux服务器上搭建的,基于Linux学习。创建一个模块选择依... 查看详情

17springcloud整合lettuce使用redis

喜欢关注个人公众号:java乐园Redis是一种nosql数据库,以键值对<key,value>的形式存储数据,其速度相比于MySQL之类的数据库,相当于内存读写与硬盘读写的差别,所以常常用作缓存,用于少写多读的场景下,直接从缓存拿数... 查看详情

使用 Reactive Lettuce 流水线 Redis 命令

】使用ReactiveLettuce流水线Redis命令【英文标题】:PipelineRediscommandswithReactiveLettuce【发布时间】:2019-01-2218:52:20【问题描述】:我正在使用springbootwebflux+projectreactor+lettuce以非阻塞方式连接和查询Redis。我已经用LettuceConnectionFactory配... 查看详情

redis客户端选型-jedis、lettuce、redisson

...客户端。2.比较  官方推荐的java客户端只有Jedis、lettuce、Redisson,所以这次分析只针对这三个进行。2.1.概述  Jedis:redis的Java实现客户端,提供了比较全面的Redis命令的支持。  lettuce:Lettuceisascalablethread-safeRedisc... 查看详情

lettuce:connectiontoxxxnotallowed.thispartitionisnotknownintheclusterview.(代码片段)

...amework.data.redis.RedisSystemException:Redisexception;nestedexceptionisio.lettuce.core.RedisException:io.lettuce.core.cluster.UnknownPartitionException:Connectiontoxxxnotallowed.Thispartitionisnotknownintheclusterview.可能原因Lettuce会在本地维护一份clusternodes返回的信息作为路... 查看详情

lettuce:connectiontoxxxnotallowed.thispartitionisnotknownintheclusterview.(代码片段)

...amework.data.redis.RedisSystemException:Redisexception;nestedexceptionisio.lettuce.core.RedisException:io.lettuce.core.cluster.UnknownPartitionException:Connectiontoxxxnotallowed.Thispartitionisnotknownintheclusterview.可能原因Lettuce会在本地维护一份clusternodes返回的信息作为路... 查看详情

spring-data-redis+lettuce如何使用pipeline(代码片段)

关于spring-data-redis和lettuce,笔者写过不少文章:这个Redis连接池的新监控方式针不戳~我再加一点佐料spring-data-redis连接泄漏,我TM人傻了spring-data-redis动态切换数据源spring-data-redis上百万的QPS压力太大连接失败,我TM... 查看详情

springboot连接redis错误io.lettuce.core.rediscommandtimeoutexception:

springboot连接redis报错超时连接不上 可以从以下方面排查1查看自己的配置文件信息,把超时时间不要设置0毫秒设置5000毫秒  2redis服务长时间不连接就会休眠,也会连接不上重新启动redis服务《黑窗口》  查看详情

redisclient之jedis与lettuce(代码片段)

前言JedisJedis是Redis官方推荐的Java连接开发工具,要在Java开发中使用好Redis中间件,必须对Jedis十分了解才行。基本使用Jedis的使用非常简单,只需要创建Jedis对象的时候指定host,port,password即可。Jedisjedis=newJedis("ip&... 查看详情

jedis那么低性能,还在用?赶紧换上lettuce吧

3大redis客户端:Jedis、Redisson、Lettuce,如何选型?简介:Redis的3大Java客户端组件Redis官方推荐的Java客户端有Jedis、lettuce和Redisson。客户端1:Jedis是老牌的Redis的Java实现客户端,提供了比较全面的Redis命令的... 查看详情

springboot整合redis异常汇总

...developer.aliyun.com/article/767317springboot从2.x版本开始默认使用lettuce访问redis,所以部分配置由jedis改为lettuce异常1:CannotretrieveinitialclusterpartitionsfrominitialURIs[RedisURI[host=\'192.168.1.1\',port=6379]]这个问题绕了很多弯路,根据网上的很多方案... 查看详情