ONS应用场景:
1、异步
2、解耦
3、最终一致
4、并行
举例:淘宝购买话费充值的流程。
不用消息中间件的话,交易完成由最慢的一个环节决定,其中一个环节挂掉都有可能导致交易失败。
解耦。引入中间件后,无需等待后端所有请求。后端请求跟中间件通信。会有消息堆积,就算后端挂掉重启后可以继续消费。前端也不受影响。
最终一致。中间的某时刻有可能出现状态未同步,但数据最终状态一定会保持一致。
并行。提升效率。
ONS设计四路
设计假定:
每台pc机器都可能down机
任意集群都可以处理能力不足
最坏情况一定会发生 TPS,QPS
内网环境需要低延迟来提供最佳用户体验,降低投递延迟
关键设计
分布式集群化
强数据安全
海量数据堆积,ons的最需求点
毫秒级投递延迟
无单点集群化设计(分布式设计,不会被拖后腿,不能有瓶颈才能可扩展)
理论上无限的处理能力
集群级别高可用
最大差别点--消息的发布者和订阅者都必须是集群,可自动按需扩缩。其他mq会有单点
强数据安全和高可用
任何一个队列都是可以由单机队列RAID保证数据冗余;跨机的异步队列复制冗余;有多组队列
海量数据堆积能力
任意集群都可以出现处理不足
消息堆积是常态:就算是部分后端跟不上也会导致堆积。
有两个不能容许:1、中间件不能挂掉 2、前端的记录写入不能被延迟,系统本身不能慢。
(其他MQ的TPS,QPS可能很高很漂亮,但这些系统最大的问题在于消息不能堆积,一堆积就崩。因为调优时就没有考虑到,而这是ONS优点)
大量堆积,系统稳定,延迟不增
毫秒级的投递延迟
kafka关注点是在于消息处理的吞吐量,并没有关注到延迟,采用主要是拉
采用长轮训/推送方式:推-延迟小,订阅者会很轻量 拉--定期去拉,若频次快,消息服务器压力大,关注吞吐量
推拉结合则在于:先告诉订阅者有消息,然后订阅者再去拉消息。缺点:消息交互次数多
ONS 采用推拉平衡:订阅者去拉,没有消息等待到消息服务器收到消息后才会主动推送消息。
ONS 的关键概念
Topic(主题)
第一级消息类型;书的标题;交易消息
Tag(消息类型)
第二级消息类型;书的目录,方便检索;交易消息,创建和完成
*发送/订阅组(ProducerID/ConsumerID),这个概念只有ONS有,因为ONS侧重集群。
发送/接受机器的集群,标记这台机器属于哪个集群,发送or接收。一个配置文件搞定。集群自动化管理及其的增减。ons会随机选择一台接收机哦!
消息乱序问题
产生原因:
吞吐+容错 vs 方便 容易理解
若有多台消息服务器和多个订阅者,消息的有0~7阶段,0给了A订阅者,那1也必须接着给A,若对于0,A没有响应,则必须阻塞。
有序对接优劣分析:
劣势:并行度瓶颈;异常处理
队列吞吐量最有模型应该为:尽量保证队列有序,特殊极少情况可以乱序,出现乱序也必须做出异常处理
阿里中间件经验谈:
避开问题。。。
只关注比如交易的付款状态
多人通过消息转账,并不关注同步状态的顺序
不关注乱序的应用是大量存在的
队列无需并不意味着消息无序(TCP协议,包的到达是乱序的,但在协议里边有消息顺序的ID号,接收可以通过ID恢复组包是有序的)
将锁分离的越细越可以提高并行度。
消息重复问题
产生原因:
网络不可达:怎么办?1、回滚事务,但开销太大 2、再发一次请求,这样就可能出现重复
怎么办呢?
最好的解决方法是恰好不需要--幂等 S*S=S 无论做多少次结果都一样
(非幂等) update set col = col +1 非幂等消息去重 1、保证有唯一ID标记每条消息 2、保证信息处理成功豫去重表日志同时出现
非幂等代价就是TPS增加,写入增加。需要增加机器。
分布式事务与ONS
DRDS实践-- 事务的分布式优化
ONS消息与事务转账
只要出现跨机事务,就会有事务间的等待。解决:将一个大事务拆分为小的事务。小的事务间通过ONS异步并行,从而降低延迟。
关键设计难点
如何保证消息发出和bob账户减钱同时成功or失败?消息处理超时/失败如何解决?
先发消息到ons,执行事务,在发送一个确认消息发送。然后ons才会给接收者发消息。若发送消息到ons后,确认消息10min为达到,则返回去询问发送者。这样来保证分布式事务的完成。
处理超时问题(重复)
额外增加去重表来防止重复。
消息失败
传统是直接回滚。分布式系统则采用ons发现比如smith账户销户,则让人工处理,挂起。反正不回滚。这就是送达模型。
____________________________________________________________________________________________________________________________
注意:根据Amdahl定律,使用多核CPU对系统进行优化,优化的效果取决于CPU的数量以及系统中的串行化程序的比重。CPU数量越多,串行化比重越低,则优化效果越好。仅提高CPU数量而不降低程序的串行化比重,也无法提高系统性能。