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

继续答星球水友提问,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

 

似乎很容易就搞定了:

(1)服务可以水平扩展;

(2)数据量增加时,数据库可以水平扩展;

(3)读写量增加时,缓存也可以水平扩展;

 

计数系统的难点,还在于业务扩展性问题,以及效率问题。

 

以微博为例:

(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;

画外音:这种方案的扩展性和效率是非常低的。

 

那如何进行优化呢?

 

首先看下数据库层面元数据扩展,常见的扩展方式是,增加列,记录更多的业务计数。

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

 

增加列这种业务计数扩展方式的缺点是:每次要扩充业务计数时,总是需要修改表结构,增加列,很烦。

 

有没有不需要变更表结构的扩展方式呢?

行扩展是一种扩展性更好的方式。

表结构固化为:

t_count(msg_id, count_key, count_value)

当要扩充业务计数时,增加一行就行,不需要修改表结构。

画外音:很多配置业务,会使用这种方案,方便增加配置。

 

增加行这种业务计数扩展方式的缺点是:表数据行数会增加,但这不是主要矛盾,数据库水平扩展能很轻松解决数据量大的问题。

 

接下来看下redis批量获取计数的优化方案。

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

 

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

如上图所示,同一个msg_id的四个计数,存储在一个value里,从而避免多次redis访问。
画外音:通过value来扩展,是不是很巧妙?

 

总结

计数业务,在数据量大,并发量大的时候,要考虑的一些技术点:

(1)用缓存抗读写;

(2)服务化,计数系统与业务系统解耦;

(3)水平切分扩展吞吐量、数据量、读写量;

(4)要考虑扩展性,数据库层面常见的优化有:列扩展,行扩展两种方式;

(5)要考虑批量操作,缓存层面常见的优化有:一个value存储多个业务计数;

 

计数系统优化先聊到这里,希望大家有收获。

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

答球友问
用DB自增键生成uid了,还能分库吗?

亿级数据“定时任务”,如何缩短执行时间?

粉丝关系链,10亿数据,如何设计?
几万条群离线消息,如何高效拉取?
盘口数据频繁变化,100W用户如何实时通知?

调研
大伙是用redis搞计数么?

编写一个自动增加微博点赞的脚本通常涉及到网络爬虫技术、API交互或者是模拟用户操作的自动化工具。这里以Python为例,假设你需要使用Selenium库(用于浏览器自动化)和某个微博平台的公开API(如果有的话,大部分社交媒体平台都不支持这种功能,因为这可能会被视为机器人行为并被封禁): 1. **安装依赖**: - 安装`selenium`库 (`pip install selenium`) - 可能需要下载对应浏览器驱动(如ChromeDriver) 2. **获取网页元素**: 使用Selenium打开微博网站,并定位到点赞按钮的HTML元素。 ```python from selenium import webdriver driver = webdriver.Chrome() driver.get('https://weibo.com/<your_post_url>') # 替换为实际微博URL like_button = driver.find_element_by_css_selector('.ui-like-action') # 根据实际CSS选择器查找点赞按钮 ``` 3. **点击点赞**: 调用`click()`方法模拟用户点击。 ```python like_button.click() ``` 4. **处理可能的登录验证**: 如果需要登录才能点赞,先模拟登录过程。例如,使用`WebDriverWait`等待页面加载完成,然后输入用户名和密码。 5. **循环点赞**: 将上述步骤封装成函数,然后循环执行,直到达到目标点赞数或者遇到限制。 ```python def like_tweet(): while True: try: like_button.click() print(f"已点赞") except Exception as e: if 'login required' in str(e): # 检查是否有登录需求 login(driver) # 自定义登录函数 else: break # 遇到其他错误或达到上限停止 like_tweet() ``` 重要提示:这只是一个基本示例,真实情况可能因网站结构变化而无法直接工作。此外,遵守各平台的使用协议,尊重用户隐私和网站条款,避免违法或滥用自动化工具。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值