2019独角兽企业重金招聘Python工程师标准>>>

配置redis

如果想要运行一个内存高效的redis数据库,首先要理解那些在 redis.conf 配置文件中所有内存相关的指令。

redis.conf 为大多数指令提供了丰富的内联文档,大多数redis配置指令可以在运行时通过CONFIG SET进行设置。

rdbchecksum ,默认是yes,将65位循环冗余校验码(CRC64)放置在RDB快照文件的末尾,作为防止文件损坏的一种手段。当redis产生一个子进程将快照保存至磁盘时,对RDB快照进行CRC64校验会增加10%的内存使用。

redis中的主哈希表将主键与对应的值进行关联,若activerehashing=yes,那么该主哈希表每个100毫秒会重新哈希。重新哈希的过程将释放删除了的键占用的操作系统内存。activerehashing 发生在非工作时间,对客户端连接额影响最小。

主从复制

采用主从复制的方式提供高度可靠性、可伸缩性。在集群环境中,通过slave-of 指令将redis实例切换到从模式,此时 从实例 被允许从另一个被指派为主实例的redis中复制数据。内存 和 来自硬件和网络的延迟会直接影响主从实例的性能。

repl-disable-tcp-nodelay 指令可以用来更好地处理redis主从实例间的网络流量拥塞。通过对主从间的密集数据同步和更少的网络流量之间进行权衡,这种复制能够改善高流量情况下的网络性能。

32位redis

在redis.io网站上的官方文档内存优化中,其中有一条建议是在32位模式下编译redis替代默认的64位实例。对于同样小于3GB的数据集,其在32位redis实例中要比在64位版本中的redis中小。

如果应用程序使用整数集合,只要总内存不超过4GB的最大限制,那么32位版本节省的内存是相当可观的。当存入不同大小和类型的值时,redis的32位和64位版本之间的百分比差异意味着节省的内存数量显著降低。对于那些使用集合的应用程序来说,它们较多的使用了字符串,因为64位的redis可能是更好的选择。这是因为在64位版本中的字符串拥有额外的空间及更高效的编码。

对于哈希数据结构来说,32位和64位redis实例并没有特别大的差异:

对于32位版本的redis列表来说,在32位限制之下,列表非常适合存储整数和浮点数:

对于redis集合的测试如下:

1) 32位的redis并未在redis用户群中进行广泛部署和测试,因此相较于64位版本可能会有未发现的bug。

2) 诸如bittop、bitcount这样的位操作基于redis的64位版本进行了优化,因此相较于32位则没有那么高效。

3) 在32位redis中设置maxmemory参数更加困难,如果在32位版本的redis中的maxmemory值设置的过于靠近最大值4GB,那么通信、主从复制、I/O缓存都有可能随时导致redis崩溃。

info meory

10.143.128.165:6379> info memory
# Memory
used_memory:819312
used_memory_human:800.11K
used_memory_rss:1904640
used_memory_peak:2282784
used_memory_peak_human:2.18M
used_memory_lua:36864
mem_fragmentation_ratio:2.32
mem_allocator:jemalloc-3.6.0

used_memory    分配的字节数大小

used_memory_human 将used_memory格式化为人类可读的值

used_memory_rss    常驻集大小(resident set size) 操作系统中看到的内存分配,

以及top显示的结果

used_memory_peak    redis使用的峰值内存

used_memory_peak_human    将used_memory_peak可视化

used_memory_lua                    redis的lua子系统使用的字节数

mem_fragmentation_ratio        used_memory_rss与used_memory的比率

mem_allocator                        在编译器redis使用的分配器

键过期

保证redis数据库不会超过可用内存---为键设置超时时间,一旦过了键的超时时限,键就会被自动驱逐。

当在键上调用EXPIRE命令设置过期时间时,该超时只能通过删除或者替换键的方式清除。之后,任何改变值的命令都是无法更改或者清楚之前设置的超时的。

10.143.128.165:6379> set name yinn
OK
10.143.128.165:6379> expire name 60
(integer) 1
10.143.128.165:6379> get name
"yinn"
10.143.128.165:6379> ttl name
(integer) 53
10.143.128.165:6379> append name nana
(integer) 8
10.143.128.165:6379> get name
"yinnnana"
10.143.128.165:6379> get name
(nil)

如果在设置了超时的键上调用set或者getset(键过期之前),那么超时会被清除,键不会从数据库中驱逐:

10.143.128.165:6379> set name yin
OK
10.143.128.165:6379> expire name 30
(integer) 1
10.143.128.165:6379> set name xian
OK
10.143.128.165:6379> ttl name
(integer) -1

