设为首页 收藏本站
查看: 463|回复: 0

[经验分享] Redis细节积累

[复制链接]

尚未签到

发表于 2016-12-18 08:13:13 | 显示全部楼层 |阅读模式
Redis细节积累


  本文主要说明一些redis优点和缺点以免网站架构时乱用
  一、优点




  • key/value存储支持丰富的数据结构操作(list、set、map等操作)
  • 支持批量的操作,减少网络的开销
  • 支持replication机制,弥补了aof、snapshot性能上不足,达到了数据可持久化
  • 支持虚拟内存,没有开来操作系统的虚拟内存管理,而是自己开发封装,具体原因参考:http://blog.nosqlfan.com/html/868.html?ref=rediszt
  二、缺点




  • 是基于内存管理,也就是自己申请内存管理数据,当进程重启或者挂了就会丢失数据,所以可以考虑使用内存文件系统,只要系统部重启数据不会丢失,细节参见:http://blog.nosqlfan.com/html/3638.html
  • 关于使用hashtable的时候,当数据达到zimap数据的临界值的时候,有一次rehash的扩容,这个时间点会有性能上的缺陷,只是个人看源代码的想法,欢迎指教
  • 复制机制的缺陷:没有像MySQL那样有复制位置的概念,即无增量复制,这会给整个集群搭建带来非常多的问题。详细见:http://blog.nosqlfan.com/html/3153.html?ref=rediszt
  三、redis复制缺陷的解决方案





  • 主动复制避开Redis复制缺陷
  我们可以采用主动复制的方式来搭建我们的集群环境,所谓主动复制是指由业务端或者通过代理中间件对Redis存储的数据进行双写或多写,通过数据的多份存储来达到与复制相同的目的。但是会造成数据一致性问题,这样需要看项目的应用场景是否对数据一致性要求高不高



  • 通过presharding进行Redis在线扩容
  resharding的方案来解决动态扩容和数据分区的问题,实际就是在同一台机器上部署多个Redis实例的方式,当容量不够时将多个实例拆分到不同的机器上,这样实际就达到了扩容的效果。但是实际还是依赖redis的复制功能,所以做这个拆分的过程最好选择为业务访问低峰时段进行。



  • Redis复制的改进
  首先写Redis的AOF文件,并对这个AOF文件按文件大小进行自动分割滚动,同时关闭Redis的Rewrite命令,然后会在业务低峰时间进行内存
快照存储,并把当前的AOF文件位置一起写入到快照文件中,这样我们可以使快照文件与AOF文件的位置保持一致性,这样我们得到了系统某一时刻的内存快
照,并且同时也能知道这一时刻对应的AOF文件的位置,那么当从库发送同步命令时,我们首先会把快照文件发送给从库,然后从库会取出该快照文件中存储的
AOF文件位置,并将该位置发给主库,主库会随后发送该位置之后的所有命令,以后的复制就都是这个位置之后的增量信息了。



  • Redis与MySQL的结合
  四、内存优化



hash-max-zipmap-entries 64
hash-max-zipmap-value 512
hash-max-zipmap-entries

  当value这个Map内部不超过多少个成员时会采用线性紧凑格式存储,默认是64,即value内部有64个以下的成员就是使用线性紧凑存储,超过该值自动转成真正的HashMap。

  hash-max-zipmap-value 含义是当 value这个Map内部的每个成员值长度不超过多少字节就会采用线性紧凑存储来节省空间。
  以上2个条件任意一个条件超过设置值都会转换成真正的HashMap,也就不会再节省内存了,那么这个值是不是设置的越大越好呢,答案当然是否定
的,HashMap的优势就是查找和操作的时间复杂度都是O(1)的,而放弃Hash采用一维存储则是O(n)的时间复杂度,如果成员数量很少,则影响不大,否则会严重影响性能,所以要权衡好这个值的设置,总体上还是最根本的时间成本和空间成本上的权衡。
  同理list:

list-max-ziplist-entries 512
set-max-intset-entries 512
  不过如果在Redis内部存储的大部分数据是数值型的话,Redis内部采用了一个shared
integer的方式来省去分配内存的开销,即在系统启动时先分配一个从1~n
那么多个数值对象放在一个池子中,如果存储的数据恰好是这个数值范围内的数据,则直接从池子里取出该对象,并且通过引用计数的方式来共享,这样在系统存储
了大量数值下,也能一定程度上节省内存并且提高性能,这个参数值n的设置需要修改源代码中的一行宏定义REDIS_SHARED_INTEGERS,该值
默认是10000,可以根据自己的需要进行修改,修改后重新编译就可以了。
  有Redis线上运维经验的人会发现Redis在物理内存使用比较多,但还没有超过实际物理内存总容量时就会发生不稳定甚至崩溃的问题,有人认为是
基于快照方式持久化的fork系统调用造成内存占用加倍而导致的,这种观点是不准确的,因为fork
调用的copy-on-write机制是基于操作系统页这个单位的,也就是只有有写入的脏页会被复制,但是一般你的系统不会在短时间内所有的页都发生了写
入而导致复制,那么是什么原因导致Redis崩溃的呢?
  答案是Redis的持久化使用了Buffer IO造成的,所谓Buffer
IO是指Redis对持久化文件的写入和读取操作都会使用物理内存的Page Cache,而大多数数据库系统会使用Direct
IO来绕过这层Page
Cache并自行维护一个数据的Cache,而当Redis的持久化文件过大(尤其是快照文件),并对其进行读写时,磁盘文件中的数据都会被加载到物理内
存中作为操作系统对该文件的一层Cache,而这层Cache的数据与Redis内存中管理的数据实际是重复存储的,虽然内核在物理内存紧张时会做
Page Cache的剔除工作,但内核很可能认为某块Page Cache更重要,而让你的进程开始Swap
,这时你的系统就会开始出现不稳定或者崩溃了。我们的经验是当你的Redis物理内存使用超过内存总容量的3/5时就会开始比较危险了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-315737-1-1.html 上篇帖子: Redis入门教程 下篇帖子: redis 数据读取
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表