每秒30W次的点赞业务,怎么优化?

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 30WQPS的点赞计数业务,如何设计?

image.png

继续答星球水友提问,30WQPS的点赞计数业务,如何设计? 可以看到,这个业务的特点是:(1)吞吐量超高(2)能够接受一定数据不一致画外音:计数有微小不准确,不是大问题。 先用最朴素的思想,只考虑点赞计数,可以怎么做?有几点是最容易想到的:(1)肯定不能数据库抗实时读写流量;(2)redis天然支持固化,可以用高可用redis集群来做固化存储(3)也可以用MySQL来做固化存储redis做缓存,读写操作都落缓存,异步线程定期刷DB(4)架一层计数服务,将计数与业务逻辑解耦; 此时MySQL核心数据结构是:

t_count(msg_id, praise_count)

  此时redis的KV设计也不难:

key:msg_id

value:praise_count
image.png

似乎很容易就搞定了:(1)服务可以水平扩展;(2)数据量增加时,数据库可以水平扩展;(3)读写量增加时,缓存也可以水平扩展; 计数系统的难点,还在于业务扩展性问题,以及效率问题。 以微博为例:
image.png

(1)用户微博首页,有多条消息list<msg_id>,这是一种扩展(2)同一条消息msg_id,不止有点赞计数,还有阅读计数,转发计数,评论计数,这也是一种扩展 假如用最朴素的方式实现,多条消息多个计数的获取伪代码如下:

// (1)获取首页所有消息msg_id

list<msg_id> = getHomePageMsg(uid);

// (2)对于首页的所有消息要拉取多个计数

for( msg_id in list<msg_id>){

         //(3.1)获取阅读计数

         getReadCount(msg_id); 

         //(3.2)获取转发计数

         getForwordCount(msg_id);

         //(3.3)获取评论计数

         getCommentCount(msg_id);

         //(3.4)获取赞计数

         getPraiseCount(msg_id);

}

  由于同一个msg_id多了几种业务计数, redis的key需要带上业务flag ,升级为:

msg_id:read

msg_id:forword

msg_id:comment

msg_id:praise

用来区分共一个msg_id的四种不同业务计数,redis不能支持key的模糊操作,必须访问四次reids。   假设首页有100条消息,这个方案总结为: (1)for循环每一条消息,100条消息100次; (2)每条消息4次RPC获取计数接口调用; (3)每次调用服务要访问reids,拼装key获取count; 画外音:这种方案的扩展性和效率是非常低的。   那如何进行优化呢?   首先看下数据库层面元数据扩展,常见的扩展方式是, 增加列 ,记录更多的业务计数。
image.png

如上图所示,由一列点赞计数,扩充为四列阅读、转发、评论、点赞计数。

  增加列这种业务计数扩展方式的缺点是: 每次要扩充业务计数时,总是需要修改表结构 ,增加列,很烦。   有没有不需要变更表结构的扩展方式呢? 行扩展 是一种扩展性更好的方式。
image.png

表结构固化为:

t_count(msg_id, count_key, count_value)

当要扩充业务计数时,增加一行就行,不需要修改表结构。 画外音:很多配置业务,会使用这种方案,方便增加配置。   增加行这种业务计数扩展方式的缺点是: 表数据行数会增加 ,但这不是主要矛盾,数据库水平扩展能很轻松解决数据量大的问题。   接下来看下redis批量获取计数的优化方案。
image.png

原始方案,通过拼装key来区分同一个msg_id的不同业务计数。

  可以升级为,同一个value来存储多个计数。
image.png

如上图所示,

同一个msg_id的四个计数 ,存储在一个value里,从而避免多次redis访问。
画外音:通过value来扩展,是不是很巧妙?   总结 计数业务,在数据量大,并发量大的时候,要考虑的一些技术点: (1)用缓存抗读写; (2)服务化,计数系统与业务系统解耦; (3)水平切分扩展吞吐量、数据量、读写量; (4)要考虑扩展性,数据库层面常见的优化有:列扩展,行扩展两种方式; (5)要考虑批量操作,缓存层面常见的优化有:一个value存储多个业务计数;   计数系统优化先聊到这里,希望大家有收获。

欢迎大家继续提问,有问必答。

本文转自“架构师之路”公众号,58沈剑提供。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
消息中间件 存储 缓存
十万订单每秒热点数据架构优化实践深度解析
【11月更文挑战第20天】随着互联网技术的飞速发展,电子商务平台在高峰时段需要处理海量订单,这对系统的性能、稳定性和扩展性提出了极高的要求。尤其是在“双十一”、“618”等大型促销活动中,每秒需要处理数万甚至数十万笔订单,这对系统的热点数据处理能力构成了严峻挑战。本文将深入探讨如何优化架构以应对每秒十万订单级别的热点数据处理,从历史背景、功能点、业务场景、底层原理以及使用Java模拟示例等多个维度进行剖析。
55 8
|
监控 前端开发 JavaScript
不了解 QPS、TPS、RT、并发数、吞吐量,劝你简历别写熟悉高并发
分布式、微服务、Service Mesh目前都是大家耳熟能详的词语了,现在随便一个互联网公司说出来大家都是在搞微服务。 但我们搞来搞去,怎么样来衡量一个应用当前的状态到底是怎么样的?到底需不需要扩容?是需要横向扩容还是进行项目重构?
|
1月前
|
架构师 Java 测试技术
一文搞透高并发指标(QPS、TPS、吞吐量等)
详解高并发场景下的QPS、TPS、RT及吞吐量等关键性能指标,帮助理解系统性能评估的核心概念。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
一文搞透高并发指标(QPS、TPS、吞吐量等)
|
28天前
|
NoSQL 关系型数据库 MySQL
百万数据量优化实战
在现代互联网业务中,处理百万级别的数据量是家常便饭。传统的单体数据库架构在面对如此庞大的数据量时,往往显得力不从心。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
52 4
|
4月前
|
算法 关系型数据库 MySQL
技术分享:600W QPS高并发ID设计与时钟回拨解决方案
【8月更文挑战第26天】在大型分布式系统中,高并发ID生成和时钟同步是两个至关重要的技术挑战。随着业务量的快速增长,如美团点评的金融、支付、餐饮等业务场景,每秒需要处理数百万级别的请求,这就对ID的生成效率和唯一性提出了极高要求。同时,时钟回拨问题也时常困扰着系统管理员,影响数据一致性和系统稳定性。本文将围绕这两个主题,分享一些工作学习中的技术干货。
69 1
|
4月前
|
存储 边缘计算 缓存
钉钉发展与优化迭代问题之钉钉每次消息发送都要查询路由服务带来的压力如何解决
钉钉发展与优化迭代问题之钉钉每次消息发送都要查询路由服务带来的压力如何解决
|
4月前
|
网络协议 Ubuntu
百万并发连接的实践测试01
百万并发连接的实践测试01
百万并发连接的实践测试02
百万并发连接的实践测试02
|
7月前
|
分布式计算 Java 数据库连接
回答粉丝疑问:Spark为什么调优需要降低过多小任务,降低单条记录的资源开销?
回答粉丝疑问:Spark为什么调优需要降低过多小任务,降低单条记录的资源开销?
63 1
|
7月前
|
消息中间件 Java 程序员
阿里巴巴高并发架构到底多牛逼?是如何抗住淘宝双11亿级并发量?
众所周知,在Java的知识体系中,并发编程是非常重要的一环,也是面试的必问题,一个好的Java程序员是必须对并发编程这块有所了解的。