计数系统架构设计(转)

news2024/11/16 22:43:02

本文主要节选和总结自沈剑大佬的 计数系统架构实践一次搞定 | 架构师之路和文章的评论,略有删改

一、问题描述

很多业务都有“计数”需求,以微博为例:

微博首页的个人中心部分,有三个重要的计数:关注了多少人的计数、粉丝的计数、发布博文的计数

微博首页的博文消息主体部分,有四个计数:转发计数、评论、点赞、浏览计数

本文主要讨论:数据量大、高并发情况下怎么高效查询?计数属性增加怎么快速扩展架构?

二、架构设计

不同的属性计数,分别用一张表来记录,比如博文转发表,新增一个转发则新增一条记录、博文评论表、博文点赞表新增一条评论或者点赞都在各自的表里新增一条记录,用户关注表、用户粉丝表、博文表、收藏表等,也是新增粉丝或者新增博文就在对应表里新增记录。

每个用户的三个计数值需要发起三次count查询,每篇博文的4个技术值,也需要4次count的查询。高并发下数据库压力较大。

缺点:每个用户需要3个count查询,首页十多篇博文,需要几十次count查询

2.1 计数外置

额外冗余设置 2 张计数表,分别用来记录用户维度和博文维度的计数,每个计数属性在计数表里是一列字段。比如上面的微博业务可以抽象出两个表(用户计数表和博文计数表),针对这两个维度来进行计数的存储:

t_user_count (uid, gz_count, fs_count, bw_count);

t_bw_count (bw_id, forword_count, comment_count, praise_count);

查询

每个用户的计数只需要查一次用户计数表即可,微博首页每条博文也仅需要查一次博文计数表即可,甚至可以用 in 语句把所有博文的计数放在同一条sql里执行,这样微博首页所有博文计数仅需一次查询即可。

更新

MQ 消息解耦,每当发生一个计数更新的事件,比如点赞事件、转发事件、都给 MQ 发送一条消息,由下游服务负责监听消息,给对应事件的表里增加条记录,更新总的计数表,如果有缓存,需要淘汰缓存。

2.2 加入缓存提高查询性能

像关注计数,粉丝计数,微博消息计数,变化的频率很低,查询的频率很高,这类读多些少的业务场景,非常适合使用缓存来进行查询优化,减少数据库的查询次数,降低数据库的压力。

缓存中的数据结构是hash,一个实体是一个hash,hash实体的 key 是{用户id拼接上:user} 或者{博文id拼接上:bowen},hash 实体每个元素的key是具体的属性,value是对应的计数值。

hset 123:user follower 10
hset 123:user fanse 20
hget 123:user // {"follower": 10, "fanse": 20}

一次 mget 网络操作即可拿到该用户或者该博文所有的属性计数值。

2.3 一致性不高的业务场景可以用缓存提高写性能

对于写多读少,一致性要求不高的计数,也可以先用缓存保存,然后定期刷到数据库中,以降低数据库的写压力。或者发生 50 个计数事件就同步一次 db。

写操作需要先 mget 查到原来的值,然后 mset 设置新值。

2.4 计数属性增加

在数据量很大,并发很高的情况下,如果想在冗余计数表中增加一个字段,比如用户计数表中增加一个收藏博文数,会很难。好的方式是以下量两种:

1、冗余的计数表设计时预留好字段

2、冗余计数表采用竖表设计而非横表设计,把列扩展变成了行扩展。即计数表的每个计数属性值不再存在同一条横向记录里,而是把每种属性的技术值单独存一条记录,这样每次增加属性,就只需要增加一条记录即可。

三、问题

问:计数外置,增加冗余计数表,怎么解决数据冗余必将引发的数据一致性问题

  • 对于一致性要求比较高的业务,要有定期 check 并 fix 的机制,例如关注计数,粉丝计数,博文总数计数等。check 机制包括定时任务扫库、日志扫增量、MQ 延时消息实现定时任务
  • 对于一致性要求比较低的业务,即使有数据不一致,业务可以接受,例如微博浏览数,微博转发数等

