设计
绝世好阿狸
这个作者很懒,什么都没留下…
展开
-
【设计】基于redis的简单频控实现
场景:xxx时间内只能yyy次在redis里维护一个数字类型的k-v,key的生成策略与频控的维度有关,比如是用户级的频控,那么key就是一个userId;如果是总频控,那么key就是一个string常量。key的过期时间就是频控的时间间隔,在创建key的时候设置过期时间。过频控时,需要将key的计数值自增。关于自增的时机:第一种:先get再incr。第二种:先incr再get。这两种都可以,看具体的场景。如果过了频控,后续的业务操作还有其他条件,不一定成功,这种需要用方案一。比如发原创 2020-08-22 14:07:37 · 1192 阅读 · 0 评论 -
【设计】计数(二)普通计数
这里说的是非基数类型的计数。对于这类型计数,可以只使用一个变量存储计数值,比如点赞数,直接用一个like_count变量逐步累加就行。但是考虑一个复杂场景,比如记录每一个作品的点赞数,这个时候就需要加一个作品维度了,如果使用mysql记录,那么scheme可能是:photo_id,like_count。再复杂一些,作品里可能有多个计数的维度,比如除了点赞计数,还有评论计数,分享计数等等,那看上去需要每一种计数类型都建一张表了,其实也不用,可以再一列type,表明计数类型:photo_id,typ原创 2020-08-17 23:41:00 · 159 阅读 · 0 评论 -
【设计】计数(一)基数计数
所谓基数计数就是统计不重复元素的个数,典型的场景比如页面uv数,这类计数的特点是需要去重。第一种思路——精确计数即存储所有所有不重复元素的值,用一个set数据结构存。比如存储访问某一个页面的全部去重用户id,需要拿计数值时,只需要计算这个set的元素数目即可。这个set根据场景,可能是内存中一个set数据结果,可能是mysql数据库中的一个表,也可能是redis里的set等等。这个方案在基数值不大的情况下是可以的,毕竟方案本身足够简单,但是如果基数值很大时,就会有问题,这个set会很大,存储原创 2020-08-16 16:32:07 · 585 阅读 · 0 评论 -
【设计】C-S协议 可扩展性
C-S架构下,接口定义需要考虑后续的可扩展性。这里是指广义的客户端-服务端。原则上,对于下发协议,后续的变更只能新增字段而不能发生结构性的变更(比如修改结构或删除),否则就无法向前兼容。如果非要变更,需要做好兼容性处理。分两种case:1.服务端兼容,需要客户端传入版本号,服务端根据版本号兼容,低版本的使用老协议下发,高版本的使用新协议下发,如果无法区分客户端版本,那么服务端无法兼容,一版推荐...原创 2020-04-11 12:50:53 · 387 阅读 · 0 评论 -
【设计】数据源切换 注意点
切换数据源的常规流程:双写,导历史数据,切读,关闭双写。这里有一个关键点是,在切读前,双写一定要开全了,这个务必确认,否则一旦切读,读服务可能读不到数据。对于微服务的场景,这一点可能会被忽略,需要根据监控梳理出双写以及读的服务有哪些,别漏掉。另外,双写和切读的服务很可能不是同一个。举个例子,api和rpc服务在双写,另一个consumer在切读,这时,如果有一个双写的服务漏掉了,那么con...原创 2019-12-09 10:02:54 · 190 阅读 · 0 评论 -
【设计】时序类数据 统计
主要用于服务的打点、数值分布以及延时统计。实现分成下面几个部分:1.客户端sdk;2.发送进程;3.接收进程;4.web客户端展示;1.sdk:提供类似如下的接口:log(name, count, value)name是统计名称,与业务相关;count是计数器;value是分布的值,比如延迟;count与value可以不同时存在,看具体使用需求...原创 2018-04-27 23:07:31 · 678 阅读 · 0 评论 -
【设计】关系类业务
后端设计中,常常有一种场景,就是关系类的存储。比如订阅或者关注等。就以关注为例。通常来说,记录关注关系,需要落地到db,那么表结构大概是怎样的?很容易想到的一个表结构:id:自增id;userId:被关注用户id;followerId:关注用户id核心信息其实就这几个。这个表可以解决简单的场景。但是当数据量越来越大,可能需要搞缓存。那么缓存怎么存?第一反应应该是一个se...原创 2019-08-08 23:45:42 · 156 阅读 · 0 评论