Redis经验谈(转)
原文:http://www.programmer.com.cn/14577/
新浪作为全世界最大的Redis用户,在开发和运维方面有非常多的经验。本文作者来自新浪,希望能为业界提供一些亲身经历,让大家少走弯路。
使用初衷
从2010年上半年起,我们就开始尝试使用Redis,主要出于以下几方面的考虑。
- 性能比MySQL好。因为业务的发展对性能的需求越来越强烈。
- 丰富的数据类型。在速度就是市场的互联网时代,快速开发是一个不变的需求。
- Cache宕机让人纠结,Redis有半持久化和持久化两种方式,能从某种程度上解决这个问题,以减少Cache宕机带来的雪崩效应。
- 在部分业务场景中,使用MySQL+Memcached存在一致性问题,若使用Redis替代,能降低整体架构复杂度。
完善过程
在开始应用Redis时,规模比较小,数据量也很小,没有遇到太多的问题。而随着数据量的增加,遇到了很多问题。总结一句话就是,当数据量变大时,以前不是问题的问题都变成了问题。
Master/Slave同步问题
首先遇到的是Master/Slave的同步问题。它的原理是Slave做了Slaveof之后,向Master发送一个Sync,Master把 内存的数 据Dump出来,形成rdb文件,然后传到Slave,Slave把这个文件加载到内存,完成之后Master向Slave发送新数据包。
在网络出现问题时,比如瞬断,会导致Master里的数据全部重传。对单个端口来说,如果数据量小,那么这个影响不大,而如果数据量比较大的话,则 会导致网 络瞬间流量暴增,同时在同步时Slave做不了读操作。我们对其进行了修改,加入Position的概念来解决这个问题,确保在网络出现问题时不会重传所 有数据,只重传断开时后面的数据。
aof的定期归档问题
Redis默认产生的aof文件需要手工做 bgrewrite-aof,这个操作产生的lock会对写产生一定的影响。因此,我们最开始用脚本在凌晨业务低峰时进行这个操作。而随着数量的增 加,lock的时间越来越不能被业务接受。我们对源代码进行了修改,将bgrewriteaof放到Redis内部去实现,在配置文件内制定执行时间,让 这个操作自动执行,并且不会导致写产生的lock问题。
同时,我们还将aof设计得与MySQL的binlog类似,设定每个aof的大小,在达到一定值时,会自动产生一个新的aof。
Mytrigger和MytriggerQ的设计
业务有这样的需求:应用按用户维度写入数据,统计用户的记录数(如关注数、粉丝数)时,需要从数据库中执行count(*)操作。在InnoDB中 执行这个 相对较慢,而增加Cache方案又满足不了业务对实时性的要求。因此,我们开发了Mytrigger组件来读取MySQL的binlog,然后通过业务逻 辑转化写入Redis。
例如,MySQL中存每条记录,Redis中存按用户维度的记录总和。这样实现之后,应用从MySQL中读取数据,从Redis里读取记录条数,MySQL的压力降低很多,同时计数读取性能提高了很多。
如果应用是数据的写入方,那么它需要将数据写入数据库,同时需要把这些新增或变更通知给另一个应用,另一个应用获得这些新增或更新后开始做自己的业务逻辑处理。
刚开始,我们采用了写数据库的同时再写一份MemcacheQ的方法,后来更换为MytriggerQ读取MySQL的binlog,将读取到的数 据转化为 队列。需要了解数据变化的业务通过读取这个MytriggerQ服务来获取数据的变化。这样,应用只用写一次,简化了应用架构的复杂度。
容量设计
在申请使用Redis之前,我们会对业务进行评估。通过填写预计容量和性能需求表格,我们能算出Redis占用的内存量,确保单个端口的数据量不高于机器内存的三分之一。
当前,我们使用的是96GB的内存型机型,每个端口最终容量控制在30GB以下。当业务需求的容量超过机器最大内存时,采用的拆分方式是Hash到 多个端 口,通过基准测试得出在容量允许的情况下,一台机器部署2个实例、4个实例或8个实例的最大性能,预留20%的容量用于增长,根据业务指标计算出需要的资 源数。
使用了Redis自身的过期策略之后,发现存入Redis的数据有可能出现即使还有大量内存没有使用,Redis还会让key过期去释放内存,或者内存不足时key还没有过期的问题。
对于过期的数据,我们采用清理和滚动两种方式。清理容易出现内存碎片;滚动即建两组端口,同时写两组端口。比如要保留3个月的数据,那么每个断开保 留6个月 的数据,两个同时写,使用奇数端口,在第4个月时,把读写切换到偶数端口,同时清理奇数端口里的数据,但使用这种方式带来了很高的维护成本。
应用场景
做Cache还是做Storage是我们一直在思考的问题。Redis有持久化和半持久化两种方式,但即使这样,所有Redis的数据都在内存中。大数据量存储时,数据类型的优势将越来越不明显。
当数据量小时,可以不用做过多考虑,因为一切都不是问题,可以利用其丰富的数据类型带来业务的快速开发和上线;数据量总量和增加量都相对可控,数据 比较精细 可以使用Redis做存储。例如,用户维度的计数就用Redis来做Storage。但对于对象维度,如微博维度的数据使用Redis做Cache。
有些业务的容量增长过快,与之前的预计有出入,且所有的数据都在内存中,没有冷热区分(降低存储最好的办法就是分级存储),我们就将这部分不再适合 放在 Redis的业务使用新的方案代替。例如把它替换成MySQL+Memcached的方式。因为每次做滚动切换的方案运维成本和硬件成本投入都很高,所以 可使用HandlerSocket来替换。例如,前6个月的数据放在Redis中,之后的数据放到MySQL中,在减少切换的同时也能降低运维成本。
未来的计划
随着机器规模的不断增加,可用性和自动化需求越来越强烈,目前我们正在结合ZooKeeper设计Redis的自动切换,同时提高Redis自动化 维护需 求。我们会开发一个高速数据访问框架和管理系统,将故障切换、数据拆分逻辑和自动数据迁移放到里面,实现其应用的产品化。希望走过的这些路对大家在使用 Redis的过程中有所帮助。
作者杨海朝,新浪首席DBA,在大规模高并发、海量访问方面有丰富的管理经验。热衷于整体架构、数据库设计、性能优化、分布式部署方案和高可用性方面的研究。
Redis经验谈(转)的更多相关文章
- Redis经验谈
新浪作为全世界最大的Redis用户,在开发和运维方面有非常多的经验.本文作者来自新浪,希望能为业界提供一些亲身经历,让大家少走弯路. 使用初衷 从2010年上半年起,我们就开始尝试使用Redis,主要 ...
- Remoting,OData Snippet Compiler等
http://www.sliver.com/dotnet/SnippetCompiler/ [ASP.NET Web API教程]ASP.NET Web API系列教程目录 张逸 .Net Remot ...
- Hadoop、Pig、Hive、Storm、NOSQL 学习资源收集
(一)hadoop 相关安装部署 1.hadoop在windows cygwin下的部署: http://lib.open-open.com/view/1333428291655 http://blo ...
- Hadoop、Pig、Hive、NOSQL 学习资源收集
转自:http://www.cnblogs.com/zzjhn/p/3855566.html (一)hadoop 相关安装部署 1.hadoop在windows cygwin下的部署: http:// ...
- REDIS基础笔记
Redis基础笔记 资源链接 简介 简介 安装 五种数据类型及相应命令 1. 字符串类型 2. 散列类型 3. 列表类型 4. 集合类型 5. 有序集合 其他 事务 SORT 生存时间 任务队列 发布 ...
- 使用redis构建可靠分布式锁
关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...
- Ignite性能测试以及对redis的对比
测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...
- mac osx 安装redis扩展
1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...
- Redis/HBase/Tair比较
KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式 支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...
随机推荐
- [XPath] XPath 与 lxml (四)XPath 运算符
XPath 中支持的运算符 # | 或: 返回所有 price 和 title 节点集合 >>> root.xpath('//price|//title') [<Element ...
- mybayis 之resultType="map"
List<Map> publishInfos = memberShareMapper.shareToCouponCountGroupByPublishId(memberShare.getA ...
- (原创)使用mceusb设备,将lirc移植到android笔记
首先说一下大环境和总体步骤: 下载lirc 0.8.7源码,使用ubuntu的setup.sh,配置为mceusb的驱动,同时Compile tools for X-Windows选项去掉,生成con ...
- stylus--css 框架使用方法
Stylus是一款需要编译的css语言,所以其本身文件不能被html直接调用,需要要编译为css文件后再进行日常的加载. stylus是一款优秀的css编译语言,需要node.js支持,第一步需要 ...
- 原生js--鼠标事件
鼠标事件对象几个重要的属性: clientX 窗口坐标,加上垂直滚动可以得到文档纵坐标 clientY 窗口坐标,加上水平滚动可以得到文档横坐标 altKey boolean值,点击时是否按下了alt ...
- RDMA卡的检测方法
1. udaddy This script covers RDMA_CM UD connections. (It establishes a set of unreliable RDMA datagr ...
- Android aapt使用小结
Android打包成Apk后,其实是一个压缩文件,我们用winrar打开也能看到里面的文件结构.还能看到AndroidManifest.但是里面的内容有点问题. 不知道是因为加密还是Android就是 ...
- Spring加载xsd文件报错:because 1) could not find the document; 2) the document could not be read...
Spring启动时加载xml文件的过程: spring在加载xsd文件时总是先试图在本地查找xsd文件(spring的jar包中已经包含了所有版本的xsd文件),如果没有找到,才会转向去URL指定的路 ...
- 【Win】使用L2TP出现809错误
1.环境:win7/10 2.解决: a.修改注册表(新建一个文本文件,复制以下内容,保存后文件扩展名改为.reg,双击运行文件.) Windows Registry Editor Version 5 ...
- vs2010版本注释
转:http://www.cnblogs.com/chaselwang/p/3580839.html 关于Visual Studio 20**自动添加头部注释信息 作为一个万年潜水党,不关这一篇文章技 ...