同步说的是你server服务器端的执行方式。
同步和异步:同步和异步一般是面向操作系统与应用程序对IO操作的层面上来区别的。
同步时,应用程序会直接参与IO读写操作,并且我们的应用程序会直接阻塞到某一个方法上,直到数据准备就绪,或者采用轮询的策略实时检查数据的就绪状态,如果就绪则获取数据。
异步时,则所有的IO读写操作交给操作系统处理,与我们的应用程序没有直接关系,我们的程序不关心IO读写,当操作系统完成了IO读写操作时,会给我们应用程序发送通知,我们的应用程序会直接拿走数据即可。
NIO的实质仍是同步IO,因为应用程序参与了IO读写,不是bio中的单向inputstream和outputstream,而是双向的socketchannel。
阻塞说的是具体的技术,接收数据的方式、状态(io,nio)。
nio之所以叫非阻塞IO,是因为有一个多路复用选择器Selector,是一个单线程轮询上千上万已经注册在Selector上的客户端channel(同理server也应该注册到Selector上)。只是NIO的一大进步,之所以NIO使用的少,是NIO中的buffer不太好用。有个position这个属性要flip才能复位。
后续会介绍netty或者mina对NIO原生API做了封装,可以理解更好用的API,mina2支持异步通信NIO2(AIO)。
SocketIO(NIO客户端与服务端通信双向实现)
1 | package org.bopan.nio; |
1 | package org.bopan.nio; |
从Paxos到Zookeeper分布式一致性原理与实践(一)
更新的并发性
《深入理解计算机系统》一书对并发进行了如下的定义:如果逻辑控制流在时间上重叠,那么它们就是并发的。这里提到的逻辑控制流,通俗地讲,就是一次程序操作,比如读取或者更新内存中的变量。
分布式一致性问题
所谓的分布式一致性问题,是指在分布式环境中引入数据复制机制后,不同数据节点间可能出现的,并无法依靠计算机应用程序自身解决的数据不一致情况。简单地讲,数据一致性就是指在对一个副本数据进行更新的同时,必须确保也能够更新其他副本,否则副本之间的数据将不再一致。
一致性级别划分:
·强一致性
·弱一致性
·最终一致性
ACID
事务的ACID特性:原子性、一致性、隔离性、持久性
A:事务中包含的各项操作在一次执行过程中,只允许出现全部成功执行 或者 全部不执行。
C:事务执行的结果必须是使数据库从一个一致性状态转变到另一个一致性状态。
I:事务的隔离性是指在并发环境中,并发的事务是相互隔离的,一个事务的执行不能被其他事务干扰。
在标准的SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。其中Oracle默认隔离级别是授权读取,Mysql默认隔离级别是可重复读取。
脏读、幻读、不可重复读
1.脏读:
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
2.不可重复读:
是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)
例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。
3.幻读:
是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象
发生了幻觉一样。
例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。
D:事务的持久性是指一个事务一旦提交,它对数据库中的对应数据的状态变更就应该是永久性的。
分布式事务
场景:
一个跨银行的转账操作涉及调用两个异地的银行服务,其中一个是本地银行提供的取款服务,另一个则是目标银行提供的存款服务,这两个服务本身是无状态并且是互相独立的,共同构成了一个完整的分布式事务。如果从本地银行取款成功,但是因为某种原因存款服务失败了,那么就必须回滚到取款前的状态,否则用户可能会发现自己的钱不翼而飞了。
分布式事务也可以被定义为一种嵌套型的事务,也具有ACID事务特性。
CAP和BASE理论(分布式系统经典理论)
CAP理论告诉我们,一个分布式系统不可能同时满足一致性(C:Consistency)、可用性(A:Availability)和分区容错性(P:Partition tolerance)这三个基本需求,最多只能同时满足其中的两项。
BASE理论是Basic Available(基本可用)、Soft state(弱状态)和Eventually consistent(最终一致性)三个短语的简写。
其核心思想是即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventually consistency)。
Base理论面向的是大型高可用可扩展的分布式系统,和传统的ACID特性是相反的 ,ACID要求强一致性,而是提出通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。ACID特性与BASE理论往往会结合使用。
为什么kafka使用磁盘而不是内存(阅读博客)
kafka最核心的思想是使用磁盘,而不是使用内存,可能所有人都会认为,内存的速度一定比磁盘快!
举例:这也是我们使用缓存技术的原因啊!在理解了Kafka的设计思想,磁盘的顺序读写速度和内存持平(这个有待验证)
而且Linux对于磁盘的读写优化也比较多,包括read-ahead和write-behind,磁盘缓存等。如果在内存做这些操作的时候,一个是Java对象的内存开销很大(回顾JVM)
另一个是随着堆内存数据的增多,Java的GC时间会变得很长,使用磁盘操作有以下几个好处:
1.磁盘缓存由Linux系统维护,减少了程序员的不少操作。
2.磁盘顺序读写速度超过内存随机读写。
3.JVM的GC效率低,内存开销大。使用磁盘可以避免这一类问题。
4.系统冷启动后,磁盘缓存依然可用。
RocketMQ与Kafka对比(阅读博客阿里中间件)
阅读博客之前,我只知道RocketMQ与kafka是否遵循JMS规范的区别。
数据可靠性
·RocketMQ支持异步实时刷盘,同步刷盘,同步复制,异步复制
·Kafka使用异步刷盘方式,异步复制/同步复制
总结:RocketMQ的同步刷盘在单机可靠性上比Kafka更高,不会因为操作系统Crash,导致数据丢失。Kafka同步复制理论上性能低于RocketMQ的同步复制,原因是Kafka的数据以分区为单位组织,意味着一个Kafka实例上会有几百个数据分区,RocketMQ一个实例上只有一个数据分区,RocketMQ可以充分利用IO组Commit机制,批量传输数据,配置同步复制与异步复制相比,性能损耗约20%~30%。
严格的消息顺序(可靠性)
·kafka支持消息顺序,但是一台代理宕机后,就会产生消息乱序
·RocketMQ支持严格的消息顺序,在顺序消息场景下,一台Broker宕机后,发送消息会失败,但是不会乱序
(未完待续)
JMS
传统模式下的问题:
1.同步通信:客户发出调用后,必须等待服务对象完成处理并返回结果后才能继续执行。
2.客户和服务对象的生命周期紧密耦合:客户进程和服务对象进程都必须正常运行;如果由于服务对象崩溃或者网络故障导致客户的请求不可达,客户会接收到异常;
3.点对点通信:客户的一次调用只发送给某个单独的目标对象。
面向消息的中间件(Message-Oriented Middleware, MOM)较好的解决了以上问题。发送者将消息发送给消息服务器,消息服务器将消息存放在若干队列中,在合适的时候再将消息转发给接收者。这种模式下:
1.发送和接收是异步的,发送者无需等待;
2.发送消息的时候接收者不一定运行,接收消息的时候发送者也不一定运行;
3.一对多通信,对于一个消息可以有多个接收者。
JMS定义了Java中访问消息中间件的接口。JMS只是接口,并没有给予实现,实现JMS接口的消息中间件称为JMS Provider。MOM有很多种类,比如Apache的ActiveMQ、Alibaba的RocketMQ、IBM的MQSeries(听说很强)、RabbitMQ等等,他们都遵循JMS规范。另外还有大数据领域的Kafka并没有遵循JMS规范。
JMS术语
Provider:生产者
Consumer:消费者
PTP:Point to Point,点对点消息模型
Queue:队列目标
Pub/sub:Publish/Subscribe,即发布/订阅的消息模型
Topic:主题目标
ConnectionFactory:连接工厂,JMS用它创建连接
Connection:JMS客户端到JMS Provider的连接
Destination:消息的目的地
Session:会话,一个发送或接收消息的线程;表示一个单线程的上下文,用于发送和接收消息。由于会话是单线程的,所以消息是连续的,就是说消息是按照发送的顺序一个一个接收的。会话的好处是它支持事务。如果用户选择了事务支持,会话上下文将保存一组消息,直到事务被提交才发送这些消息。在提交事务之前,用户可以使用回滚操作取消这些消息。一个会话允许用户创建消息生产者来发送消息,创建消息消费者来接收消息
Message:消息(核心内容)
JMS定义了五种不同的规范的Message。
StreamMessage Java原始值得数据流
MapMessage 键值对
TextMessage 一个字符串对象
ObjectMessage 一个序列化的Java对象
BytesMessage 一个未解释字节的数据流(Byte字节数组)