我正在尝试创建一个基础设施,不同的机器通过 Redisson 获取共享锁。一旦获得锁,一些异步任务就完成了,最后,当我完成工作时,我通过当前正在运行的线程释放 Redisson 锁 - 但我收到以下错误
java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: xxxxx thread-id: 57
Run Code Online (Sandbox Code Playgroud)
所以,我明白那个意思,但是因为我要执行异步工作,所以我不能使用获取线程来执行释放。
我不应该使用 Redisson 锁吗?像这样的异步工作的最佳匹配是什么?
我们正在使用 Redisson 连接到具有 1 个主节点和 2 个副本节点的 AWS elasticache 上的复制 Redis。
该应用程序使用多个RLocalCachedMaps、Locks 和几千个Topics来跟踪用户状态。(随着用户在线和离线,主题和订阅来来去去)。
然而,我们经常得到一系列RedisTimeoutExceptions,最初这些是在服务器运行了几天之后并且会持续发生直到服务器重新启动,或者会因内存不足错误而崩溃。这让我认为这是缺乏可用的订阅,但是如果我正确理解它们,我们的设置(如下)应该支持超过 100,000 个订阅并且我们还没有接近。
此外,其中一些会在预热期间发生,服务器上的负载相对较轻,经过几次异常连接后,几天都没有大问题,这表明这不是纯粹的订阅问题。命令每次都是简单的锁定/发布/订阅,而不是复杂的批处理。
AWS Elasticache 节点上的负载始终很小,我们的服务器部署在 AWS EC2 实例上,因此应该具有相对良好的连接性!
我们在数量上获得的 2 个例外是锁定或订阅主题:
Caused by: org.redisson.client.RedisTimeoutException: Subscribe timeout: (7500ms)
at org.redisson.command.CommandAsyncService.syncSubscription(CommandAsyncService.java:142) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonLock.lockInterruptibly(RedissonLock.java:149) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonLock.lockInterruptibly(RedissonLock.java:136) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonLock.lock(RedissonLock.java:118) ~[redisson-3.8.2.jar!/:na]
Run Code Online (Sandbox Code Playgroud)
和
java.util.concurrent.CompletionException: org.redisson.client.RedisTimeoutException
at org.redisson.misc.RedissonPromise.await(RedissonPromise.java:197) ~[redisson-3.8.2.jar!/:na]
at org.redisson.misc.RedissonPromise.await(RedissonPromise.java:206) ~[redisson-3.8.2.jar!/:na]
at org.redisson.command.CommandAsyncService.syncSubscription(CommandAsyncService.java:141) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonTopic.addListener(RedissonTopic.java:133) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonTopic.addListener(RedissonTopic.java:109) ~[redisson-3.8.2.jar!/:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_111]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_111]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_111]
at …Run Code Online (Sandbox Code Playgroud) 我正在考虑在我的应用程序服务器中使用Lettuce和Redisson Java 客户端(以连接到 Redis)。我无法从尝试过这两种方法或其中一种方法的人那里找到对这两种方法的正确比较。我看到的唯一详细比较是here和Redisson自己发布的其他一些链接。我发现的另一个链接是这个SO post,它没有得到很好的接收。
我想听听实际使用过这两个客户端或其中一个客户端的人的意见,他们的经验/用例以及优缺点是什么。我目前有一个集群 Redis 设置,我正在使用 Lettuce。生菜达到了我想要的效果。然而,在故障转移时发现集群中的新节点有一些痛点。我在这个SO 线程中提出了这个问题,并且能够按照答案中的解释解决它。从积极的方面来说,我发现与 Redisson 的文档相比,Lettuce 文档更清晰、更易于遵循。
我主要考虑转向Redisson,因为我希望使用 Redisson 的RedLock 由 Redis实现,以便在我的应用服务器的多个实例之间进行领导者选举。Lettuce 没有提供它的实现。因此,开箱即用的唯一选项是 Redisson。在这种情况下,我还必须完全摆脱 Lettuce 和 Redisson。Redissons 如何支持 Redis 集群部署。我想知道 Redisson 是否报告/未决故障转移时的集群节点发现问题(我在他们的repo 中没有看到任何问题)。我也读到过关于库体积庞大且不如 Lettuce 轻巧的担忧。
鉴于上述问题和我已有的知识,我想了解有关使用这两个客户端的评论,以帮助我做出决定。
谢谢
正如标题所说,是否有映射到 Redisson 框架的 spring 数据 redis ( http://redisson.org )
我在我的大数据应用程序中使用 Redis 作为缓存服务。Redis 的主要目的是验证我们从每个请求中收到的密钥。
我们使用 RMap 来存储键值对,示例如下:
key = 1212sads23sads341212saas23asds45
value = Regular java object with some complex data.
Run Code Online (Sandbox Code Playgroud)
我想为我插入的每个键分配 TTL,我知道我可以使用RMap.expire(). 我没有得到的是,当特定密钥到期时我怎么能听。由于每个键都有不同的 TTL,正如 Redis 文档中所述,它负责键的自动过期并生成事件。
我的问题是,
如何捕获生成的 EXPIRE 事件并获取它在 Redisson java 库中生成的键?
这是更好的方法(redis 内置自动过期),还是运行一些检查过期键的线程更好?
redisson客户端线程安全吗?在我的应用程序中,我想维护一个客户端对象,并让所有线程使用它来获取/放入Redis.在配置中,有两个参数threads和nettyThreads.这些参数是否有助于创建连接池?如果是,如果我的用例主要是对Redisson对象进行简单的get/put操作,那么我应该使用哪些?
此外,这些连接是否在RedissonClient的整个生命周期中都有效?
我是AWS Elasticache redis的新手,并且低于端点。
我对使用Jedis和Redisson感到困惑,因为两者都提供单连接和集群连接类。
就像在Jedis中一样,对于单个连接我们可以使用:
Jedis conn = new Jedis("endpoint_address");
Run Code Online (Sandbox Code Playgroud)
对于集群连接,我们使用:
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
jedisClusterNodes.add(new HostAndPort("redis_cluster_ip", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNodes);
Run Code Online (Sandbox Code Playgroud)
当我想使用Redisson时,也会出现这些选项。我不想比较这两个库,我的问题是:当您只有一个端点并且仍然可以使用 AWS 自动扩展功能时,哪一种是连接到AWS Redis Elasticache集群的正确方法?
预期的答案是:使用单机或集群模式。
谢谢 :)
我使用 Redisson 作为我的 Spring Boot 应用程序的 Redis 客户端。我想要获得连接池统计数据/指标并将其发布到 micrometer。
任何建议都将受到欢迎。
我们使用的是 Redisson 3.17.0 和 redis 版本 6.0.8。我们的 Redis 集群模式设置有 3 个主节点,每个主节点有大约 4-5 个副本。当redis master发生故障转移时,redisson开始抛出无法将命令写入连接的异常。即使故障转移完成后(大约 30 秒),异常也不会停止。只有运行 redisson 的实例的反弹才能解决此错误。这影响了我们服务的高可用性。我们将 pingConnectionInterval 设置为 5000 毫秒。我们的阅读模式仅限于大师。
org.redisson.client.RedisTimeoutException: Command still hasn't been written into connection! Try to increase nettyThreads setting. Payload size in bytes: 81. Node source: NodeSource [slot=10354, addr=null, redisClient=null, redirect=null, entry=null], connection: RedisConnection@1578264320 [redisClient=[addr=rediss://-:6379], channel=[id: 0xb0f98c8c, L:/-:55678 - R:-/-:6379], currentCommand=null, usage=1], command: (EVAL), params: [local value = redis.call('hget', KEYS[1], ARGV[2]); after 2 retry attempts
Run Code Online (Sandbox Code Playgroud)
以下是我们的 redisson 客户端配置:
redisClientConfig: {
endPoint: "rediss://$HOST_IP:6379"
scanInterval: 1000 …Run Code Online (Sandbox Code Playgroud) redisson ×10
redis ×6
java ×4
jedis ×2
caching ×1
lettuce ×1
locking ×1
micrometer ×1
spring-boot ×1