程序员经典面试题:如何实现一个海量计数系统

数据库 MySQL 新闻
我们在开发中,经常有一些计数相关的工作。例如,抖音上的短视频,有评论数,播放数。发送微博的时候,也有转发数,评论数,点赞数,电商网站上,有着商品售卖金额,商品的出售件数等统计。那么,这些统计是怎么做到的呢?

 我们在开发中,经常有一些计数相关的工作。例如,抖音上的短视频,有评论数,播放数。发送微博的时候,也有转发数,评论数,点赞数,电商网站上,有着商品售卖金额,商品的出售件数等统计。那么,这些统计是怎么做到的呢?

 

[[316970]]

 

不难想到,我们可以在用户查看这条评论的时候,去统计总共有多少个赞。举个例子,你在虎扑上发表一条评论,每当有人点赞的时候,都会在评论下面增加一条点赞记录,记录谁谁谁点赞了。当有人访问这条评论的时候,我们可以使用Mysql的SelectCount语句,对其进行统计,查询总共有多少条记录,并且返回给前段。这种方案有什么问题呢?当数据量小的时候,我们总可以非常迅速地计算到结果。但是随着数据量的增大,例如一条非常火的评论,可能已经有数十万个赞了,每次都去查询效率都比较低。评论的内容是核心数据,评论的点赞数是次要数据,如果查询点赞数量的耗时过长,反而会影响主要业务。我们要做的,是尽量地少去查询,或者让查询的速度更快。

 

在此之前的方案,我们每次都是全量Count一遍,那么,我们能不能把这个数据存起来呢?这样子,就不需要每次有人来查询的时候,都去统计。每次有变更的时候,就去数据库里面进行selectCount,查询后将结果保存下来。之后每次有人访问这条评论,我们就直接返回,而不需要进行SelectCount。当然,每次都去SelectCount也是一个笨方法,我们为什么不每次有人点赞就+1,有人取消点赞就减一呢。我们将点赞数据的电话分为两种事件,一种是+1,另一种是-1。当然,这种做法的潜在风险点就是并发问题,例如原来的数据是5,突然来了两个+1的请求,由于他们并发执行了,最终的结果变成6。这种情况下我们需要加锁防止并发,或者让数据库帮我们实现。

仅是这样是远远不够的,我们如何面对突发的流量呢?例如突然爆发了一个热点事件,突然火了一条评论,可能10分钟之内就已经几万个点赞了。假如我们每次都去数据库更新,那势必效率会大大降低。为了应对这种突发性的流量,业内的解决方案大家其实都非常熟悉,不就采用消息队列进行削峰嘛。但是,这种突发性的流量容易造成MQ堆积,那么有没有什么好的方法呢?其实非常简单,本来我们要进行10次+1的操作,为什么我们不合并成1次+10操作呢。这样就能大大减少数据库的压力,我们一般有两场常见的实现方式,一种是对异步队列进行任务合并,另外一种是我们可以将计数存在缓存上,定期将数据刷到数据库中。

 

我们更多采用的是第二种方法,并且我们还会进一步优化,就是我们会将点赞的统计存放在Redis这种的缓存中间件上,然后再定期刷到磁盘上。对于这样的统计数据,冷热是非常明显的,基本上,采用采用这种方案,已经可以适用大部分计数系统了。欢迎大家关注我,共同学习,共同进步。大家的支持是我继续唠嗑的动力。

责任编辑:华轩 来源: 今日头条
相关推荐

2020-04-08 10:18:56

MySQL数据库SQL

2019-09-20 14:25:21

程序员Google人生第一份工作

2012-05-25 10:15:06

Java程序员面试题

2020-04-26 09:48:11

MySQL数据库架构

2020-05-06 15:02:58

MySQL数据库技术

2020-02-06 08:58:09

程序员技术数据库

2019-10-18 09:40:19

程序员固态硬盘Linux

2020-02-07 10:14:07

程序员设计人生第一份工作

2020-03-18 09:33:47

数据库程序员数组

2020-04-12 22:29:50

程序员MySQL数据

2020-02-22 21:51:43

程序员Microsoft SServerSQL

2020-10-05 21:13:37

程序员技能开发者

2011-07-18 15:08:19

SQL存储过程

2009-03-18 13:12:36

程序员技术IT行业

2017-02-05 10:21:10

程序员好问题

2015-05-13 14:06:03

程序员糟糕的程序员

2014-07-28 14:00:40

linux面试题

2016-05-05 17:45:43

Spring面试题答案

2014-01-06 09:33:32

程序员管理

2021-07-01 07:43:41

项目程序员代码
点赞
收藏

51CTO技术栈公众号