当前位置: 首页 > 面试题库 >

Redis的内存使用量是数据的10倍

林泰平
2023-03-14
问题内容

我有一个小问题。

我正在尝试将单词表存储在Redis中。表现很棒。

我的方法是制作一个称为“单词”的集合,并通过“添加”添加每个新单词。

这是添加15.9mb且包含约一百万个单词的文件时的问题,redis服务器进程消耗160mb的ram。我为什么要使用10倍的内存,有没有更好的方法来解决此问题?

提前致谢


问题答案:

好吧,这是对任何有效数据存储的期望:字必须在内存中以指针链接的单元的动态数据结构中被索引。结构元数据,指针和内存分配器内部碎片的大小是数据占用比相应平面文件更多的内存的原因。

Redis集被实现为哈希表。这包括:

  • 几何增长的指针数组(2的幂)
  • 当增量重新哈希处于活动状态时,可能需要第二个阵列
  • 表示哈希表中条目的单链接列表单元(3个指针,每个条目24个字节)
  • Redis对象包装器(每个值一个)(每个条目16个字节)
  • 实际数据本身(每个数据的大小和容量以8字节为前缀)

以上所有大小均针对64位实现而给出。考虑到内存分配器的开销,对于使用jemalloc分配器(> =
2.4)的最新版本的Redis,Redis每个设置项(在数据顶部)至少占用64个字节。

Redis 为某些数据类型提供了内存优化,但是它们不包括字符串集。如果您确实需要优化集合的内存消耗,则可以使用一些技巧。我不会仅使用160
MB的RAM来执行此操作,但是如果您有更大的数据,则可以执行以下操作。

如果不需要集合的并集,交集,差值功能,则可以将单词存储在哈希对象中。好处是,如果哈希对象足够小,则Redis可以使用zipmap对其进行自动优化。zipmap机制已在Redis>
= 2.6中被ziplist取代,但是思想是相同的:使用可以适合CPU缓存的序列化数据结构来获得性能和紧凑的内存占用。

为了确保哈希对象足够小,可以根据某种哈希机制分配数据。假设您需要存储1M项,则可以通过以下方式实现添加单词:

  • 将其以10000为模进行哈希处理(在客户端完成)
  • HMSET单词:[hashnum] [word] 1

而不是存储:

words => set{ hi, hello, greetings, howdy, bonjour, salut, ... }

您可以存储:

words:H1 => map{ hi:1, greetings:1, bonjour:1, ... }
words:H2 => map{ hello:1, howdy:1, salut:1, ... }
...

要检索或检查单词的存在,它是相同的(将其哈希并使用HGET或HEXISTS)。

使用此策略,只要根据zipmap配置(或Redis> = 2.6的ziplist)选择哈希的模数,就可以节省大量内存:

# Hashes are encoded in a special way (much more memory efficient) when they
# have at max a given number of elements, and the biggest element does not
# exceed a given threshold. You can configure this limits with the following
# configuration directives.
hash-max-zipmap-entries 512
hash-max-zipmap-value 64

当心:这些参数的名称已通过Redis> = 2.6更改。

在此,对1M个项目取10000模,意味着每个哈希对象100个项目,这将确保所有这些对象都存储为zipmap / ziplist。



 类似资料:
  • 问题内容: 我需要使用php创建一个具有大量数据的mysql数据库的解决方案。我的程序将有许多要求,我认为如果我使用缓存和OO数据库,我会得到很好的结果,但是我没有经验。 我认为,例如,如果我将保存在mysql中的信息缓存到redis数据库中,性能将会提高,但是我不知道这是否是个好主意,因此我希望有人来帮助我选择。 抱歉,如果我的英语不太好,我来自巴西。 问题答案: 是的,redis对此很有帮助。

  • 如果在记录的初始过期时间之前访问记录,则需要重置过期时间。我使用Spring数据redis API使用Redis作为缓存。我正在使用RediscacheManager的setDefaultEx的(5000)设置默认过期。无法找到有关重置到期时间的任何解决方案或留档。感谢任何指导。 此外,我想知道,为什么这不能成为Redis缓存的一个自然功能,毕竟,它应该从缓存中获取最常用的记录。

  • 我使用的是Android studio 3.1.3(编写本文时的最新版本)和Gradle 3.1.3。 我不知道这是否重要,但我最近升级到了Ubuntu18.04 每当我启动Android studio时,它都是从非常小的内存占用开始的。(一个名为java的进程占用大约1GB的RAM) 还有其他人面临这个问题吗?当我在Ubuntu16.04和旧的android工作室时,这不是问题。Ubuntu一定

  • 问题内容: 我还没有使用过Redis,但我听说过它,并打算尝试将其作为缓存存储。 我听说Redis使用内存作为缓存存储数据库,那么如果我使用变量作为对象或字典数据类型来存储数据有什么区别?喜欢: Redis有什么优势? 问题答案: Redis是一个 远程 数据结构服务器。这肯定比仅将数据存储在本地内存中要慢(因为它涉及套接字往返来获取/存储数据)。但是,它也带来了一些有趣的属性: 应用程序的所有进

  • 本文向大家介绍基于redis key占用内存量分析,包括了基于redis key占用内存量分析的使用技巧和注意事项,需要的朋友参考一下 Redis的指令看不出哪一类型的key,占用了多少内存,不好分析redis内存开销大的情况下,各应用程序使用缓存的占比。 借助第3方工具进行分析 1、采用2个工具结合 redis-rdb-tools+sqlite 2、sqlite linux服务器都会自带,安装r

  • 本文向大家介绍MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?相关面试题,主要包含被问及MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?时的应答技巧和注意事项,需要的朋友参考一下 redis 配置文件 redis.conf 中有相关注释,大家可以自行查阅或者通过这个网址查看: http://do