设计评论系统(缓存怎么做)
mysql是否有主从延迟,如何解决
mysql有主从延迟
主从延迟主要因为mysql主从同步的机制,mysql有三种同步机制
- 同步复制:事务线程等待所有从库复制成功响应
- 异步复制:事务不等待从库直接响应
- 半同步复制:事务线程不用等待所有从库复制完成,只要一部分复制成功响应即可
分布式事务解决方案
rokectmq事务消息实现原理
rocketmq采用了2PC的思想,事务消息的提交分为两个阶段。阶段一,Producer发送half消息到broker,broker储存消息bing并进行响应,此时消息是Consumer不可见的。阶段二,Producer根据half消息发送结果进行处理,如果half消息发送成功,则执行本地事务并提交事务状态给broker。
事务状态有三种
- COMMIT_MESSAGE:事务提交,消息对consumer可见
- ROLLBACK_MESSAGE:事务回滚,丢弃消息
- UNKNOWN_MESSAGE:事务未知,暂不处理,稍后处理
Broker如何实现事务half消息Consumer不可见:改写topic并将原参数保存
half消息回查是由broker发起的,broker会定期对UNKNOWN_MESSAGE执行任务回查防止producer提交状态失败,为避免无限回查默认回查次数为15
rocketmq如何保住消息不丢失
rocketmq消息主要有三个步骤:
- producer发送消息到broker
- broker持久化消息
- consumer消费消息
下面分别从三个角度讨论rocketmq是如何保住消息不丢失的
Producer
对于producer来说消息发出去之后,如果消息未能正确存储则算消息丢失
消息发送后返回四种状态码,发送失败时producer会进行重发(默认重发2次)
- SEND_OK:消息发送成功(并不代表消息一定会发送成功,还取决于broker的刷盘方式)
- FLUSH_DISK_TIMEOUT:如果broker配置的刷盘方式为同步刷盘, broker接到消息并且未能在配置的时间内落盘,则返回该状态
- FLUSH_SLAVE_TIMEOUT:如果broker配置的主从同步方式为SYNC_MASTER,并且未能在配置时间内完成同步,则返回该状态
- SLAVE_NOT_AVALIBLE:如果broker是主节点并且配置的同步方式为SYNC_MASTER,在没有可靠的slave节点时返回该状态
异步消息需要设置回调函数
事务消息可能会出现ack发送失败的情况,严格意义来讲消息不算丢失(可以在commit log中看到)
Broker
对于broker来说消息默认存储到broker的内存,异步保存到磁盘,磁盘崩溃则算消息丢失
broker有两种刷盘机制:同步刷盘、异步刷盘
- 同步刷盘:broker接到消息后,立即通知刷盘线程将消息刷到磁盘,成功后返回ack
- 异步刷盘(默认):broker接到消息后,保存到缓存中(pagecache),直接返回ack,当内存中消息累计到一定程度统一触发写入程序。
broker有两种同步机制:异步复制、同步双写
- 同步双写:broker-master接到消息后将消息复制给slave复制成功后返回ack
- 异步复制:broker-master接到消息后直接返回ack,异步复制slave
rocketmq不是百分之百保证消息不丢失的(异步刷盘、异步复制都不能百分百保证),但是rocketmq可以通过调整配置(同步刷盘、同步双写)实现消息不丢失。
Consumer
消息完成持久化后,consumer拉取之后未能成功消费且未反馈broker,算作消息丢失
consumer会在本地持久化保存消费offset,consumer消费消息之后会向broker提交ack。