评论系统架构设计

架构设计最重要的就是理解整个产品体系在系统中的定位。搞清楚系统背后的背景,才能做出最佳的设计和抽象。不要做需求的翻译机,先理解业务背后的本质,事情的初衷。

功能模块

评论系统,我们往小里做就是视频评论系统,往大里做就是评论平台,可以接入各种业务形态。

  • 发布评论: 支持回复楼层、楼中楼。
  • 读取评论: 按照时间、热度排序。
  • 删除评论: 用户删除、作者删除。
  • 管理评论: 作者置顶、后台运营管理(搜索、删除、审核等)。

架构设计

概览

  • BFF: comment
    复杂评论业务的服务编排,比如访问账号服务进行等级判定,同时需要在 BFF 面向移动端/WEB场景来设计 API,这一层抽象把评论的本身的内容列表处理(加载、分页、排序等)进行了隔离,关注在业务平台化逻辑上。

  • Service: comment-service
    服务层,去平台业务的逻辑,专注在评论功能的 API 实现上,比如发布、读取、删除等,关注在稳定性、可用性上,这样让上游可以灵活组织逻辑把基础能力和业务能力剥离。

  • Job: comment-job
    消息队列的最大用途是消峰处理。
     

comment service

专注在评论数据处理。

读的核心逻辑:
Cache-Aside 模式,先读取缓存,再读取存储。早期 cache rebuild 是做到服务里的,对于重建逻辑,一般会使用 read ahead 的思路,即预读,用户访问了第一页,很有可能访问第二页,所以缓存会超前加载,避免频繁 cache miss。当缓存抖动是否,特别容易引起集群 hundering herd 现象,大量的请求会触发 cache rebuild,因为使用了预加载,容易导致服务 OOM。所以我们开到回源的逻辑里,我们使用了消息队列来进行逻辑异步化,对于当前请求只返回 mysql 中部分数据即止。

写的核心逻辑:
我们担心类似“明星出轨”等热点事件的发生,而且写和读相比较,写可以认为是透穿到存储层的,系统的瓶颈往往就来自于存储层,或者有状态层。对于写的设计上,我们认为刚发布的评论有极短的延迟(通常小于几 ms)对用户可见是可接受的,把对存储的直接冲击下放到消息队列,按照消息反压的思路,即如果存储 latency 升高,消费能力就下降,自然消息容易堆积,系统始终以最大化方式消费。

Kafka 是存在 partition 概念的,可以认为是物理上的一个小队列,一个 topic 是由一组 partition 组成的,所以 Kafka 的吞吐模型理解为: 全局并行,局部串行的生产消费方式。对于入队的消息,可以按照 hash(comment_subject) % N(partitions) 的方式进行分发。那么某个 partition 中的 评论主题的数据一定都在一起,这样方便我们串行消费。
同样的,我们处理回源消息也是类似的思路。

comment admin

mysql binlog 中的数据被 canal 中间件流式消费,获取到业务的原始 CRUD 操作,需要回放录入到 es 中,但是 es 中的数据最终是面向运营体系提供服务能力,需要检索的数据维度比较多,在入 es 前需要做一个异构的 joiner,把单表变宽预处理好 join 逻辑,然后倒入到 es 中。
一般来说,运营后台的检索条件都是组合的,使用 es 的好处是避免依赖 mysql 来做多条件组合检索,同时 mysql 毕竟是 oltp 面向线上联机事务处理的。通过冗余数据的方式,使用其他引擎来实现。
es 一般会存储检索、展示、primary key 等数据,当我们操作编辑的时候,找到记录的 primary key,最后交由 comment-admin 进行运营测的 CRUD 操作。

comment

comment 作为 BFF,是面向端,面向平台,面向业务组合的服务。所以平台扩展的能力,我们都在 comment 服务来实现,方便统一和准入平台,以统一的接口形式提供平台化的能力。

  • 依赖其他 gRPC 服务,整合统一平台测的逻辑(比如发布评论用户等级限定)。
  • 直接向端上提供接口,提供数据的读写接口,甚至可以整合端上,提供统一的端上 SDK。
  • 需要对非核心依赖的 gRPC 服务进行降级,当这些服务不稳定时。