问:一致性要求高的场景能不能用 redis 来执行写操作

对于缓存维护计数定期更新到数据库的方式,数据库的数据存在一定的滞后性,如果缓存发生重启,从db恢复数据时可能会丢失部分数据。对于一致性要求比较高的业务,不太合适。

一般不建议把缓存当数据库来用,一是 redis 持久化不如 db 好,重启有可能丢数据;二是缓存持久化频繁,会降低性能。如果非要用 redis 来提高写性能,最好提高 redis 的持久化性能。

缓存计数自增的命令是:INCRBY,可以保证原子性。

问:能不能只用 redis,不用数据库

不太建议

问:如果把冗余计数表从横表换成竖表,那岂不是会导致记录数量扩大好几倍

是的,但是数据量可以很容易通过水平扩展的方式来解决。

问:博文的评论这些是不是用 mongo 来存比较好

可以使用mongodb来应对频繁修改表的需求

问:横表和竖表怎么选择

横表显然记录条数会比较少,查询相对较快,竖表记录条数会变多,查询相对较慢,如果表结构相对稳定就使用横表,如果表结构可能频繁变更,就用竖表,大部分根据经验来判断。比如配置性的数据用竖表就非常合适。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/351395.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何编写一个基本的 Verilog Module(模块)

1、概述这篇文章主要介绍了 Verilog 在 FPGA 设计中的概念和使用方法。首先讨论使用模块(module)关键字构造 Verilog 设计的方式,以及这与所描述的硬件的关系。这包括对参数、端口(port)和例化(instantiato…

JSON Web Token (JWT)

1,什么是JWT JWT是JSON Web Token是简称,是一个行业开发标准(RFC 7519)定义了一种简介的 自包含的协议格式,用于在通信双方传递JSON对象,传递的信息经过数字签名可以被验证和信任。它可以使用HMAC算法或使…

4.如何靠IT逆袭大学?

学习的动力不止于此: IT逆袭 这两天利用工作空余时间读了贺利坚老师的《逆袭大学——传给 IT 学子的正能量》,感触很多,有些后悔没有好好利用大学时光。 不过人都是撞了南墙再回头的,吃一堑长一智。 这本书无论你是工作了还是…

DataX简介、部署、原理和使用介绍

DataX简介、部署、原理和使用介绍 1.DataX简介 1-1.项目地址 项目地址:https://github.com/alibaba/DataX 官方文档:https://github.com/alibaba/DataX/blob/master/introduction.md 1-2.DataX概述 ​ DataX 是阿里云 DataWorks数据集成 的开源版本…

JDK安装环境变量配置

jdk下载地址:https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html 下载安装包和exe都可。 安装JDK 安装JDK时,除了修改安装目录,其他的一路【下一步】,傻瓜式安装。 (注:当提示安装JRE时…

WPF MVVM系统入门-上

WPF MVVM系统入门-上 Models:存放数据的模型,实体对象 Views:可视化界面 ViewModels:业务逻辑。ViewModels与Models的联系会更紧密,而Views页面会主动绑定ViewModels中的数据,原则上ViewModels不要直接去操作Views,被动的被Vie…

教唆chat ai 吵架--chatGPT和chatBing体验

教唆chat ai 吵架–chatGPT和chatBing体验 请注意,本文主观性非常高,只是一个参考性文章,无任何其他含义。 当我们谈到人工智能对话模型时,ChatGPT和ChatBing是两个备受关注的模型。它们都是自然语言处理领域中的重要里程碑&…

hive学习(仅供参考)

hive搭建Hive什么是hiveHive的优势和特点hive搭建解压、改名修改环境变量添加hive-site.xml将maven架包拷贝到hive替换一下gua包使环境变量生效初始化安装成功Hive 什么是hive 将结构化的数据文件映射为数据库表 提供类sql的查询语言HQL(Hive Query Language) Hive让更多的人…

【C++内存管理机制】学习笔记(4):重载operate new/::operator new..../new()

目录 简介C++应用程序 分配内存的途径重载::operator new/::operator delete重载operator new/operator delete重载new()/delete()结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简…

自学软件测试?一般人“别来沾边”...

本人7年测试经验,在学测试之前对电脑的认知也就只限于上个网,玩个办公软件。这里不能跑题,我为啥说:自学软件测试,一般人我还是劝你算了吧?因为我就是那个一般人! 软件测试基础真的很简单&…

mac环境,安装NMP遇到的问题

一 背景 项目开发中,公司项目需要使用本地的环境运行,主要是php这块的业务。没有使用docker来处理,重新手动撸了一遍。记录下其中遇到的问题; 二 遇到的问题 2.1 Nginx的问题 brew install nginx后,启动nginx,报错如下:nginx: [emerg] no "ssl_certificate" …

数据结构与算法(二):线性表

上一篇《数据结构与算法(一):概述》中介绍了数据结构的一些基本概念,并分别举例说明了算法的时间复杂度和空间复杂度的求解方法。这一篇主要介绍线性表。 一、基本概念 线性表是具有零个或多个数据元素的有限序列。线性表中数据…

零售电子标签解决方案

电子货架标签系统(ESLs),是一种放置在货架上、可替代传统纸质价格标签的电子显示装置, 每一个电子货架标 签通过有线或者无线网络与商场计算机数据库相连, 并将最新的商品价格通过电子货架标签上的屏显示出来。 电子…

2023年数学建模美赛D题(Prioritizing the UN Sustainability Goals)分析与编程

2023年数学建模美赛D题分析建模与编程 重要说明: 本文介绍2023年美赛题目,并进行简单分析;本文首先对 D题进行深入分析,其它题目分析详见专题讨论;本文及专题分析将在 2月17日每3小时更新一次,完全免费&am…

使用chatgpt生成快速入眠笔记

以下是使用chatgpt生成快速入眠笔记的简单过程 可以发现,增加详细两个字,可以让它表述的更明白。 通过询问“还有其他方法吗”,获取更多可能性,当然你也可以直接说继续 但实测继续有时候不会记住上一条提问 详细讲解一下程序员怎…

类似LeetCode的登录页面(小程序版)

前言每一个项目都会有用户端的注册和登录页面,对于刚入门的小白来说,在UI设计方面不太擅长,就算大致的UI界面设计出来了,但是落实到代码上来实现的时候就很容易卡住。这篇博客主要介绍的就是仿作一个类似LeetCode登录的简约大方页…

离线环境轻量级自动化部署

流程图: 常规系统发布的痛点 服务器频繁重启,上面部署的应用服务不能随之重启,导致服务时常宕机应用手动部署相对比较麻烦,步骤繁琐应用发布环境取决于发布人本地环境,导致不同发布人每次发布环境不一致,导…

【玩转多核异构】双核高速率CAN-FD评测——飞凌嵌入式

为了能够让更多的工程师朋友了解多核异构处理器,飞凌嵌入式特别推出了【玩转多核异构】专题,帮助大家解决在多核异构处理器的开发过程中遇到的问题。【玩转多核异构】专题持续更新中,欢迎您的持续关注。引言凭借实时性、抗干扰性和安全性等优…

Redis 开发规范

原创 | Java 2021 超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库中间件 Sharding-JDBC 和 MyCAT 源码解析作业调度中间件 Elastic-Job 源码解析分布式事务中间件 TCC-Transaction 源…

详细总结Ansible中使用playbook

文章目录前言一、Playbook的功能二、YAML三、playbook执行命令1.使用ansible-playbook部署ftp服务,并开启匿名用户访问权利2.使用ansible-playbook部署apache服务,设定默认发布文件内容为www.westos.org3.tags:标签四、使用vim解决yaml书写格…