Redis使⽤场景举例
redis支持的数据结构1.新浪微博:史上最⼤的Redis集
随着应⽤对⾼性能需求的增加,NoSQL逐渐在各⼤名企的系统架构中⽣根发芽。这⾥我们将为⼤家分享社交巨头新浪微博带来的Redis实践,⾸先我们看新浪微博 @启盼cobain的Redis实战经验分享:
Tape is Dead,Disk is Tape,Flash is Disk,RAM Locality is King. — Jim Gray
Redis不是⽐较成熟的或者的替代品,是对于⼤型互联⽹类应⽤在架构上很好的补充。现在有越来越多的应⽤也在纷纷基于Redis做架构的改造。⾸先简单公布⼀下Redis平台实际情况:
2200+亿 commands/day 5000亿Read/day 500亿Write/day
18TB+ Memory
500+ Servers in 6 IDC 2000+instances
应该是国内外⽐较⼤的Redis使⽤平台,今天主要从应⽤⾓度谈谈平台。
Redis使⽤场景
1.Counting(计数)
计数的应⽤在另外⼀篇⽂章⾥较详细的描述,计数场景的优化 /?p=262这⾥就不多加描述了。
可以预见的是,有很多同学认为把计数全部存在内存中成本⾮常⾼,我在这⾥⽤个图表来表达下我的观点:
很多情况⼤家都会设想纯使⽤内存的⽅案会很有很⾼成本,但实际情况往往会有⼀些不⼀样:
COST,对于有⼀定吞吐需求的应⽤来说,肯定会单独申请DB、Cache资源,很多担⼼DB写⼊性能的
同学还会主动将DB更新记⼊异步队列,⽽这三块的资源的利⽤率⼀般都不会太⾼。资源算下来,你惊异的发现:反⽽纯内存的⽅案会更精简!
KISS原则,这对于开发是⾮常友好的,我只需要建⽴⼀套连接池,不⽤担⼼数据⼀致性的维护,不⽤维护异步队列。
Cache穿透风险,如果后端使⽤DB,肯定不会提供很⾼的吞吐能⼒,cache宕机如果没有妥善处理,那就悲剧了。
⼤多数的起始存储需求,容量较⼩。
2.Reverse cache(反向cache)
⾯对微博常常出现的热点,如最近出现了较为⽕爆的短链,短时间有数以万计的⼈点击、跳转,⽽这⾥会常常涌现⼀些需求,⽐如我们向快速在跳转时判定⽤户等级,是否有⼀些账号绑定,性别爱好什么的,已给其展⽰不同的内容或者信息。
普通采⽤memcache+Mysql的解决⽅案,当调⽤id合法的情况下,可⽀撑较⼤的吞吐。但当调⽤id不可控,有较多垃圾⽤户调⽤时,由于memcache未有命中,会⼤量的穿透⾄Mysql服务器,瞬间造成连接数疯长,整体吞吐量降低,响应时间变慢。
这⾥我们可以⽤redis记录全量的⽤户判定信息,如string key:uid int:type,做⼀次反向的cache,当⽤户在redis快速获取⾃⼰等级等信息后,再去Mc+Mysql层去获取全量信息。如图:
当然这也不是最优化的场景,如⽤Redis做bloomfilter,可能更加省⽤内存。
3.Top 10 list
产品运营总会让你展⽰最近、最热、点击率最⾼、活跃度最⾼等等条件的top list。很多更新较频繁的列表如果使⽤MC+MySQL维护的话缓存失效的可能性会⽐较⼤,鉴于占⽤内存较⼩的情况,使⽤Redis做存储也是相当不错的。
4.Last Index
⽤户最近访问记录也是redis list的很好应⽤场景,lpush lpop⾃动过期⽼的登陆记录,对于开发来说还是⾮常友好的。
5.Relation List/Message Queue
这⾥把两个功能放在最后,因为这两个功能在现实问题当中遇到了⼀些困难,但在⼀定阶段也确实解决了我们很多的问题,故在这⾥只做说明。
Message Queue就是通过list的lpop及lpush接⼝进⾏队列的写⼊和消费,由于本⾝性能较好也能解决⼤部分问题。
6.Fast transaction with Lua
Redis 的Lua的功能扩展实际给Redis带来了更多的应⽤场景,你可以编写若⼲command组合作为⼀个⼩型的⾮阻塞事务或者更新逻辑,如:在收到message推送时,同时1.给⾃⼰的增加⼀个未读的对话 2.给⾃⼰的私信增加⼀个未读消息 3.最后给发送⼈回执⼀个完成推送消息,这⼀层逻辑完全可以在Redis Server端实现。
但是,需要注意的是Redis会将lua script的全部内容记录在aof和传送给slave,这也将是对磁盘,⽹卡⼀个不⼩的开销。
7.Instead of Memcache
1. 很多测试和应⽤均已证明,
2. 在性能⽅⾯Redis并没有落后memcache多少,⽽单线程的模型给Redis反⽽带来了很强的扩展性。
3. 在很多场景下,Redis对同⼀份数据的内存开销是⼩于memcache的slab分配的。
4. Redis提供的数据同步功能,其实是对cache的⼀个强有⼒功能扩展。
Redis使⽤的重要点
1.rdb/aof Backup!
我们线上的Redis 95%以上是承担后端存储功能的,我们不仅⽤作cache,⽽更为⼀种k-v存储,他完全替代了后端的存储服务(MySQL),故其数据是⾮常重要的,如果出现数据污染和丢失,误操作等情况,将是难以恢复的。所以备份是⾮常必要的!为此,我们有共享的hdfs资源作为我们的备份池,希望能随时可以还原业务所需数据。
2.Small item & Small instance!
由于Redis单线程(严格意义上不是单线程,但认为对request的处理是单线程的)的模型,⼤的数据结构list,sorted set,hash set的批量处理就意味着其他请求的等待,故使⽤Redis的复杂数据结构⼀定要控制其单key-struct的⼤⼩。
另外,Redis单实例的内存容量也应该有严格的限制。单实例内存容量较⼤后,直接带来的问题就是故障恢复或者Rebuild从库的时候时间较长,⽽更糟糕的是,Redis rewrite aof和save rdb时,将会带来⾮常⼤且长的系统压⼒,并占⽤额外内存,很可能导致系统内存不⾜等严重影响性能的线上故障。我
们线上96G/128G内存服务器不建议单实例容量⼤于20/30G。
3.Been Available!
业界资料和使⽤⽐较多的是Redis sentinel(哨兵)
/en/latest/storage/redis_code_analysis/sentinel.html
qiita/wellflat/items/8935016fdee25d4866d9
2000⾏C实现了服务器状态检测,⾃动故障转移等功能。
但由于⾃⾝实际架构往往会复杂,或者考虑的⾓度⽐较多,为此 @许琦eryk和我⼀同做了hypnos项⽬。
hypnos是神话中的睡神,字⾯意思也是希望我们⼯程师⽆需在休息时间处理任何故障。:-)
其⼯作原理⽰意如下:
Talk is cheap, show me your code! 稍后将单独写篇博客细致讲下Hypnos的实现。
4.In Memory or not?
发现⼀种情况,开发在沟通后端资源设计的时候,常常因为习惯使⽤和错误了解产品定位等原因,⽽忽视了对真实使⽤⽤户的评估。也许这是⼀份历史数据,只有最近⼀天的数据才有⼈进⾏访问,⽽把历史数据的容量和最近⼀天请求量都抛给内存类的存储现实是⾮常不合理的。
所以当你在究竟使⽤什么样的数据结构存储的时候,请务必先进⾏成本衡量,有多少数据是需要存储在内存中的?有多少数据是对⽤户真正有意义的。因为这其实对后端资源的设计是⾄关重要的,1G的数据容量和1T的数据容量对于设计思路是完全不⼀样的
Plans in future?
1.slave sync改造
全部改造线上master-slave数据同步机制,这⼀点我们借鉴了MySQL Replication的思路,使⽤rdb+aof+pos作为数据同步的依据,这⾥简要说明为什么官⽅提供的psync没有很好的满⾜我们的需求:
假设A有两个从库B及C,及 A `— B&C,这时我们发现master A服务器有宕机隐患需要重启或者A节点直接宕机,需要切换B为新的主库,如果A、B、C不共享rdb及aof信息,C在作为B的从库时,仍会清除⾃⾝数据,因为C节点只记录了和A节点的同步状况。
故我们需要有⼀种将A`–B&C 结构切换切换为A`–B`–C结构的同步机制,psync虽然⽀持断点续传,但仍⽆法⽀持master故障的平滑切换。
实际上我们已经在我们定制的Redis计数服务上使⽤了如上功能的同步,效果⾮常好,解决了运维负担,但仍需向所有Redis服务推⼴,如果可能我们也会向官⽅Redis提出相关sync slave的改进。
2.更适合redis的name-system Or proxy
细⼼的同学发现我们除了使⽤DNS作为命名系统,也在zookeeper中有⼀份记录,为什么不让⽤户直接访问⼀个系统,zk或者DNS选择其⼀呢?
其实还是很简单,命名系统是个⾮常重要的组件,⽽dns是⼀套⽐较完善的命名系统,我们为此做了很多改进和试错,zk的实现还是相对复杂,我们还没有较强的把控粒度。我们也在思考⽤什么做命名系统更符合我们需求。
3.后端数据存储
⼤内存的使⽤肯定是⼀个重要的成本优化⽅向,flash盘及分布式的存储也在我们未来计划之中。(原⽂链接: Largest Redis Clusters Ever)
2.Pinterest:Reids维护上百亿的相关性
Pinterest已经成为硅⾕最疯故事之⼀,在2012年,他们基于PC的业务增加1047%,移动端采⽤增加1698%,该年3⽉其独⽴访问数量更飙升⾄533亿。在Pinterest,⼈们关注的事物以百亿记——每个⽤户界⾯都会查询某个board或者是⽤户是否关注的⾏为促成了异常复杂的⼯程问题。这也让Redis获得了⽤武之地。经过数年的发展,Pinterest已经成为媒体、社交等多个领域的佼佼者,其辉煌战绩如下:获得的推荐流量⾼于Google+、YouTube及LinkedIn三者的总和
与Facebook及Twitter⼀起成为最流⾏的三⼤社交⽹络
参考Pinterest进⾏购买的⽤户⽐其它⽹站更⾼
如您所想,基于其独⽴访问数,Pinterest的⾼规模促成了⼀个⾮常⾼的IT基础设施需求。
通过缓存来优化⽤户体验
近⽇,Pinterest⼯程经理Abhi Khune对其公司的⽤户体验需求及Redis的使⽤经验进⾏了分享。即使是
滋⽣的应⽤程序打造者,在分析⽹站的细节之前也不会理解这些特性,因此先⼤致的理解⼀下使⽤场景:⾸先,为每个粉丝进⾏提及到的预检查;其次,UI将准确的显⽰⽤户的粉丝及关注列表分页。⾼效的执⾏这些操作,每次点击都需要⾮常⾼的性能架构。
不能免俗,Pinterest的软件⼯程师及架构师已经使⽤了MySQL及memcache,但是缓存解决⽅案仍然达到了他们的瓶颈;因此为了拥有更好的⽤户体验,缓存必须被扩充。⽽在实际操作过程中,⼯程团队已然发现缓存只有当⽤户sub-graph已经在缓存中时才会起到作⽤。因此。任何使⽤这个系统的⼈都需要被缓存,这就导致了整个图的缓存。同时,最常见的查询“⽤户A是否关注了⽤户B”的da案经常是否定的,然⽽这却被作为了缓存丢失,从⽽促成⼀个数据库查询,因此他们需要⼀个新的⽅法来扩展缓存。最终,他们团队决定使⽤Redis来存储整个图,⽤以服务众多的列表。
使⽤Redis存储⼤量的Pinterest列表
Pinterest使⽤了Redis作为解决⽅案,并将性能推⾄了内存数据库等级,为⽤户保存多种类型列表:
关注者列表
你所关注的board列表
粉丝列表
关注你board的⽤户列表
某个⽤户中board中你没有关注的列表
每个board的关注者及⾮关注者
Redis为其7000万⽤户存储了以上的所有列表,本质上讲可以说是储存了所有粉丝图,通过⽤户ID分⽚。鉴于你可以通过类型来查看以上列表的数据,分析概要信息被⽤看起来更像事务的系统储存及访问。Pinterest当下的⽤户like被限制为10万,初略进⾏统计:如果每个⽤户关注25个board,将会在⽤户及board间产⽣17.5亿的关系。同时更加重要的是,这些关系随着系统的使⽤每天都会增加。
Pinterest的Reids架构及运营
通过Pinterest的⼀个创始⼈了解到,Pinterest开始使⽤Python及订制的Django编写应⽤程序,并⼀直持续到其拥有1800万⽤户级⽇410TB ⽤户数据的时候。虽然使⽤了多个存储对数据进⾏储存,⼯程师根据⽤户id使⽤了8192个虚拟分⽚,每个分⽚都运⾏在⼀个Redis DB之上,同时1个Redis实例将运⾏多个Redis DB。为了对CPU核⼼的充分使⽤,同⼀台主机上同时使⽤多线程和单线程Redis实例。
鉴于整个数据集运⾏在内存当中,Redis在Amazon EBS上对每秒传输进来的写⼊都会进⾏持久化。扩展主要通过两个⽅⾯进⾏:第⼀,保持50%的利⽤率,通过主从转换,机器上运⾏的Redis实例⼀半会
转译到⼀个新机器上;第⼆,扩展节点和分⽚。整个Redis集都会使⽤⼀个主从配置,从部分将被当做⼀个热备份。⼀旦主节点失败,从部分会⽴刻完成主的转换,同时⼀个新的从部分将会被添加,ZooKeeper将
完成整个过程。同时他们每个⼩时都会在Amazon S3上运⾏BGsave做更持久的储存——这项Reids操作会在后端进⾏,之后Pinterest会使⽤这些数据做MapReduce和分析作业。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。