高并发系统设计 --基于MySQL构建评论系统

如何用MySQL来实现评论系统

为什么我不用mongodb?

  1. 社区成熟度不如MySQL,redis
  2. 需要学习的东西很多,迁移,扩容,片建,集群
  3. redis > mongodb

架构设计

使用MySQL进行存储的话,就必须要用到Redis来做缓存,后台admin需要接通ES来进行查询,comment-service通过异步来进行写Redis和MySQL评论数据,MySQL和ES通过Canal进行binlog同步。

缓存模式

首先我们需要预读,我们读第一页的时候,也需要把第二页的内容加载出来。读第二页的时候,我们预先读第三页,这样可以避免大量的cache miss。

但是这里有一个致命的问题就是:当缓存抖动的时候,会触发大量的cache rebuild,因为我们使用了预加载,容易造成OOM(内存溢出)。因此我们需要使用消息队列来进行逻辑异步化,对于当前请求,只返回MySQL中的部分数据即可。

写的逻辑

至于写的操作,我们要穿透到存储层,因此最好使用消息队列异步削峰。例如我的评论发布出去了,用户过100ms才看到评论,这是无所谓的。

存储设计

comment_subject表

idint主键
obj_idint对象id
obj_typeint对象类型
member_idint作者id
countint评论总数
root_countint跟评总数
all_countint评论+回复总数
stateint状态 0:正常 1:隐藏
attrsint属性 0:置顶 1:不置顶
create_time+update_timedatatime创建时间,修改时间

obj_id+obj_type把评论系统设计成中台。 一般是指搭建一个灵活快速应对变化的架构,快速实现前端提的需求,避免重复建设,达到提高工作效率目的。

obj_id+obj_type形成了一个业务键,比如微博,发帖,发视频,你可以发视频,你也可以发文章,评论系统设计成中台。

comment_index

idint主键id
obj_idint对象id
obj_typeint对象类型
member_idint发表者id
rootint根评论id,不为0是回复评论
parentint父评论id,为0是root评论
floorint评论楼层
countint评论总数
root_countint根评论总数
likeint点赞数
hateint点踩数
stateint状态,0:正常;1:隐藏
attrsint属性
create_timedatetime创建时间
update_timedatetime修改时间

parent:父评论id,其实就是记录是否是回复评论。

comment_content表:

comment_idint主键
at_member_idsvarchar对象id
ipint对象类型
platformint发表者id
devicevarchar跟评论id,不为0是回复评论
messagevarchar评论内容
metavarchar评论元数据:背景,字体
create_timedatetime创建时间
update_timedatetime修改时间

index是索引表,content是内容表。

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

数据读取:基于obj_id + obj_typecomment_index表找到评论列表,where root=0 order by floor。之后根据comment_index的id字段捞出comment_content的评论内容。对于二级的子楼层,where parent/root in(id...)

为什么要把index和content分成两个表

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

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

缓存设计

comment_subject_cache【string】

keystringoid_type
valueintsubject marshal string
expireduration24h

comment_index_cache【sorted set】

keystringcache key:oid_type_sort其中sort为排序方式,0:楼层,1:回复数量
memberintcomment_id:评论id
scoredouble楼层号,回复数量,排序得分
expireduration8h

comment_content_cache

keystringcomment_id
valueintcontent
expireduration24h

comment_subject_cache:对应主题的缓存,value使用protobuf序列化的方式存入,这样调用rpc的时候速度可以更块一点。

comment_index_cache:使用redis sorted set进行索引的缓存,索引即数据的组织顺序,而非数据内容。通过预加载少量数据,通过增量加载的方式逐渐预热填充缓存,而redis sorted set skiplist的实现可以做到O(logN) + O(M)的时间复杂度,效率很高

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

comment_content_cache:对应评论内容数据,使用protobuf序列化的方式存入。

增量加载(目标表仅更新源数据表中变化的内容)+lazy加载(延迟加载,种将资源标识为非阻塞(非关键)资源并仅在需要时加载它们的策略)

可用性设计

其实就是各种缓存问题,消息队列消息等问题。

如果这个key是热点的key的话可以使用本地缓存+分布式缓存。

那么如何统计是否是热点呢?

