赞
踩
consistency: 一致性,所有数据节点上的数据一致性和正确性
availability:可用性,每个操作总能在一定的时间内返回结果
partition tolerance:分区容错,是否可以对数据进行分区
强一致性:一修改,马上更新,用户拿到永远是最新的消息
弱一致性:不保证用户会马上拿到最新的消息
最终一致性:弱一致性的一种特例,系统保证在没有后续更新的前提下,返回上一次更新的结果。
一台机器负责数据的更新,其他机器负责从主机器上同步数据。
(1)协调者向所有参与者发送事务执行的请求,并等待所有参与者反馈事务的执行结果。事务参与者收到请求后,执行事务,并记录到事务日志里面,但不真正提交。参与者将自己事务的执行情况反馈给协调者,同时阻塞等待协调者的后续指令
(2)当所有参与者都能够正常执行事务后,协调者向各个参与者发送commit通知,请求提交事务。参与者收到事务提交通知之后,执行commit的操作,然后释放占有的资源。参与者向协调者返回事务提交的结果。
(3)当一个或者多个参与者回复事务执行失败或者协调者等待超时,协调者向各个参与者发送事务回滚的请求。参与者收到事务回滚通知后,执行回滚操作,并释放占有的资源。参与者向协调者反馈回滚的信息。
(1)同步阻塞:当参与者占用第三方资源等待协调者的通知时,其他第三方节点不能访问当前的资源
(2)单点故障:一旦协调者发生故障,参与者会一直阻塞下去,尤其是第二阶段,所有的参与者还处在锁定事务资源的状态,无法继续完成事务操作。
(3)数据的不一致性:在第二阶段中,当局部网络异常或者协调者在发送commit请求的时候出现故障,会导致一部分参与者没有收到commit请求,一部分收到,这样会导致数据的部分一致性
将原本两阶段提交的第一阶段一分为二;对参与者引入超时机制
(1)协调者询问参与者是否能正常执行事务,如果协调者接收到所有参与者返回的确定信息,则再向所有参与者发送执行事务的请求
(2)参与者执行事务,并将事务记录在日志中,但不真正提交,并将事务的执行情况返回给协调者,协调者收到所有参与者的确认消息后向所有参与者发送提交通知,若收到一个或者多个异常的消息,则向所有参与者发送事务回滚的请求。
(3)参与者在等待协调者发送commit请求期间,若等待超时,则会自动执行commit请求,从而避免陷入阻塞。
在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么最后能得到一个一致的状态。paxos协议就是保证每个节点执行相同的命令序列,提议者把客户端产生的议题发给发给决策者,由决策者决定使用哪个议题
(1)在申请阶段,多个提议者向决策者对一个议案发出请求,在同一时刻,只有一个提议者能够获得一半以上的决策者的同意。之后进入沟通阶段,提议者会根据决策者返回的内容提交自己的议案,最终要么达成一致性,要么重新回到申请阶段
(2)paxos最重要的两个组件时提议者和决策者。提议者采用抢占的方式取获取一半以上的决策者的认同。决策者采用“喜新厌旧”的原则,一旦更大的议案申请访问,马上让旧的议案访问失效,不再接收它们提交的取值。然后给新的提议者发送访问权限,接收新的议案取值。
解耦
多个应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程都失败
异步
生产者生产消息放到消息队列后直接返回继续操作,不用等消费者接收消息
削峰
大量的请求可以暂时存放到消息队列中,等待处理
点对点模式
生产者生产消息发送到队列中,消费者读取队列中的数据,然后队列删除该消息,消费者不可能接收到重复的消息
发布/订阅模式
生产者生产消息放到队列中,系统将这些消息发送给不同的订阅者
每个消息可以有多个订阅者
发布者和订阅者之间有时间上的依赖,针对某个主题的订阅者,必须先创建订阅实例才能订阅该主题消息
为了消费消息,订阅者需要提前订阅该消息,并保持在线运行
中小型软件公司,建议选RabbitMQ。
优点
缺点
服从JMS规范,运行在Java语言所支持的平台之上 ,它相比RabbitMQ的缺点是社区活跃度低,会出莫名其妙的问题,会丢失消息 ,不适合上千个队列的申请
阿里开发,使用java实现
优点:
优点
跟消息队列模型的集群有关,比如
RocketMQ,集群有多种模式,包括多主多从的异步复制模式,多主多从的同步双写模式
Kafka集群:
一个典型的Kafka集群中包含若干Producer(可以是web前端产生的Page View,或者是服务器日志,系统CPU、Memory等),若干broker(Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高),若干Consumer Group,以及一个Zookeeper集群。Kafka通过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance。Producer使用push模式将消息发布到broker,Consumer使用pull模式从broker订阅并消费消息。
为什么会造成重复消费
正常情况下,消费者在消费消息时候,消费完毕后,会发送一个确认信息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除。只是不同的消息队列发送的确认信息形式不同,例如RabbitMQ是发送一个ACK确认消息,RocketMQ是返回一个CONSUME_SUCCESS成功标志,kafka实际上有个offset的概念,就是每一个消息都有一个offset,kafka消费过消息后,需要提交offset,让消息队列知道自己已经消费过了。 因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将该消息分发给其他的消费者。
解决方案
在客户端或者使用第三方介质开一个redis缓存,给每个消息设置一个唯一的id,并存储到redis中,每次收到消息先到redis中查找,若存在redis中,就丢掉这个消息,不存在则接收这个消息,然后存到redis中
提供事务和确认模式来确保生产者不丢消息。
事务机制:发送消息前,开启事务,然后发送消息,如果发送过程中出现什么异常,事物就会回滚,如果发送成功则提交事务(channel.txCommit())。 然而缺点就是吞吐量下降了。
确认模式:一旦channel进入confirm模式,所有在该信道上面发布的消息都将会被指派一个唯一的ID,一旦消息被投递到所有匹配的队列之后,rabbitMQ就会发送一个Ack给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了.如果rabiitMQ没能处理该消息,则会发送一个Nack消息给生产者,生产者可以进行重试操作。
一般用confirm
消息队列丢数据
处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。这个持久化配置可以和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发
消费者丢数据
消费者丢数据一般是因为采用了自动确认消息模式。这种模式下,消费者会自动确认收到信息。这时rahbitMQ会立即将消息删除,这种情况下如果消费者出现异常而没能处理该消息,就会丢失该消息。
通过某种算法,将需要保持先后顺序的消息放到同一个消息队列中(kafka中就是partition,rabbitMq中就是queue)。然后只用一个消费者去消费该队列。
若是多个消费者消费一个队列的话,就重试就好了,只要保证入队有序,出队的顺序由消费者自己负责。
客户端配置,通过代理去访问服务器
不需要配置,对客户端来说代理本身就是服务器,但是代理是从其他服务器拿数据再返回
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。