我们的服务器从单机发展到拥有多台机器的分布式系统,各个系统之前需要借助于网络进行通信,原有单机中相对可靠的方法调用以及进程间通信方式已经没有办法使用,同时网络环境也是不稳定的,造成了我们多个机器之间的数据同步问题,这就是典型的分布式事务问题。
在分布式事务中事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。分布式事务就是要保证不同节点之间的数据一致性。
1、2PC(二阶段提交)方案 - 强一致性
2、3PC(三阶段提交)方案
3、TCC (Try-Confirm-Cancel)事务 - 最终一致性
4、Saga事务 - 最终一致性
5、本地消息表 - 最终一致性
6、MQ事务 - 最终一致性
消息的生产方,除了维护自己的业务逻辑之外,同时需要维护一个消息表。这个消息表里面记录的就是需要同步到别的服务的信息,当然这个消息表,每个消息都有一个状态值,来标识这个消息有没有被成功处理。
发送放的业务逻辑以及消息表中数据的插入将在一个事务中完成,这样避免了业务处理成功 + 事务消息发送失败,或业务处理失败 + 事务消息发送成功,这个问题。
举个栗子:
我们假定目前有两个服务,订单服务,购物车服务,用户在购物车中对几个商品进行合并下单,之后需要情况购物车中刚刚已经下单的商品信息。
1、消息的生产方也就是订单服务,完成了自己的逻辑(对商品进行下单 *** 作)然后把这个消息通过 mq 发送到需要进行数据同步的其他服务中,也就是我们栗子中的购物车服务。
2、其他服务(购物车服务)会监听这个队列;
1、如果收到这个消息,并且数据同步执行成功了,当然这也是一个本地事务,就通过 mq 回复消息的生产方(订单服务)消息已经处理了,然后生产方就能标识本次事务已经结束。如果是一个业务上的错误,就回复消息的生产方,需要进行数据回滚了。
2、很久没收到这个消息,这种情况是不会发生的,消息的发送方会有一个定时的任务,会定时重试发送消息表中还没有处理的消息;
3、消息的生产方(订单服务)如果收到消息回执;
1、成功的话就修改本次消息已经处理完,也就是本次分布式事务的同步已经完成;
2、如果消息的结果是执行失败,同时在本地回滚本次事务,标识消息已经处理完成;
3、如果消息丢失,也就是回执消息没有收到,这种情况也不太会发生,消息的发送方(订单服务)会有一个定时的任务,定时重试发送消息表中还没有处理的消息,下游的服务需要做幂等,可能会收到多次重复的消息,如果一个回复消息生产方中的某个回执信息丢失了,后面持续收到生产方的 mq 消息,然后再次回复消息的生产方回执信息,这样总能保证发送者能成功收到回执,消息的生产方在接收回执消息的时候也要做到幂等性。
这里有两个很重要的 *** 作:
1、服务器处理消息需要是幂等的,消息的生产方和接收方都需要做到幂等性;
2、发送放需要添加一个定时器来遍历重推未处理的消息,避免消息丢失,造成的事务执行断裂。
该方案的优缺点
优点:
1、在设计层面上实现了消息数据的可靠性,不依赖消息中间件,弱化了对 mq 特性的依赖。
2、简单,易于实现。
缺点:
主要是需要和业务数据绑定到一起,耦合性比较高,使用相同的数据库,会占用业务数据库的一些资源。
下面分析下几种消息队列对事务的支持
RocketMQ 中的事务,它解决的问题是,确保执行本地事务和发消息这两个 *** 作,要么都成功,要么都失败。并且,RocketMQ 增加了一个事务反查的机制,来尽量提高事务执行的成功率和数据一致性。
主要是两个方面,正常的事务提交和事务消息补偿
正常的事务提交
1、发送消息(half消息),这个 half 消息和普通消息的区别,在事务提交 之前,对于消费者来说,这个消息是不可见的。
2、MQ SERVER写入信息,并且返回响应的结果;
3、根据MQ SERVER响应的结果,决定是否执行本地事务,如果MQ SERVER写入信息成功执行本地事务,否则不执行;
如果MQ SERVER没有收到 Commit 或者 Rollback 的消息,这种情况就需要进行补偿流程了
补偿流程
1、MQ SERVER如果没有收到来自消息发送方的 Commit 或者 Rollback 消息,就会向消息发送端也就是我们的服务器发起一次查询,查询当前消息的状态;
2、消息发送方收到对应的查询请求,查询事务的状态,然后把状态重新推送给MQ SERVER,MQ SERVER就能之后后续的流程了。
相比于本地消息表来处理分布式事务,MQ 事务是把原本应该在本地消息表中处理的逻辑放到了 MQ 中来完成。
Kafka 中的事务解决问题,确保在一个事务中发送的多条信息,要么都成功,要么都失败。也就是保证对多个分区写入 *** 作的原子性。
通过配合 Kafka 的幂等机制来实现 Kafka 的 Exactly Once,满足了读取-处理-写入这种模式的应用程序。当然 Kafka 中的事务主要也是来处理这种模式的。
什么是读取-处理-写入模式呢?
栗如:在流计算中,用 Kafka 作为数据源,并且将计算结果保存到 Kafka 这种场景下,数据从 Kafka 的某个主题中消费,在计算集群中计算,再把计算结果保存在 Kafka 的其他主题中。这个过程中,要保证每条消息只被处理一次,这样才能保证最终结果的成功。Kafka 事务的原子性就保证了,读取和写入的原子性,两者要不一起成功,要不就一起失败回滚。
这里来分析下 Kafka 的事务是如何实现的
它的实现原理和 RocketMQ 的事务是差不多的,都是基于两阶段提交来实现的,在实现上可能更麻烦
先来介绍下事务协调者,为了解决分布式事务问题,Kafka 引入了事务协调者这个角色,负责在服务端协调整个事务。这个协调者并不是一个独立的进程,而是 Broker 进程的一部分,协调者和分区一样通过选举来保证自身的可用性。
Kafka 集群中也有一个特殊的用于记录事务日志的主题,里面记录的都是事务的日志。同时会有多个协调者的存在,每个协调者负责管理和使用事务日志中的几个分区。这样能够并行的执行事务,提高性能。
下面看下具体的流程
事务的提交
1、协调者设置事务的状态为PrepareCommit,写入到事务日志中;
2、协调者在每个分区中写入事务结束的标识,然后客户端就能把之前过滤的未提交的事务消息放行给消费端进行消费了;
事务的回滚
1、协调者设置事务的状态为PrepareAbort,写入到事务日志中;
2、协调者在每个分区中写入事务回滚的标识,然后之前未提交的事务消息就能被丢弃了;
这里引用一下消息队列高手课中的
RabbitMQ 中事务解决的问题是确保生产者的消息到达MQ SERVER,这和其他 MQ 事务还是有点差别的,这里也不展开讨论了。
先来分析下一条消息在 MQ 中流转所经历的阶段。
生产阶段 :生产者产生消息,通过网络发送到 Broker 端。
存储阶段 :Broker 拿到消息,需要进行落盘,如果是集群版的 MQ 还需要同步数据到其他节点。
消费阶段 :消费者在 Broker 端拉数据,通过网络传输到达消费者端。
发生网络丢包、网络故障等这些会导致消息的丢失
在生产者发送消息之前,通过channeltxSelect开启一个事务,接着发送消息, 如果消息投递 server 失败,进行事务回滚channeltxRollback,然后重新发送, 如果 server 收到消息,就提交事务channeltxCommit
不过使用事务性能不好,这是同步 *** 作,一条消息发送之后会使发送端阻塞,以等待RabbitMQ Server的回应,之后才能继续发送下一条消息,生产者生产消息的吞吐量和性能都会大大降低。
使用确认机制,生产者将信道设置成 confirm 确认模式,一旦信道进入 confirm 模式,所有在该信道上面发布的消息都会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后,RabbitMQ 就会发送一个确认(BasicAck)给生产者(包含消息的唯一 deliveryTag 和 multiple 参数),这就使得生产者知晓消息已经正确到达了目的地了。
multiple 为 true 表示的是批量的消息确认,为 true 的时候,表示小于等于返回的 deliveryTag 的消息 id 都已经确认了,为 false 表示的是消息 id 为返回的 deliveryTag 的消息,已经确认了。
确认机制有三种类型
1、同步确认
2、批量确认
3、异步确认
同步模式的效率很低,因为每一条消息度都需要等待确认好之后,才能处理下一条;
批量确认模式相比同步模式效率是很高,不过有个致命的缺陷,一旦回复确认失败,当前确认批次的消息会全部重新发送,导致消息重复发送;
异步模式就是个很好的选择了,不会有同步模式的阻塞问题,同时效率也很高,是个不错的选择。
Kafaka 中引入了一个 broker。 broker 会对生产者和消费者进行消息的确认,生产者发送消息到 broker,如果没有收到 broker 的确认就可以选择继续发送。
只要 Producer 收到了 Broker 的确认响应,就可以保证消息在生产阶段不会丢失。有些消息队列在长时间没收到发送确认响应后,会自动重试,如果重试再失败,就会以返回值或者异常的方式告知用户。
只要正确处理 Broker 的确认响应,就可以避免消息的丢失。
RocketMQ 提供了3种发送消息方式,分别是:
同步发送:Producer 向 broker 发送消息,阻塞当前线程等待 broker 响应 发送结果。
异步发送:Producer 首先构建一个向 broker 发送消息的任务,把该任务提交给线程池,等执行完该任务时,回调用户自定义的回调函数,执行处理结果。
Oneway发送:Oneway 方式只负责发送请求,不等待应答,Producer 只负责把请求发出去,而不处理响应结果。
在存储阶段正常情况下,只要 Broker 在正常运行,就不会出现丢失消息的问题,但是如果 Broker 出现了故障,比如进程死掉了或者服务器宕机了,还是可能会丢失消息的。
防止在存储阶段消息额丢失,可以做持久化,防止异常情况(重启,关闭,宕机)。。。
RabbitMQ 持久化中有三部分:
消息的持久化,在投递时指定 delivery_mode=2(1是非持久化),消息的持久化,需要配合队列的持久,只设置消息的持久化,重启之后队列消失,继而消息也会丢失。所以如果只设置消息持久化而不设置队列的持久化意义不大。
对于持久化,如果所有的消息都设置持久化,会影响写入的性能,所以可以选择对可靠性要求比较高的消息进行持久化处理。
不过消息持久化并不能百分之百避免消息的丢失
比如数据在落盘的过程中宕机了,消息还没及时同步到内存中,这也是会丢数据的,这种问题可以通过引入镜像队列来解决。
镜像队列的作用:引入镜像队列,可已将队列镜像到集群中的其他 Broker 节点之上,如果集群中的一个节点失效了,队列能够自动切换到镜像中的另一个节点上来保证服务的可用性。(更细节的这里不展开讨论了)
*** 作系统本身有一层缓存,叫做 Page Cache,当往磁盘文件写入的时候,系统会先将数据流写入缓存中。
Kafka 收到消息后也会先存储在也缓存中(Page Cache)中,之后由 *** 作系统根据自己的策略进行刷盘或者通过 fsync 命令强制刷盘。如果系统挂掉,在 PageCache 中的数据就会丢失。也就是对应的 Broker 中的数据就会丢失了。
处理思路
1、控制竞选分区 leader 的 Broker。如果一个 Broker 落后原先的 Leader 太多,那么它一旦成为新的 Leader,必然会造成消息的丢失。
2、控制消息能够被写入到多个副本中才能提交,这样避免上面的问题1。
1、将刷盘方式改成同步刷盘;
2、对于多个节点的 Broker,需要将 Broker 集群配置成:至少将消息发送到 2 个以上的节点,再给客户端回复发送确认响应。这样当某个 Broker 宕机时,其他的 Broker 可以替代宕机的 Broker,也不会发生消息丢失。
消费阶段就很简单了,如果在网络传输中丢失,这个消息之后还会持续的推送给消费者,在消费阶段我们只需要控制在业务逻辑处理完成之后再去进行消费确认就行了。
总结:对于消息的丢失,也可以借助于本地消息表的思路,消息产生的时候进行消息的落盘,长时间未处理的消息,使用定时重推到队列中。
消息在 MQ 中的传递,大致可以归类为下面三种:
1、At most once: 至多一次。消息在传递时,最多会被送达一次。是不安全的,可能会丢数据。
2、At least once: 至少一次。消息在传递时,至少会被送达一次。也就是说,不允许丢消息,但是允许有少量重复消息出现。
3、Exactly once:恰好一次。消息在传递时,只会被送达一次,不允许丢失也不允许重复,这个是最高的等级。
大部分消息队列满足的都是At least once,也就是可以允许重复的消息出现。
我们消费者需要满足幂等性,通常有下面几种处理方案
1、利用数据库的唯一性
根据业务情况,选定业务中能够判定唯一的值作为数据库的唯一键,新建一个流水表,然后执行业务 *** 作和流水表数据的插入放在同一事务中,如果流水表数据已经存在,那么就执行失败,借此保证幂等性。也可先查询流水表的数据,没有数据然后执行业务,插入流水表数据。不过需要注意,数据库读写延迟的情况。
2、数据库的更新增加前置条件
3、给消息带上唯一ID
每条消息加上唯一ID,利用方法1中通过增加流水表,借助数据库的唯一性来处理重复消息的消费。
关于JavaWeb增删改查的简单总结 原创
2020-04-25 13:14:49
走到天涯海角
码龄4年
关注
增删改查中最简单的功能是删除,通过Id来删除单表或者多表都是可以的。
增删改查中最重要的功能是查询,因为不仅仅是单表查询、连表查询需要用到查询,新增前和修改前也要使用到查询。
查询遇到的业务比如:
1登录:通过查询用户名和密码来找出用户,密码可以重复,但是用户名必须唯一,否则没办法找出单个用户。
(重要) 只要查询的字段是唯一的,都可以通过这个字段来查询出对应的单个对象或者集合。
什么字段是唯一的呢?
如:用户名必须唯一,文件名必须唯一,主键ID必须唯一等等,一时半会想不起来。
新增前,通过查询获得如:下拉框中的数据等
在新增时,通过获取下拉框的值或者输入框的值,就可以保存新增。
新增也会遇到循环插入的情况,如新增角色和修改角色,要循环插入数据到角色菜单关系表中。
循环插入数据的做法,我是用过两种方法,一种方法是使用c3p0,另一种是使用mybatis的foreach标签
修改前,通过查询,获得如:用户的信息,然后放到修改输入框,提高用户的使用体验。
修改时,通过隐藏区的Id,和输入框或者下拉框中的值,来进行保存修改。
文章知识点与官方知识档案匹配
Java技能树首页概览
92024 人正在系统学习中
打开CSDN APP,看更多技术内容
JavaWeb实现简单对数据库的增删改查_向晚而生的博客_web实现数
数据库:MySQL 连接池:Druid连接池 Github仓库地址:点我 jar包下载:点我!提取码:y4ef 参考:Javaweb实现增删改查 *** 作 *** 作 用JavaWeb部分知识实现对数据库的增删改查 只展示Student和Teacher的相关代码 一、效果图 二、数据库实现 1
继续访问
Web对数据库的增删改查(servlet+jsp+javaBean增删改查)
1开始之前的准备(servlet+jsp+javaBean增删改查) jsp:页面的请求和展示 在前台主要学了jsp进行页面的请求和展示 java后台 mysql数据库 学习了java如何进行数据库增删改查 JDBC重构Dao Dao进行sql语句 将数据库的获取结果响应到页面上
继续访问
最新发布 javaweb极简登录注册增删改查
javaweb极简登录注册增删改查
继续访问
简单的JavaWeb项目,基本的增删改查和分页查询等功能。
简单的JavaWeb项目,刘意老师整理,拥有登录,添加,删除,修改,分页查询,删除选中,复杂分页查询功能。
JavaWeb阶段案例--简易版管理图书系统(增删改查)
超详细JavaWeb阶段项目 --图书管理系统 -- 连接数据库在网页上实现图书的增删改查
继续访问
笔记--MySQL相关 *** 作
一 登录数据库 1 用户无密码: mysql -uroot -p mysql-> 2 用户有密码: MySQL -root -p[passwd] mysql-> 二 创建数据库: 查询: mysql> show databases; +--------------------+ | Database
继续访问
Javaweb--通过网页实现对数据库的增删查改
文章目录Javaweb--通过网页实现对数据库的增删查改1、功能需求2、技术选型2、最终效果图3、数据库准备4、前端开发5、后端开发 Javaweb–通过网页实现对数据库的增删查改 通常在写一些后台管理系统的时候,一定会有关于数据表格的增删查改的功能实现。最近也是闲来无事,做了这个小案例,希望能帮到有写这方面需求的朋友们。 1、功能需求 这次以单个的员工数据表为例,实现以下功能需求: 1、能够正常从数据库中读取相应数据。 2、设置分页,能够通过点击页码,进行数据更新,同时支持输入页码更新数据
继续访问
让我们在网页中实现数据库的增删改查~
目录主要思路首先让我们链接自己的数据库 indexjs对数据库设定一些用户规则 userjs做一个添加数据的静态网页 addhtml做一个主页面 listhtml最最最主要的js代码自我激励 主要思路 搭建网站服务器,实现客户端与服务器端的通信 连接数据库, 创建用户集合, 向集合中插入文档 当用户访问 /list时,将所有用户信息查询出来 1实现路由功能 1呈现用户列表页面 1 再点击修改按钮的时 将用户ID传递到当前页面 2 从数据库中查询当前用户信息 将用户信息展示到页面中 2从数据
继续访问
JavaWeb 增删改查快速开发总结
JavaWeb增删改查基本都是那一套,其中最繁琐 变动的便是围绕SQL语句、Servlet来展开,下面是我对这些左到一个小总结,希望能对您有所帮助首先项目搭建好之后就是最关键的SQL语句 Servlet代码 Servlet方法 然后是前端methods()方法 删除和批量删除(这里用element做了个删除提示)
继续访问
Java web阶段学习总结(华清远见)
经过web前端的学习之后,我们开启了Java web后端的学习。学习一样新的东西首先要了解它的原理,以及所要具备的一些条件。对于Servlet 的开发步骤一般有:新建一个Java web项目工程 --> 创建servlet类继承>
大数据技术的体系庞大且复杂,基础的技术包含数据的采集、数据预处理、分布式存储、数据库、数据仓库、机器学习、并行计算、可视化等。
1、数据采集与预处理:FlumeNG实时日志收集系统,支持在日志系统中定制各类数据发送方,用于收集数据;Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,提供数据同步服务。
2、数据存储:Hadoop作为一个开源的框架,专为离线和大规模数据分析而设计,HDFS作为其核心的存储引擎,已被广泛用于数据存储。HBase,是一个分布式的、面向列的开源数据库,可以认为是hdfs的封装,本质是数据存储、NoSQL数据库。
3、数据清洗:MapReduce作为Hadoop的查询引擎,用于大规模数据集的并行计算。
4、数据查询分析:Hive的核心工作就是把SQL语句翻译成MR程序,可以将结构化的数据映射为一张数据库表,并提供HQL(HiveSQL)查询功能。Spark启用了内存分布数据集,除了能够提供交互式查询外,它还可以优化迭代工作负载。
5、数据可视化:对接一些BI平台,将分析得到的数据进行可视化,用于指导决策服务。
Data warehouse(可简写为DW或者DWH)数据仓库,是在数据库已经大量存在的情况下,为了进一步挖掘数据资源、为了决策需要而产生的,它是一整套包括了etl、调度、建模在内的完整的理论体系。数据仓库的方案建设的目的,是为前端查询和分析作为基础,主要应用于OLAP(on-line Analytical Processing),支持复杂的分析 *** 作,侧重决策支持,听且提供直观易懂的查询结果。比较流行的有:AWS Redshift,Greenplum,Hive等。
12主要特点
面向主题:
*** 作型数据库组织面向事务处理任务,而数据仓库中的数据是按照一定的主题域进行组织。
主题是指用户使用数据仓库进行决策时所关心的重点方面,一个主题通过与多个 *** 作型信息系统相关。
集成
需要对源数据进行加工与融合,统一与综合
在加工的过程中必须消除源数据的不一致性,以保证数据仓库内的信息时关于整个企业的一致的全局信息。(关联关系)
不可修改
DW中的数据并不是最新的,而是来源于其他数据源
数据仓库主要是为决策分析提供数据,涉及的 *** 作主要是数据的查询
与时间相关
处于决策的需要数据仓库中的数据都需要标明时间属性
13与数据库的对比
DW:专门为数据分析设计的,涉及读取大量数据以了解数据之间的关系和趋势
数据库:用于捕获和存储数据
特性 数据仓库 事务数据库
适合的工作负载 分析、报告、大数据 事务处理
数据源 从多个来源收集和标准化的数据 从单个来源(例如事务系统)捕获的数据
数据捕获 批量写入 *** 作通过按照预定的批处理计划执行 针对连续写入 *** 作进行了优化,因为新数据能够最大程度地提高事务吞吐量
数据标准化 非标准化schema,例如星型Schema或雪花型schema 高度标准化的静态schema
数据存储 使用列式存储进行了优化,可实现轻松访问和高速查询性能 针对在单行型物理块中执行高吞吐量写入 *** 作进行了优化
数据访问 为最小化I/O并最大化数据吞吐量进行了优化 大量小型读取 *** 作
2数据分层
数据分层,每个企业根据自己的业务需求可以分成不同的层次,但是最基础的分层思想,理论上数据分为三个层:数据运营层、数据仓库层、数据服务层。基于这个基础分层之上,再提交信息的层次,来满足不同的业务需求。
21数据运营层(ODS)
ODS:Operation Data Store 数据准备区,也称为贴源层。数据仓库源头系统的数据表通常会原封不动的存储一份,这称为ODS层,是后续数据仓库加工数据的来源。
ODS层数据的来源方式:
业务库
经常会使用sqoop来抽取,例如每天定时抽取一次。
实时方面,可以考虑用canal监听mysql的binlog,实时接入即可。
埋点日志
日志一般以文件的形式保存,可以选择用flume定时同步
可以用spark streaming或者Flink来实时接入
kafka也OK
消息队列:即来自ActiveMQ、Kafka的数据等。
22数据仓库层(DW)
DW数据分层,由下到上为DWD,DWB,DWS。
DWD:data warehouse details 细节数据层,是业务层与数据仓库的隔离层。主要对ODS数据层做一些数据清洗和规范化的 *** 作。
数据清洗:去除空值、脏数据、超过极限范围的
DWB:data warehouse base 数据基础层,存储的是客观数据,一般用作中间层,可以认为是大量指标的数据层。
DWS:data warehouse service 数据服务层,基于DWB上的基础数据,整合汇总成分析某一个主题域的服务数据层,一般是宽表。用于提供后续的业务查询,OLAP分析,数据分发等。
用户行为,轻度聚合
主要对ODS/DWD层数据做一些轻度的汇总。
23数据服务层/应用层(ADS)
ADS:applicationData Service应用数据服务,该层主要是提供数据产品和数据分析使用的数据,一般会存储在ES、mysql等系统中供线上系统使用。
我们通过说的报表数据,或者说那种大宽表,一般就放在这里
以上就是关于RabbitMQ,RocketMQ,Kafka 事务性,消息丢失和重复发送处理策略全部的内容,包括:RabbitMQ,RocketMQ,Kafka 事务性,消息丢失和重复发送处理策略、增删改查哪个最重要、大数据方面核心技术有哪些等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)