用最少的机器支撑万亿级访问,微博6年Redis优化历程(2)
计数微博有很多计数场景,如用户纬度的关注数、粉丝数,微博纬度的转发数、评论数等.计数作为微博中一项很重要的数据,在微博业务中承担了很重要的角色.为更好的满足计数业务需求,我们基于 Redis 定制了内部的计数服务. 原生 Redis 为了支持多数据类型,需要维护很多指针信息,存储一份业务计数要占到约 80 个字节,内存利用率很低.为此我们定制了第一版计数器 Redis counter,通过预先分配内存数组存储计数,并且采用 doublehash 解决冲突,减少了原生 Redis 大量的指针开销.通过以上优化将内存成本降低到原来的 1/4 以下.(小编:又节约了 3 / 4 服务器……) 随着微博的发展,微博纬度的计数不断增加,在原来的转发数、评论数基础上,又增加了表态数,2013 年还上线了阅读数. Redis counter 已不能很好的解决这类扩展问题:
为此我们又设计了改进版的计数器 CounterService,增加如下特性:
??通过以上的定制优化,我们从根本上解决了计数业务的成本及性能问题. 除了以上关系、计数业务场景的定制优化,为了满足判断类业务场景需求,定制了 BloomFilter 服务;为了满足 feed 聚合业务场景需求,定制了 VerctorService 服务;为了降低服务成本,定制了 SSDCache 服务等.(小编:老板感动得流泪了) 服务化时代(2014 -)Cache Service、SSD Cache随着微博业务的快速增长,Redis 集群规模也在持续增加,目前微博 Redis 集群内存占用数十 TB,服务于数百个业务线,Redis 集群的管理依然面临很多的问题. 数据迁移问题随着时间推移,越来越多的业务由于数据量的增加,单端口到内存占用已经达到上限,微博内部建议单端口内存不超过 20GB,因此需要重新拆分端口,这就涉及到数据迁移,目前迁移操作是通过内部开发的一个迁移工具来完成的,迁移操作的成本相对较高. 数据路由问题?目前的使用方式,需要在业务代码中实现数据路由规则,路由规则的变更需要重新上线代码,业务变更复杂度较高.同时节点配置采用 DNS 的方式,存在实时性和负载不均的问题,虽然使用过程中有对应的解决策略,但是需要一定的运维干预,运维复杂度较高. HA 系统不成熟当前的 HA 系统更多的是采用自动发现问题,手动确认处理的策略,没有实现真正意义的自动化,运维成本依然很高. 为了解决以上问题,我们在 Redis 基础上实现服务化框架 CacheService. CacheService 最早是为了解决内部使用 memcached 遇到的问题而开发的服务化框架,主要包含以下几个模块:
微博内部的配置服务中心,主要是管理静态配置和动态命名服务的一个远程服务,并能够在配置发生变更的时候实时通知监听的 ConfigClient.
实际的数据存储引擎,初期支持 memcached,后续又扩展了 Redis、SSDCache 组件,其中 SSDCache 是为了降低服务成本,内部开发的基于 SSD 的存储组件,用于缓存介于 memory 和 DB 之间的 warm 数据.
代理业务端的请求,并基于设定的路由规则转发到后端的 cache 资源,它本身是无状态的.proxy 启动后会去从 ConfigServer 加载后端 cache 资源的配置列表进行初始化,并接收 ConfigServer 的配置变更的实时通知.
提供给业务方使用的 SDK 包,通过它不需要在业务代码中实现数据路由规则,业务方也无需关心后端 cache 的资源.只需要简单配置所使用的服务池名 group 和业务标识 namespace 即可使用 cache 资源,client 从 ConfigServer 获取 proxy 的节点列表,选择合适的 proxy 节点发送请求,支持多种负载均衡策略,同时会自动探测 proxy 节点变更.
管理集群中各个组件的运行状态以保证业务的 SLA 指标,当出现异常时会自动执行运维处理.同时配置变更、数据迁移等集群操作也都是由它来负责. 总结从对 Redis 的优化历程可以看出,技术的进步是由业务的需求推动的,我们需要拥抱需求.同时对于一个服务我们需要持续优化并保证服务的运维友好性才能保证服务的生命力.后续的一些计划,完善服务化体系中冷热数据分级存储机制以降低服务成本;引入新的组件以更好的满足业务需求、进一步完善集群管理组件降低运维复杂度. 文/刘东辉 原文出处——高可用架构微信公众号 (编辑:ASP站长网) |