也可以使用 persist 命令清楚键上的超时设定:

10.143.128.165:6379> set name yinn
OK
10.143.128.165:6379> expire name 60
(integer) 1
10.143.128.165:6379> ttl name
(integer) 51
10.143.128.165:6379> persist name
(integer) 1
10.143.128.165:6379> ttl name
(integer) -1

在一个已经设置过超时的键上调用expire命令将会清楚并重新设定超时:

10.143.128.165:6379> expire name 90
(integer) 1
10.143.128.165:6379> ttl name
(integer) 87
10.143.128.165:6379> expire name 20
(integer) 1
10.143.128.165:6379> ttl name
(integer) 17
10.143.128.165:6379> get name
(nil)

LRU键驱逐策略

通过maxmemory指令将最大内存设置为1MB以创建一个小内存的redis实例。maxmemory指令允许设定内存大小的硬性上限,运行时的redis实例受限于此。

10.143.128.165:6379> flushall   ##清楚数据库
OK
10.143.128.165:6379>config set maxmemory 1024
OK

当redis内存耗尽时,默认生效的是永不过期策略(noeviction policy):

默认的maxmemory-policy策略是永不过期。在noeviction策略中,没有键设置为过期。如果redis没有可用内存,任何写操作都会导致redis错误。

10.143.128.165:6379> config get maxmemory
1) "maxmemory"
2) "1024
10.143.128.165:6379>config get maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"

第一种过期LRU策略名为 volatile-lru,它将最近较少使用的键驱逐出去。这些键必须通过 expire set 命令设置了超时的。当redis内存耗尽时,redis开始删除那些设置了过期时间的键,即便该键仍然有剩余时间。

下一个策略是 allkeys-lru ,会删除redis中任何一个键,而且没有办法限制哪些键被删除。

redis的LRU算法是不准确的,因为redis并不会自动选择最佳的候选键来驱逐,例如最少使用的键或者最早访问的键。相反,redis默认行为是选取5个键的samples,并驱逐当中最少使用的那个。如果想要增加LRU算法的精确性,可以更改redis.conf文件中的maxmemory-samples指令,或者在运行时通过config set maxmemory-samples命令进行设置。

将maxmemory-samples增加到10,从而提升redisLRU算法的性能,效果接近真实LRU算法,但是副作用就是消耗更多的CPU计算能力。将maxmemory-samples降至3,从而减少了redisLRU算法的精确性,不过相应地加快了处理速度。

接下来是两种最大内存驱逐策略:volatile-random和allkeys-random。它们与volatile-lru和allkeys-lru相似,但是不采用LRU算法。volatile-random 基于键上设置的过期状态随机驱逐一个键,需要O(n)时间复杂度的操作来计算创建的这些键是否已被驱逐对于allkeys-random,整个键空间都是开放的。

最后一个最大内存策略是volatile-ttl,redis会尝试根据键的剩余时间(TTL)清除键。

创建内存高效的redis数据结构

小巧的哈希、列表、集合、有序集合

对于哈希、列表、有序集合来说,这种特殊编码方法基于ziplist(压缩列表):

压缩列表是一种特殊的双向链表,专为内存高效进行设计的。它存储了字符串和整数值,其中整数是以真正的整数值而非字符串形式进行存储的。它允许在列表的任意一端以O(1)时间复杂度进行push和pop操作。但是,由于每次操作都需要为ziplist使用的内存进行重新分配,实际上的复杂度与ziplist所使用的内存大小有关。

根据大小、类型以及数据结构的内容,ziplist编码方式为redis数据库极大地节约了内存使用。

redis中ziplist的实现通过为每个节点只存储3份数据实现较小的内存占用:第一份是前一个节点的长度,第二份是当前节点的长度,第三份是存储的值

对于哈希表来说,hash-max-ziplist-entries 指令设置了总共有多少字段是可以被特殊编码为ziplist,默认是512。hash-max-ziplist-value指令设置了从ziplist转变为哈希表所要达到的最大大小,默认64.

把位、字节和redis字符串用作随机访问数组

在集合中通过使用整数代替字符串,可以将集合的大小显著地降低,但是 位图仍然要比集合小一个数量级、更节省内存。

优化哈希,高效存储

待续P90

转载于:https://my.oschina.net/u/1862478/blog/1935253

