原文: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经验谈(转)的更多相关文章

  1. Redis经验谈

    新浪作为全世界最大的Redis用户,在开发和运维方面有非常多的经验.本文作者来自新浪,希望能为业界提供一些亲身经历,让大家少走弯路. 使用初衷 从2010年上半年起,我们就开始尝试使用Redis,主要 ...

  2. Remoting,OData Snippet Compiler等

    http://www.sliver.com/dotnet/SnippetCompiler/ [ASP.NET Web API教程]ASP.NET Web API系列教程目录 张逸 .Net Remot ...

  3. Hadoop、Pig、Hive、Storm、NOSQL 学习资源收集

    (一)hadoop 相关安装部署 1.hadoop在windows cygwin下的部署: http://lib.open-open.com/view/1333428291655 http://blo ...

  4. Hadoop、Pig、Hive、NOSQL 学习资源收集

    转自:http://www.cnblogs.com/zzjhn/p/3855566.html (一)hadoop 相关安装部署 1.hadoop在windows cygwin下的部署: http:// ...

  5. REDIS基础笔记

    Redis基础笔记 资源链接 简介 简介 安装 五种数据类型及相应命令 1. 字符串类型 2. 散列类型 3. 列表类型 4. 集合类型 5. 有序集合 其他 事务 SORT 生存时间 任务队列 发布 ...

  6. 使用redis构建可靠分布式锁

    关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...

  7. Ignite性能测试以及对redis的对比

    测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...

  8. mac osx 安装redis扩展

    1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis   ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...

  9. Redis/HBase/Tair比较

    KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式    支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...

随机推荐

  1. pojo与DTO的区别

    ational Mapping(对象关系映射)的缩写.通俗点讲,就是将对象与关系数据库绑定,用对象来表示关系数据.在O/R Mapping的世界里,有两个基本的也是重要的东东需要了解,即VO,PO. ...

  2. [转]window下使用SetUnhandledExceptionFilter捕获让程序的崩溃

    简单使用SetUnhandledExceptionFilter()函数让程序优雅崩溃 虽然是大公司的产品,QQ它还是会在我们的折腾下崩溃的,但是它总是崩溃的很优雅,还要弹出自己的对话框来结束.并且发送 ...

  3. codeforces水题100道 第十八题 Codeforces Round #289 (Div. 2, ACM ICPC Rules) A. Maximum in Table (brute force)

    题目链接:http://www.codeforces.com/problemset/problem/509/A题意:f[i][1]=f[1][i]=1,f[i][j]=f[i-1][j]+f[i][j ...

  4. 详解SQL中的GROUP BY语句

    下面为您介绍SQL语句中GROUP BY 语句,GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组. 希望对您学习SQL语句有所帮助. SQL GROUP BY 语法 SELEC ...

  5. linux系统环境搭建

    一.安装jdk 参考帖子 用yum安装JDK(CentOS) 1.查看yum库中都有哪些jdk版本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [r ...

  6. 《转》python学习(11)-表达式和语句

    转自 http://www.cnblogs.com/BeginMan/p/3164600.html 一.Python语句 if语句.else语句.elif语句.条件表达式.while语句.for语句. ...

  7. 大智慧F10离线资料压缩包带F10关键字过滤软件--更新于2014-01-06.rar 184MB

    大智慧F10离线资料包带F10关键字过滤软件--更新于2014-01-06.rar 移步到百度网盘下载: http://pan.baidu.com/s/1c01PDnE

  8. Delphi应用程序的调试(六)步进式代码调试

    步进式代码调试(Stepping Through Your Code) 步进式代码调试是最基本的调试操作之一,但仍要在此讲述.人们常常容易犯只见树木不见森林的错误.经常复习基本的知识有助于读者了解以前 ...

  9. css笔记 - 张鑫旭css课程笔记之 z-index 篇

    一.z-index语法.支持的属性值等 z-index: 在支持z-index的元素上, z-index规定了元素(包括子元素)的垂直z方向的层级顺序, z-index可以决定哪个元素覆盖在哪个元素上 ...

  10. Autojump:一个可以在 Linux 文件系统快速导航的高级 cd 命令

    相关博客:https://linux.cn/article-3401-1.html 对于那些主要通过控制台或终端使用 Linux 命令行来工作的 Linux 用户来说,他们真切地感受到了 Linux ...