gpt4 book ai didi

java - Redis Java 客户端 : Do I need to buffer my commands into a pipeline for performance?

转载 作者:可可西里 更新时间:2023-11-01 11:13:10 25 4
gpt4 key购买 nike

所以我只是递增排序集中的分数。这是我使用 Jedis 客户端从 Java 应用程序运行的唯一命令,每秒大约 10-30 个命令。由于我只是更新分数,所以我也不关心响应。我担心的是每个 ZINCRBY 命令都被放入它自己的 TCP 数据包中,并且还在等待下一个回复,然后才允许我的线程发送下一个 ZINCRBY 线程。

所以,我只想实现流水线来一次批处理 50 个命令。这是我看到代码/设计模式味道的地方:这种设计模式是否足够普遍以至于驱动程序应该处理它?看起来 .net“StackExchange.redis”驱动程序会自动执行命令批处理,但 Java 驱动程序没有此功能吗?我的想法是制作一个自定义的 Redis 命令缓冲区类,它将传入的命令放入管道并在 50 个项目后调用 sync(),真的需要吗?

此外,我在日志中注意到了这一点,因为我通过 Spring Data Redis 使用 Jedis:

20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.394 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.394 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.629 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.630 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.630 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection

所以看起来它正在关闭每个天真执行的命令的连接(通过 Spring 提供的模板模式)。我认为关闭连接会强制 TCP 缓冲区为每个数据包发送一个命令,所以这对我来说似乎效率很低,因为套接字占用了大量的 CPU。尽管 Spring Data Redis API 确实允许直接访问 Jedis 客户端并且不会在管道当前打开时关闭连接,因此编写“管道缓冲区”是一个选项。

简而言之,我应该创建/利用一个缓冲区来写入 redis 管道并在 X 命令后刷新吗?我只是不喜欢浪费所有这些 CPU 周期(更高的 AWS 账单)天真地运行每个命令的想法,并且很好奇是否有更好的设计模式适合我的场景。或者如果切换到不同的 Java Redis 客户端可以解决这个问题。或者如果有一些 Java 库已经在 redis 管道中缓冲命令。

最佳答案

我认为我们需要在这里更深入地了解细节,因为您在这里提到了不同的方面。

通常,所有 Java Redis 客户端(JedisLettuceRedisson 等等)默认情况下直接将命令写入 TCP channel 。因此,每个命令都作为一个或多个 TCP 数据包发送。 Lettuce 和 Redisson 作为它们的操作模式,因为这两个客户端在后台使用异步/事件驱动的编程模型将 Redis 命令写入 TCP channel 。 Jedis 会强制您等待命令结果,因为它公开了一个阻塞 API。 Redisson 和 Lettuce 公开了不同类型的 API(异步使用 Futures 或响应式(Reactive)使用 RxJava/Reactive Streams),它们不会强制您等待命令结果。

批处理/缓冲是另一种在客户端内存中收集命令并将命令作为批处理发送到 Redis 的技术。这适用于两者,LettuceRedisson客户。 Jedis 以其流水线模式将命令直接写入 TCP channel 。

命令批处理带来了一些影响。可以自动批处理命令(比如大小为 10 或 50),但这需要用户注意。批处理总是需要一些最终的同步,以避免命令在队列中逗留而未被发送,因为尚未达到批处理大小。

Spring Data Redis 使用Jedis 和Lettuce 来暴露其功能,因此需要Spring Data Redis 来应对这两种驱动程序的共性。您可以将 Spring Data Redis 设置为与 Jedis 一起使用连接池,这样您就可以从每次与 Redis 交互时都不会关闭的池化连接中受益。

关于java - Redis Java 客户端 : Do I need to buffer my commands into a pipeline for performance?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39768380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com