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 ...
随机推荐
- iOS开发-UIImageView响应点击事件
UIImageView是不能够响应点击事件的,在开发过程中我们需要经常对头像等添加点击事件,上网搜索一番后发现有如下两个方法: 1.找到点击图片Event,添加事件处理函数 UIImageView.u ...
- SpringMVC系列之主要组件
一.组件说明 DispatcherServlet:前端控制器,用于请求到达前端控制器,由它调用其他组件处理用户的请求. HandlerMapping:处理器映射器,负责根据用户请求找到Handler( ...
- iOS - UITableViewStylePlain与UITableViewStyleGroup样式的对比
一.UITableViewStylePlain 1.有多段时 段头停留(自带效果) 2.没有中间的间距和头部间距(要想有的重写UITableViewCell \UITableViewHeaderFoo ...
- Android学习之DatePicker和TimePicker
在Android开发的应用程序中,通常都会有时间和日期选择的需求,下面就对日期选择控件DatePicker和时间选择控件TimePicker的基本使用方法进行介绍: DatePicker ...
- HipHop的原理
HipHop的原理 HipHop将PHP代码转换为高度优化的C++代码,然后再用g++编译器编译.它可以保持语义等效地执行源代码,但为了提高性能,牺牲了一些很少用到的特性,比如eval(). HipH ...
- ida+windbg调试windows
jpg 改 pdf https://www.hex-rays.com/products/ida/support/tutorials/debugging_windbg.pdf
- open-falcon之dashboard\portal说明.md
dashboard 功能 为用户展示监控数据 配置文件 gunicorn.conf - workers,dashboard并发进程数 - bind,dashboard的http监听端口 - proc_ ...
- 云计算设计模式(六)——命令和查询职责分离(CQRS)模式
云计算设计模式(六)——命令和查询职责分离(CQRS)模式 隔离,通过使用不同的接口,从操作读取数据更新数据的操作.这种模式可以最大限度地提高性能,可扩展性和安全性;支持系统在通过较高的灵活性,时间的 ...
- 原生js--文档加载时间
onload触发时机:文档和所有的图片都加载完毕 DOMContentLoaded触发时机:文档加载并解析完毕,所有deferred脚本执行完毕.但此时图片和async脚本可能依旧在加载. ready ...
- sencha touch 监听视图切换动画(animation)
var animation = this.getLayout().getAnimation(); //添加监听 animation.on({ scope: this, animationend: 'o ...