分布式

Redis内存优化

字号+ 作者:风潇潇 来源:原创 2016-04-29 09:38 我要评论( )

翻译官网上的文章,关于redis的内存设置和优化 的。可能翻译的不是很周到,不过一些基本的东西还是理解了,记录一下

  1.  

  2. 特殊编码的小集合数据类型

Redis2.2,一些数据会使用特殊编码(这个其实就是Redis对map结构的优化),使用这种编码可以让Redis使用更少的内存存储数据。这个配置用以下指令。

hash-max-zipmap-entries
64 (hash-max-ziplist-entries for Redis >= 2.6)
hash-max-zipmap-value
512  (hash-max-ziplist-value for Redis >= 2.6)
list-max-ziplist-entries
512
list-max-ziplist-value
64
zset-max-ziplist-entries
128
zset-max-ziplist-value
64
set-max-intset-entries
512

如果一个特殊编码的值将溢出配置的最大大小,将自动转换成正常的编码。该操作是非常之快,但是如果你改变设置为了使用特殊编码的值更大的聚合类型,建议是运行一些基准和测试来检查转换时间是否超出预期。

    1. 使用32位实例

这样可以使用32位的编译实例,32位的redis使用的key将会消耗更少的内存,但是缺点是32redis只能限制使用4GB内存,AOFRDB文件在32位和64位之间是兼容的,这一点不用担心

    1. 比特和字节级别的操作

复述,2.2引入了新的比特和字节级别操作: GETRANGE, SETRANGE, GETBIT SETBIT。使用这些指令可以将RedisString类型当做一个随即操作数组。比如你有一个应用程序,里面有实体UserUser的主健是线性的Integer,可以用bitmap结构来存储用户的Sex属性,设置一个bit为女性,清除掉则为男性。100亿的数据仅仅只在redis实例里消耗掉12GB的数据,并且可以使用GETRANGE SETRANGE 来为每个User存储一个byte的信息。

    1. 尽可能使用散列

小哈希编码在一个非常小的空间,所以您应该代表数据使用散列每次是可能的。例如如果你有Userweb应用程序中,而不是使用不同的Key 名称,姓氏,电子邮件,密码,使用一个散列和所有必需的字段。在小哈希的时候redis会压缩转换成小的数组,以尽可能的节约内存。

具体阅读下一节。

    1. 使用散列抽象一个内存高效简单的键值存储Redis

基本上是可能的模型的一个简单的键值存储使用Redis,值可以是字符串,这不仅仅是更多的内存效率比Redis,普通的钥匙但效率比memcached也更多的内存。

让我们先从一些事实:几个键比单一键包含一个散列一些字段使用更多的内存。

但是很多次散列包含几个字段。当散列小我们可以只编码一个O(N)的数据结构,像一个线性阵列length-prefixed键值对。因为我们这样做只有当N很小,HGETHSET命令的摊销时间仍然是O(1):散列将被转换成一个真正的哈希表一旦它所包含的元素数量将增长太多redis.conf(您可以配置限制)

这并不只是从时间复杂度的角度,也从恒定次数的角度都工作的很好,线性数组的键值对很好利用CPU缓存缓存(它有一个更好的位置比一个哈希表)

然而因为散列字段和值并不是(总是)表示为全功能的Redis,对象,散列字段不能像一个真正的Key一样有一个关联的生存时间(过期),而只能包含一个字符串。但我们是好的,无论如何,这散列数据类型API在设计时的意图(我们相信简单胜过更多的功能,所以不允许嵌套的数据结构,mapfield的过期属性是不允许的)

在使用hashmap的时候要记得配置以下

hash-max-zipmap-entries
256
hash-max-zipmap-value
1024


 

每次一个散列的数量将超过指定元素或元素的大小将被转换成一个真正的哈希表,这时节省内存将丢失。

你可能会问,为什么你在普通的key隐试的处理这个问题,这样我不需要去配置?有两个原因:一是我们倾向于做出权衡显式,这是一个明确的权衡许多事情:CPU、内存、最大元素的大小。第二个是顶级key空间必须支持一些特性比如到期时间,LRU数据,等等这是不实际的一般方法。

Redis的方式是用户必须了解事情,这样他能够挑选最好的妥协,并了解系统行为。

    1. 内存分配

为了存储用户keys,Redis最多分配maxmemory设置允许 的尽可能多的内存(不过可能有小的额外分配)

其他的值可以在配置文件中设置或通过 CONFIG SET设置(使用内存作为一个LRU缓存更多信息)。下面有一些应该注意的事情复述,如何管理内存:

  • key删除时,Redis不会总是释放(返回)内存给操作系统。这并不是Redis的什么特别之处,因为它大多数是靠malloc()实现的工作。例如,如果你给一个Redis实例装在5 gb的数据,然后删除相当于2 gb的数据,驻留集大小(也称为RSS,它是内存页的数量消耗的过程)可能仍会5 gb左右,即使Redis将声称只用了大约是3 gb。这是由于底层分配器不能轻易释放内存。例如通常大多数的删除键是分配在同一个页面的而其他键仍然存在。

  • 前面的点意味着您需要提供内存基于峰值内存使用。如果你工作量不时需要10 gb,即使大多数乘以5 gb可以做,你需要准备10 gb

  • 然而分配器是聪明和能够重用空闲块的内存,所以在你释放2 gb5 gb的数据集,当你开始再次增加键,您将看到RSS(驻留集大小)保持稳定,不会分配更多。分配器基本上是试图重用之前(逻辑上)2 gb的内存释放。

  • 因为这一切,当内存使用量在高峰远远大于当前使用的内存碎片率是不可靠的,。分段计算是按照目前物理内存分配(RSS的值)的使用的内存量(分配由Redis的总和)来算的 。因为RSS反映了峰值内存,当使用的(几乎)内存很低因为很多Keys/Values被释放,RSS,比例mem_used / RSS将会非常高。(这句话可能需要完善)

如果Redismaxmemory没有设置,Redis将分配更多它认为合适的内存,因此它可以(逐渐)吃掉你所有的空闲内存。因此,配置一些限制通常是明智的。你也可以设置 maxmemory-policy noeviction(这不是默认值在一些老版本的Redis)

它使Redis返回一个内存错误的写命令如果它到达极限,进而可能导致应用程序中的错误,但是不会使整个机器挂掉因为缺少内存。

    1.  

 

转载请注明出处。

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Redis基本知识以及管理

    Redis基本知识以及管理

    2016-03-29 15:52

  • redis使用sentinel高可用配置

    redis使用sentinel高可用配置

    2016-03-31 21:39

  • redis主从复制+keepalived的高可用配置

    redis主从复制+keepalived的高可用配置

    2016-01-03 11:16

网友点评
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)