这里,我们就移步到我们的下一篇文章了,谢谢大家。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: MySQL动物信息管理系统是一个使用MySQL数据库和Java编程语言开发的动物园信息管理系统。该系统可以帮助动物园管理员管理动物信息,包括动物种类、数量、饲养情况等。 胖子是一个由淘宝开发的分布式数据库中间件,可以将多个MySQL数据库组成一个分布式数据库集群,提供高可用性、高并发性和可扩展性。MySQL NDB是MySQL提供的一种高可用性、高性能的分布式数据库存储引擎,也可以用于构建分布式数据库集群。 在使用MySQL动物信息管理系统时,可以选择使用胖子或MySQL NDB来构建分布式数据库集群,以提高系统的可用性和性能。具体选择哪种方案需要根据实际情况进行评估和比较,包括数据量、访问量、负载情况、可用性要求等因素。 ### 回答2: MySQL动物信息管理系统是一个用于管理动物园内动物信息的系统。管理员通过该系统可以轻松地查看、添加、编辑和删除园内动物的相关信息。在这个系统中,MySQL NDB(Network DataBase)被用作数据库引擎。 MySQL NDB是MySQL的一种特殊的存储引擎,它特别适用于高可用性和高可扩展性的应用场景。相比其他存储引擎,MySQL NDB具有更好的数据复制和分区能力,并且可以在不同的服务器上实现数据的同步和共享。对于一个动物园管理员来说,MySQL NDB的特性对于动物信息管理系统非常有用。 首先,由于动物园中的动物信息是实时更新的,管理员需要能够及时地获取最新的信息。而MySQL NDB可以实现数据的实时同步和复制,在多个服务器上保持数据的一致性和即时性。这意味着管理员可以在任何时间和任何地点访问到最新的动物信息。 其次,动物园中的动物数量可能非常庞大,而MySQL NDB拥有良好的可扩展性。它可以以分布式集群的形式运行,将数据分片存储在多个节点上,并实现负载均衡和故障恢复。这就意味着即使在大规模的动物信息管理系统中,MySQL NDB也能保持良好的性能和可靠性。 最后,由于管理员可能需要进行复杂的查询和统计操作,MySQL NDB的分区功能可以使数据库更加高效。管理员可以根据动物的种类、栖息地、饲养情况等因素进行分区,从而提高查询速度和效率。此外,由于MySQL NDB支持并行查询处理,在高负载情况下可以更好地处理管理员的请求。 总之,MySQL NDB作为动物信息管理系统数据库引擎,具有高可用性、高可扩展性和高效率的特点,能够帮助管理员轻松地管理动物园内的动物信息。 ### 回答3: MySQL动物信息管理系统是一个用于管理动物园基本信息的数据库系统。管理员可以通过该系统进行动物的录入、查询、更新和删除等操作。 在管理员使用MySQL NDB(MySQL Cluster)作为数据库引擎时,会有一些与传统MySQL数据库不同的特点和优势。 首先,MySQL NDB是一个分布式数据库引擎,能够将数据库分布在多台计算机上,实现高可用性和容错性。这对于动物信息管理系统来说是非常重要的,因为即使其中一台计算机发生故障,系统仍然可以继续正常运行,管理员可以继续对动物信息进行管理。 其次,MySQL NDB支持数据库的自动分片(sharding)和自动数据重分布。这意味着当数据库的数据增长超过一台计算机的处理能力时,管理员无需手动进行数据分片和迁移操作,系统会自动将数据分散存储在多台计算机上,以平衡负载,并在需要时对数据进行重分布。 此外,由于MySQL NDB采用了内存数据库(in-memory database)的设计思路,因此具有非常高的读写性能,适合处理大量的并发请求。在动物信息管理系统中,管理员可以通过MySQL NDB迅速查找和修改动物信息,使系统响应更加迅捷。 然而,MySQL NDB也存在一些限制。例如,MySQL NDB不支持某些传统MySQL数据库提供的功能,如全文搜索和外键约束等。管理员在设计和开发动物信息管理系统时需要考虑到这些限制,并根据实际需求进行权衡和选择。 总的来说,MySQL NDB作为数据库引擎对于动物信息管理系统来说是一种可行的选择,能够提供高可用性、容错性和良好的性能。管理员可以通过合理使用MySQL NDB的特性和优势来设计和实现功能完善的动物信息管理系统

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡桃姓胡,蝴蝶也姓胡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值