3_{message_id}_${business_id}_${type}_${mtime}_${mid}=>{origin_id}
3、存储层的优化和思考
作为一个典型的大流量基础服务,点赞的存储架构需要最大程度上满足两个点①、满足业务读写需求的同时具备最大的可靠性②、选择合适的存储介质与数据存储形态,最小化存储成本从以上两点触发,考虑到KV数据在业务查询以及性能上都更契合点赞的业务形态,且TaiShan可以水平扩容来满足业务的增长。点赞服务从当前的关系型数据库(TiDB) 缓存(Redis)逐渐过渡至KV型数据库(Taishan) 缓存(Redis),以具备更强的可靠性。同时TaiShan作为公司自研的KV数据库,在成本上也能更优于使用TiDB存储。
4、点赞服务层(thumbup-service)
作为面对C端流量的直接接口,在提供服务的同时,需要思考在面对各种未知或者可预知的灾难时,如何尽可能提供服务存储(db、redis等)的容灾设计(同城多活)在DB的设计上,点赞服务有两地机房互为灾备,正常情况下,机房1承载所有写流量与部分读流量,机房2承载部分读流量。当DB发生故障时,通过db-proxy(sidercar)的切换可以将读写流量切换至备份机房继续提供服务。
在缓存(Redis)上,点赞服务也拥有两套处于不同机房的集群,并且通过异步任务消费TiDB的binLog维护两地缓存的一致性。可以在需要时切换机房来保证服务的提供,而不会导致大量的冷数据回源数据库。服务的容灾与降级(以点赞数、点赞状态、点赞列表为例),点赞作为一个用户强交互的社区功能服务,对于灾难发生时用户体验的保证是放在第一位的。所以针对重点接口,我们都会有兜底的数据作为返回。多层数据存储互为灾备点赞的热数据在redis缓存中存有一份。kv数据库中存有全量的用户数据,当缓存不可用时,KV数据库会扛起用户的所有流量来提供服务。TIDB目前也存储有全量的用户数据,当缓存、KV均不可用时,tidb会依托于限流,最大程度提供用户数据的读写服务。因为存在多重存储,所以一致性也是业务需要衡量的点。首先写入到每一个存储都是有错误重试机制的,且重要的环节,比如点赞记录等是无限重试的。另外,在拥有重试机制的场景下,极少数的不同存储的数据不一致在点赞的业务场景下是可以被接受的多地方机房互为灾备点赞机房、缓存、数据库等都在不同机房有备份数据,可以在某一机房或者某地中间件发生故障时快速切换。点赞重点接口的降级点赞数、点赞、列表查询、点赞状态查询等接口,在所有兜底、降级能力都已失效的前提下也不会直接返回错误给用户,而是会以空值或者假特效的方式与用户交互。后续等服务恢复时,再将故障期间的数据写回存储。
5、异步任务层(thumbup-job)
异步任务主要作为点赞数据写入、刷新缓存、为下游其他服务发送点赞、点赞数消息等功能首先是最重要的用户行为数据(点赞、点踩、取消等)的写入。搭配对数据库的限流组件以及消费速度监控,保证数据的写入不超过数据库的负荷的同时也不会出现数据堆积造成的C数据端查询延迟问题。
缓存刷新:点赞状态缓存、点赞列表缓存、点赞计数缓存同步点赞消息点赞事件异步消息、点赞计数异步消息针对 WriteBack方式的思考由于目前点赞系统异步处理能力或者说速率是能够满足业务的。所以当前写DB与写缓存都放在异步流程中。后续随着流量的增加,实施流程中写缓存,再由异步Job写入持久层相对来说是一个更好的方案。点赞job对binLog的容灾设计由于点赞的存储为TiDB,且数据量较大。在实际生产情况中,binLog会偶遇数据延迟甚至是断流的问题。为了减少binLog数据延迟对服务数据的影响。服务做了以下改造。监控:首先在运维层面、代码层面都对binLog的实时性、是否断流做了监控应对脱离binlog,由业务层(thumb-service)发送重要的数据信息(点赞数变更、点赞状态事件)等。当发生数据延迟时,程序会自动同时消费由thumbup-service发送的容灾消息,继续向下游发送。
三、未来规划
1、点赞服务单元化:要陆续往服务单元化的方向迭代、演进。2、点赞服务平台化:在目前的业务接入基础上增加迭代数据分库存储能力,做到服务、数据自定义隔离。3、点赞业务形态探索:以社区为基础,继续探索通过点赞衍生的业务形态。