缓存:更好的引入缓存技术。

缓存不是系统架构的必选项,只有在遇到性能瓶颈的业务场景,才可能需要引入缓存。引入缓存时,要从“大处着眼、小处着手”,即首先要从宏观考虑整体的缓存场景、缓存层次及缓存(更新/同步)策略,然后从局部考虑选择合适的缓存组件及使用方式(数据结构、分布、部署),并指定缓存系统的SLA,最后在系统运行过程中,要对缓存系统进行监控报警,还要根据业务发展、访问规模的变化,不断的对缓存架构进行优化及演进。

缓存引入前的考量

缓存引入前,首先要分析业务的应用规模、访问量级。对于规模不大的小系统或系统发展初始阶段,数据量和访问量不大,引入缓存并不能带来明显的性能提升,反而会增加开发、运维的复杂性。另外对于单条数据尺寸比较大的业务,如图片系统,虽然访问量可能较大,但更佳爱的选择可能是分布式文件系统而非缓存。而对于具有一定规模的常规业务系统(特别是互联网系统),数据规模、访问量较大,且持续快速增加,要保证服务的稳定性,在突发流量下也能快速响应用户请求,就需要把频繁读写的数据从磁盘访问变为内存访问,也就是说需要引入缓存。

其次还要分析系统架构,在系统架构中合适的模块、层次引入缓存,并考虑各个缓存系统之间的更新方式、一致性保障策略等,让缓存系统和其他架构层(如持久层、分布式文件层)有机结合。

缓存组件的选择

缓存的种类很多,我们实际使用时,需要根据缓存位置(系统前后端)、待存数据类型、访问方式、内存效率等情况来选择最适合的缓存组件。本小节接下来将主要探讨在应用层后端如何选择分布式缓存组件。

一般业务系统中,大部分数据都是简单KV数据类型,如前述微博Feed系统中的feed content、feed列表、用户信息等。这些简单类型数据只需要进行set、get、delete操作,不需要在缓存端做计算操作,最适合以memcached作为缓存组件。

其次对于需要部分获取、事务型变更、缓存端计算的集合类数据,拥有丰富数据结构和访问接口的Redis也许会更适合。Redis还支持以主从(master-slave)方式进行数据备份,支持数据的持久化,可以将内存中的数据保持在磁盘,重启时再次加载使用。因磁盘缓存(diskstore)方式的性能问题,Redis数据基本只适合保存在内存中,由此带来的问题是:在某些业务场景,如果待缓存的数据量特别大,而数据的访问量不太大或者有冷热区分,也必须将所有数据全部放在内存中,缓存成本(特别是机器成本)会特别高。如果业务遇到这种场景,可以考虑用pika、ssdb等其他缓存组件。pika、ssdb都兼容Redis协议,同时采用多线程方案,支持持久化和复制,单个缓存实例可以缓存数百G的数据,其中少部分的热数据存放内存,大部分温热数据或冷数据都可以放在磁盘,从而很好的降低缓存成本。

对前面讲到的这些后端常用的缓存组件,可以参考下表进行选择。

缓存组件数据类型访问方式数据容量(单实例)同步内存效率
Memcached简单KVGET SET DEL等常规接口100GB以下Client多写一般
Redis丰富更丰富的常规接口、事务更新等30GB以下主从复制一般
Pika/ssdb较丰富,部分Redis数据结构不支持较丰富数百GB以上主从复制一般

最后,对于对存储效率、访问性能等有高要求的业务场景,结合业务特性进行缓存组件的定制化设计与开发,也是一个很好的选择。

总之,缓存组件的选型要考虑数据模型、访问方式、缓存成本甚至开发人员的知识结构,从而进行因地制宜的取舍,不要盲目引入不熟悉、不活跃、不成熟的缓存组件,否则中途频繁调整缓存方案,会给开发进度、运维成本带来较大的挑战。

缓存架构的设计

确定缓存组件后,首先需要考虑结合业务场景,设计业务数据对应的缓存结构及缓存容量规划。如微博在用Memcached缓存feed content时,最初采用json、xml格式进行缓存,后来又改为更紧促的PB(protocol buffer)结构;而对feed content的容量规划设计,则包含了content的平均size、缓存数据量、峰值读写QPS、命中率、过期时间、平均穿透加载时间等。

其次要结合缓存组件特点,设计缓存的读写策略、分布策略、过期策略等。如在海量数据、大并发访问场景下使用Redis时,要考虑如何在主从之间进行读写分离,要考虑key的hash算法、分布策略,以使数据分散和请求访问更均衡,同时还要考虑如何让冷数据/过期数据更快从内存剔除(如主动删除冷数据、低峰scan清理过期数据),让更多的热数据常驻内存,从而确保缓存有持续的高命中率。

最后还要从开发、运维等角度,设计缓存的一致性、高可用性方案。如微博在memcached对feed vector进行更新时,如果该vector不存在则不更新,待有请求时再从持久层获取最新数据,如果该vector存在,则通过MAIN层的CAS、HA层/L1层的set来进行更新和一致性保证。又如微博对Redis采用DNS方式进行主从的访问及运维,如果是master故障,运维系统可以根据策略快速选择新的master,并将其他所有slave指向新的master,并更新DNS,确保Redis缓存的快速恢复;而对于slave故障,则直接将其摘除slave DNS即可,访问基本不受影响。

缓存系统的监控及演进

在系统运行过程中,需要对缓存系统进行实时监控报警,在缓存组件出现故障或无法满足(突发流量)需求时,进行修复及快速扩展。监控可以采用集中探测的方式,也可以采用分布式汇报的方式,具体探测方案需要根据监控系统的特点进行确定。

另外,随着业务发展和访问规模的变化,缓存架构也需要不断进行优化及演进。如在微博发展过程中,单个核心数据的访问量从万级别增加到十万、百万级别,同时突发事件可能在短时间带来30%以上的访问流量。微博为此在memcached先后引入Main-HA、L1-Main-HA多层结构,以确保缓存系统持续的高可用性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值