《深入理解redis》之三:内存管理的建议与技巧相关推荐

  1. 【死磕 Redis】------ 理解 Redis 的内存

    原文:https://www.topjava.cn/category/1391389927996002304 『chenssy』 我们知道 Redis 的所有数据都存储在内存中,内存是我们系统中的一个 ...

  2. 深入redis内部--内存管理

    2019独角兽企业重金招聘Python工程师标准>>> 深入redis内部--内存管理 博客分类: 缓存 1. Redis内存管理通过在zmalloc.h和zmalloc.c中重写c ...

  3. C语言文件联系人管理碎片整理,深入理解C语言内存管理.docx

    深入理解C语言内存管理 之前在学Java的时候对于Java虚拟机中的内存分布有一定的了解,但是最近在看一些C,发现居然自己对于C语言的内存分配了解的太少. 问题不能拖,我这就来学习一下吧,争取一次搞定 ...

  4. redis 数据结构 内存管理 持久化

    为什么80%的码农都做不了架构师?>>>    Redis 内存数据结构与编码 OBJECT encoding key.DEBUG OBJECT key 简单动态字符串(simple ...

  5. (转载)深入理解Linux中内存管理---分段与分页简介

    首先,必须要阐述一下这篇文章的主题是Linux内存管理中的分段和分页技术. 来回顾一下历史,在早期的计算机中,程序是直接运行在物理内存上的.换句话说,就是程序在运行的过程中访问的都是物理地址.如果这个 ...

  6. 【软件开发底层知识修炼】三 深入浅出处理器之三 内存管理与内存管理单元(MMU)

    学习交流加 个人qq: 1126137994 个人微信: liu1126137994 学习交流资源分享qq群: 962535112 上一篇文章学习了中断的概念与意义,以及中断的应用-断点调试原理.点击 ...

  7. Android内存管理优化建议

    OOM(OutOfMemory) 前面我们提到过使用getMemoryClass()的方法可以得到Dalvik Heap的阈值.简要的获取某个应用的内存占用情况可以参考下面的示例( 关于更多内存查看的 ...

  8. 深入理解Linux内核---内存管理zone

    转载:https://blog.csdn.net/gatieme/article/details/52384529 https://blog.csdn.net/gatieme/article/deta ...

  9. C语言与JAVA内存管理_深入理解C语言内存管理

    之前在学Java的时候对于Java虚拟机中的内存分布有一定的了解,但是最近在看一些C,发现居然自己对于C语言的内存分配了解的太少. 问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及 ...

最新文章

  1. 替换 RHEL5的yum源为CentOS5源,亲测线上系统可用
  2. 缩短网址将成微博的重要安全性问题
  3. 【DIY】联想单板机、联想UPS电源、联想屏幕打造笔记本电脑
  4. 题目3:文本文件单词的检索与计数(实现代码)
  5. java swing 案例详解_《Java Swing图形界面开发与案例详解》PDF_IT教程网
  6. 中断函数 printf_嵌入式中断服务函数的一些特点
  7. 三星要带头了!考虑明年手机不送充电器
  8. 电脑无法读取移动硬盘_移动硬盘U盘提示:文件或目录损坏且无法读取如何解决?...
  9. python画曲线图-python怎么画曲线图
  10. latex_列表和表格环境_给tabular加lable标签问题
  11. 半功率点为啥是-3dB
  12. ARIMA模型的定阶原理与建模分析
  13. 人工智能时代孩子该学点什么?
  14. RT-Thread 4.1.0 开启 PM 电源管理框架
  15. SpringCloud微服务注册和消费模式总结
  16. 放榜!腾讯iOA、腾讯天幕入选国内数字化可信服务首批认证产品
  17. 技术揭秘12306改造(二):探讨12306两地三中心混合云架构
  18. 国产数据库岁末大盘点
  19. Fiddler 的几个用法
  20. Android File System安卓文件系统(安卓存储分区,/data /storage /sdcard)

热门文章

  1. 获取的字段值是空值或者为null,而你自己的需求就是想要获取的字段为一个 * 默认的值
  2. 已解决mybatis报错:Invalid bound statement (not found)
  3. 基因组注释1. 重复序列repeatmasker, trf
  4. 与思科交换机三层链路聚合连接 ❀ 飞塔 (Fortinet) 防火墙
  5. b站网页html,bilibili注册页面html简单分析
  6. 公交管理系统的设计与实现
  7. 实战五十三:基于机器学习随机森林的购房贷款违约预测(完整代码+数据集)
  8. 北航计算机学院保研占比,许明杰:CSP助力保研入北航
  9. win10如何设置pdf默认打开方式
  10. AT指令(中文详解版)(二)