大萧条时期的野蛮生长——巨量计数服务

271 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划·4月更文挑战」的第13天,点击查看活动详情

标题可能有点歧义,但计数的服务是业务系统中常见的问题。相应的问题难度是随着数据的量级不断升级的,这在历年的双十一中已经无数次证明了,甚至上升到了技术军备竞赛的级别。1万个用户与100万与1个亿,这三者甚至已经不是同一个范畴的问题了。今天不做全面的说明,从一个计数问题的角度来看有哪些可能的解法。

不是问题的阶段

当单表数据在六到七位数量级时,这可能是不是问题的问题。因为如果需要对某一项特征计数,比如关联的任务的人数,名下有几台电脑,一共有多少个订单等等。这都可以通过对特征加索引,然后直接从数据库count或者查出结果集在代码中count。广大在校大学生都可以无压力的完成,但同时不能因为你工作经验丰富就把这样简单的问题复杂化,最快最高效的解法永远是第一选择。

开始不一样

当单表数据超过千万,也一直是网传的mysql性能分水岭(其实不是,mysql性能远不止此)。这个时候,可能一个用户id所关联的记录数已经达到万级别,确实会出现较大的延迟。如果类似twitter粉丝数这样的服务,每次进入首页都要查询一次,那人一多性能真的难以保证。这个时候为了保证速度,我们会引入redis,我们可以把每次新增的计数首先写到redis,然后再去查询时可以获得更快的响应。同时,我们单独新增一张计数表,只有用户id和对应的数量。redis设置完成之后,再异步向mysql同步,以防有时候redis被穿透还能有mysql降级。

巨量开始

还是类似twitter的例子,有些一线明星关注数都是千万级别,他们的存在无时无刻不在给后端服务压测。其实上一步的方案也是有问题的,2种存储之间的同步肯定会有不一致的情况,别说一线明星,一些自媒体人幸苦运营的频道最关注的就是关注数和浏览数,搞错了可能会招来投诉。所以,不如一刀切,不要mysql了,只通过redis进行存取。但依然有2个问题,一是redis贵,内存比硬盘贵很多倍;二是redis的高可用方案需要设计完备。针对第一个,我们需要一个冷数据存储,将长时间不访问的冷数据存储到固态硬盘中,当有访问需求时再通过异步线程获取,延迟在所难免,但出现频率并不高。针对第二个问题,redis支持集群部署,也有AOF+RDB这样的备份模式,一定程度上可以保证数据安全的。