存储设计

数据库设计

数据写入: 事务更新 comment_subject,comment_index,comment_content 三张表,其中 content 属于非强制需要一致性考虑的。可以先写入 content,之后事务更新其他表。即便 content 先成功,后续失败仅仅存在一条 ghost 数据。

数据读取: 基于 obj_id + obj_type 在 comment_index 表找到评论列表,WHERE root = 0 ORDER BY floor。之后根据 comment_index 的 id 字段捞出 comment_content 的评论内容。对于二级的子楼层,WHERE parent/root IN (id…)。

因为产品形态上只存在二级列表,因此只需要迭代查询两次即可。对于嵌套层次多的,产品上,可以通过二次点击支持。

索引内容分离

comment_index: 评论楼层的索引组织表,实际并不包含内容。comment_content: 评论内容的表,包含评论的具体内容。其中 comment_index 的 id 字段和 comment_content 是1对1的关系,这里面包含几种设计思想。

  • 表都有主键,即 cluster index,是物理组织形式存放的,comment_content 没有 id,是为了减少一次 二级索引查找,直接基于主键检索,同时 comment_id 在写入要尽可能的顺序自增。
  • 索引、内容分离,方便 mysql datapage 缓存更多的 row,如果和 context 耦合,会导致更大的 IO。长远来看 content 信息可以直接使用 KV storage 存储。

缓存设计

comment_subject_cache: 对应主题的缓存,value 使用 protobuf 序列化的方式存入。我们早期使用 memcache 来进行缓存,因为 redis 早期单线程模型,吞吐能力不高。

comment_index_cache: 使用 redis sortedset 进行索引的缓存,索引即数据的组织顺序,而非数据内容。参考过百度的贴吧,他们使用自己研发的拉链存储来组织索引,我认为 mysql 作为主力存储,利用 redis 来做加速完全足够,因为 cache miss 的构建,我们前面讲过使用 kafka 的消费者中处理,预加载少量数据,通过增量加载的方式逐渐预热填充缓存,而 redis sortedset skiplist 的实现,可以做到 O(logN) + O(M) 的时间复杂度,效率很高。

sorted set 是要增量追加的,因此必须判定 key 存在,才能 zdd。

comment_content_cache: 对应评论内容数据,使用 protobuf 序列化的方式存入。类似的我们早期使用 memcache 进行缓存。

可用性设计

Singleflight

对于热门的主题,如果存在缓存穿透的情况,会导致大量的同进程、跨进程的数据回源到存储层,可能会引起存储过载的情况,如何只交给同进程内,一个人去做加载存储?

使用归并回源的思路:
singleflight package - golang.org/x/sync/singleflight - pkg.go.dev

同进程只交给一个人去获取 mysql 数据,然后批量返回。同时这个 lease owner 投递一个 kafka 消息,做 index cache 的 recovery 操作。这样可以大大减少 mysql 的压力,以及大量透穿导致的密集写 kafka 的问题。

更进一步的,后续连续的请求,仍然可能会短时 cache miss,我们可以在进程内设置一个 short-lived flag,标记最近有一个人投递了 cache rebuild 的消息,直接 drop。

Q:为什么我们不用分布式锁之类的思路?

热点

流量热点是因为突然热门的主题,被高频次的访问,因为底层的 cache 设计,一般是按照主题 key 进行一致性 hash 来进行分片,但是热点 key 一定命中某一个节点,这时候 remote cache 可能会变为瓶颈,因此做 cache 的升级 local cache 是有必要的,我们一般使用单进程自适应发现热点的思路,附加一个短时的 ttl local cache,可以在进程内吞掉大量的读请求。
在内存中使用 hashmap 统计每个 key 的访问频次,这里可以使用滑动窗口统计,即每个窗口中,维护一个 hashmap,之后统计所有未过去的 bucket,汇总所有 key 的数据。
之后使用小堆计算 TopK 的数据,自动进行热点识别。

0 条评论

未登录用户

支持 Markdown 语法预览使用 GitHub 登录

来做第一个留言的人吧!


 

----------- 本文结束 -----------

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值