【问题标题】:Redis keys with incremental integer value具有增量整数值的 Redis 键
【发布时间】:2018-07-03 18:16:41
【问题描述】:

我有如下示例的键值对

KEY VALUE
key1    1
key2    2
key3    3
.       .
.       .
keyN    N

我的每个键都需要映射一个唯一的数字,所以我将我的键映射到自动递增的数字,然后通过 redis mass insertion 将其插入到 Redis,这非常有效,然后使用 GET 命令对所有键值映射进行内部处理.

但我有超过 10 亿个密钥,所以我想知道在这种情况下使用 Redis 是否有更高效(主要是内存使用量更少)的方法?

谢谢

【问题讨论】:

  • 你的条件是只有唯一的key吧?
  • 我有唯一的字符串键,我需要将它们映射为整数。然后我想将此键值映射与标准 GET 命令一起使用。
  • “高效”是什么意思?
  • 主要是消耗内存较少
  • 也通过有效的方式,因为我的值属于键是递增的数字,我认为 Redis 中可能有替代方式/用法,所以我不需要设置这个自动递增的值。

标签: redis


【解决方案1】:

您可以将命令流水线化到 Redis 中以避免像这样的往返时间:

{ for ((i=0;i<10000000;i++)) ; do printf "set key$i $i\r\n"; done ; sleep 1; } | nc localhost 6379

设置 10,000,000 个键需要 80 秒。


或者,如果您想避免为 printf 创建所有这些进程,请在单个 awk 进程中生成数据:

awk 'BEGIN{for(i=0;i<10000000;i++){printf("set key%d %d\r\n",i,i)}}'; sleep 1; } | nc localhost 6379

现在设置 10,000,000 个键需要 17 秒。

【讨论】:

  • 感谢我正在使用管道,它运行良好只是想知道我的字符串数字映射用法是否有任何替代方法。
  • @Tamer 也许然后显示您的代码以向其他人说明这一点,因为您在问题中没有提到管道。
  • 确定我已经更新并提到了 redis 大规模插入,它是 redis 中的管道衬里。
【解决方案2】:

自动增量键允许在将新记录插入表/redis 时生成唯一编号。

还有其他使用 UUID 的方法。

但我认为自动增量要好得多,因为它需要四倍的空间,不能基于键进行排序等

【讨论】:

  • 你指的是redis中的哪个表?
【解决方案3】:

我正在做同样的事情。 这是一个简单的例子。 如果你有更好的,欢迎讨论:)

1。连接到redis

import redis
pool = redis.ConnectionPool(host=your_host, port=your_port)
r = redis.Redis(connection_pool=pool)

2.定义一个函数来增加,使用管道

def my_incr(pipe):
    next_value = pipe.hlen('myhash')
    pipe.multi()
    pipe.hsetnx(
        name='myhash',
        key=newkey, value=next_value
    )

3.使函数成为事务

pipe = r.pipeline()
newkey = 'key1'
r.transaction(my_incr, 'myhash')

【讨论】:

  • 这里不是讨论的地方。如果您有足够的评论资格,您可以添加 cmets。如果你想讨论使用 stackoverflow 的聊天功能,但这也需要 20 个代表。如果您非常确定您的答案满足 op 的要求,我建议您回答。
【解决方案4】:

为了更加节省内存,可以使用HASH来存储这些键值对。 Redis 对小的HASH 有特殊的编码。它可以为您节省大量内存。

在您的情况下,您可以将您的密钥分成许多小的HASHs,每个HASH 的条目少于hash-max-ziplist-entries。详情请见doc

顺便说一句,使用 INCR 命令,您可以使用 Redis 创建自动递增的数字。

【讨论】:

  • 感谢我使用 HSET 和 1 个包含我所有键值的键,但我没有看到内存使用差异。也许我应该使用我所有的键作为单独的 HSET 键?
  • 不,你应该有很多小的HASHs,每个HASH 有少于hash-max-ziplist-entries 的条目。如果HASH 中的元素过多,Redis 将不会使用特殊编码。
  • 使用特殊编码,您可以使用最多 10 倍的内存(平均节省 5 倍的内存)
  • 哦,知道了,我需要对我的密钥进行分片,但在这种情况下,当我制作 HGET 时,我需要知道哪个密钥在哪个分片中,我会考虑如何对我的密钥进行分片。如果我增加 hash-max-ziplist-entries 值会发生什么?
  • 我的密钥没有任何特定的分片模式,但如果您对分片有任何建议,请告诉我,谢谢。
【解决方案5】:

我想回答我自己的问题。

如果您对键值进行了排序,那么批量插入然后读取它们的最有效方法是使用基于 B-Tree 的数据库。

例如,使用 MapDB,我可以非常快速地插入它并且占用更少的内存。

【讨论】:

    猜你喜欢
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多