高效的可扩展序列生成器实现

Leo*_*d B 2 java memcached redis sequence-generators

问题:
我需要实现多个共享序列生成器,将被 50-100 个 Tomcat 服务器使用。每个序列生成器应从 1 开始,并在每次请求后加 1。序列生成器实现应该有原子增量命令。Java 客户端应该可用。

规模:
多达 50000 个序列生成器被积极使用,对于它们中的每一个,我们预计在 5-10 秒内有一个增量请求。每秒最多 20000 个请求
50-100 个 java 客户端(Tomcat 服务器)。对序列生成器的访问在这些服务器之间共享。重要提示:只有 2 个客户端使用相同的序列生成器。
50-100 次 - 每个序列生成器的平均使用次数。
24 小时 TTL - 生成器最多应在创建后 24 小时后清理 - 因此实际上可能有超过 50000 个序列生成器,但预计最多只能有 50000 个同时主动接收请求。

性能:
<1ms 更可取的平均响应时间。平均超过 2ms 肯定不够好。

我们排除了 Oracle 的 Sequence 对象。
我们目前正在考虑 Redis 和 Memcached。
两者都很快。

推荐/足够好的实现是什么?
是否有其他更好的技术用于此目的?

另一个重要问题:
incr、Redis 或 Memcached 哪个性能更好?

谢谢

Sri*_*nan 5

Redis 应该可以让你轻松地做到这一点。

  1. 为每个序列生成器创建一个密钥
  2. 使用INCR命令获取下一个序列号
  3. 如果返回的数字为 1,则表示该密钥以前不存在。在这种情况下,您还应该发出PEXPIRE命令使密钥在 24 小时后过期

为了进一步减少延迟,您可以做几件事 -

  1. 仅为序列生成器维护 Redis 服务器。换句话说,不要在此服务器上存储任何其他数据。
  2. 不要使用AOF;而是使用 RDB 持久性。AOF 将在日志文件中附加每个 INCR 命令,另一方面,RDB 将简单地存储每个序列的当前值。

您应该通读诊断延迟问题以及有关redis 持久性的页面。

此外,expire 命令最多只能在 24 小时内发出一次,这将需要两次往返 redis。如果你想避免这种情况,你可以创建一个 lua 脚本。该速率限制LUA脚本是一个很好的起点。