文章 49
浏览 15135
我用spark导出500万数据

我用spark导出500万数据

背景 最近公司需要实现一个报表功能,需要导出近一段时间内的数据,时间段由用户在页面填写,作为 SQL 参数查询过滤,因为涉及到查询的信息详细,需要关联的表过多和字段过多,以及数据量过大,可能会有性能方面的问题 方案一: 多线程分页多 sheet+ 队列(发布订阅) 网上有很多的方案说了,用多线程分批处理,自己也写了个 demo 实现,多线程分批分页查询 + 发布订阅队列 + 分 sheet 写入,虽然功能实现了,最终测试 500 万数据,结果需要将近 8 分钟了,感觉不太满意这种方式,后面想到我们公司的服务器有大数据方面环境,想着能不能用大数据解决,最终决定用 spark 方案二:spark+cxv 经过查找资料和自己学习,基本掌握了一点 spark 的知识和整合 Java +springboot,发现 spark 天生支持这种大数据量的整合处理 基本思路就是,通过 spark 大数据引擎分布式连接 JDBC 读取数据库的数据,然后写入到 CSV 文件到 hdfs 或者到本地文件系统,最终从 hdfs 或者本地写入搭配 response 响应流给前端下载 @GetMapping("/d....

高效能list转tree树形结构,扁平化线性复杂度

高效能list转tree树形结构,扁平化线性复杂度

背景 最近在做业务的时候,发现有很多地方需要将数据库查询出来的 list 转为 tree 结构,基于面向对象的思想,想着做成一个通用的工具类,使用泛型,然后首先想到的是使用递归,O(n * n) 后面觉得递归的传统方式,时间复杂度过高,基于此进行优化,想到了一个线性规划的方式,进行数据扁平化转为线性复杂度 O(N) 接口限定 定义一个 ItreeNode 接口,该接口主要用来子类实现,自己定义父节点的规则,只要使用方自己实现 parent 方法,自己定义父节点的规则,这样就无需 id 和 parentId 必须提前限制类型了, string 或者对象都可以作为获取父节点的基准 import java.util.List; /** * 通过实现该接口的子类 自己定义parent的规则 * @param <T> */ public interface ITreeNode<T> { T parent(); void setChildren(List<T> children); List<T> getChildren(); } 第一版 使用....

当 Redis 碰上 @Transactional,有大坑

当 Redis 碰上 @Transactional,有大坑

标题: 探索 Redis 与 @Transactional 注解的冲突之谜 正文: 前言 在我们的项目中,我们遇到了一个让人费解的生产环境问题:每天早上,当运营人员后台尝试创建新事件时,系统总是无法成功创建。经过重新启动相关微服务后,系统又能恢复正常运行,直到次日早上问题再次出现,又得重启服务。 初步调查 我们发现,问题出现在使用 Redis 生成唯一分布式 ID 的过程中。每天早上,Redis 的递增操作异常地返回了 null 值,导致后续流程中断。重新启动服务似乎是暂时的解决方法,但根本问题仍然悬而未决。 return redisTemplate.opsForValue().increment("count", 1); 深入探索 根据重启后就恢复正常,我们推测晚上执行了大量的 job,大量 Redis 连接未释放,当早上再来执行 Redis 操作时,执行失败。重启后,连接自动释放了。但是其他有使用到 Redis 的业务功能又是正常的,所以推测一的方向有问题,排除 。 通过查询 ```redisTemplate 递增的方法 increment` 源码注释, 发现事务&管道会返....

spring的STOMP落地实践

spring的STOMP落地实践

背景 公司有个主系统 A,这个系统将来用途作为 SaaS 服务系统,设计尽可能保持纯粹,不要引入过多的中间件技术 其下有 B,C 甚至未来还有多个子系统,现在的需求是需要当子系统 B,C 开启了某个配置,需要对接 A 系统,A 系统能够提供 B,C 系统的能力赋能,当 BC 断开配置,B,C 又是个纯粹可以单独运行的系统,某个系统不共用同一套数据,拥有自己的环境和数据,当子系统开启了配置,相关接口功能需要限制,由主系统提供能力,断开配置,A.B,C 三个系统能够独立运行 功能拆分 主系统: 对主系统相关的增量和全量接口数据进行同步传输:这里有两个关键点 有许多增量接口需要进行同步传输&&传输数据的逻辑不能影响原先的业务逻辑(通过 AOP 注解) 需要找到一个类型消息队列 mq 那种形势进行数据同步,A 系统数据发生改动子系统能够感知 但是这个系统不能引入过多的中间件,最终经过调研,选择使用了 Spring 的 STOMP 和 Spring event 事件实现一种伪消息队列 子系统: 子系统相关接口限制:通过 AOP 接口限制 子系统需要接收主系统的全量和增量数据 (S....

"超越静态的境界:Spring设计哲学中的依赖注入与状态管理"

Spring 的依赖注入之谜:Spring 为何不拥抱静态字段 发表日期:2024 年 01 月 05 日 阅读时长:约 4 分钟 专栏标签:Spring 在 Spring 的世界里,每一个 bean 的成长都离不开一系列精心的培育过程。这个过程通常涵盖以下几个阶段: 反射孕育实例——通过反射机制创建 bean 实例。 属性的滋养——为 bean 填充属性,赋予其生机。 激活生命之火——初始化 bean,让其具备完整功能(可能伴随增强处理)。 谋划离别之时——注册 bean 的销毁方法,为其终结做好准备。 在这个生命周期中,“属性的滋养”阶段尤为关键,它正是在 populateBean 方法中得以实施。在这一过程中,除了通过 applyPropertyValues 方法直接填充属性外,大量的注入逻辑实际上是在 InstantiationAwareBeanPostProcessor 接口的 postProcessProperties 方法内实现的。这里对我们耳熟能详的 @Autowired 和 @Resource 注解进行了诠释。 protected void populateBean(....

多线程事务伪命题

多线程事务伪命题

背景 最近发现一个有趣的命题,多线程如何保证事务的一致性,简单的说,如何保证多线程情况下,一个线程操作入库逻辑执行失败,其他线程能感知,一起回滚,一起成功 个人看法 再此之前,我是觉得不太现实,为什么呢? 我们先从理论上去推理一下。 我们都知道事务的特性是什么? 这个不难吧?八股文必背内容之一,ACID 必须张口就来: 原子性(Atomicity) 一致性(Consistency) 隔离性(Isolation) 持久性(Durability) 那么问题又来了,你觉得如果有多线程事务,那么我们破坏了哪个特性? 多线程事务你也别想的多深奥,你就想,两个不同的用户各自发起了一个下单请求,这个请求对应的后台实现逻辑中是有事务存在的。 这不就是多线程事务吗? 这种场景下你没有想过怎么分别去控制两个用户的事务操作吧? 因为这两个操作之间就是完全隔离的,各自拿着各自的链接玩儿。 所以多个事务之间的最基本的原则是什么? 隔离性 。两个事务操作之间不应该相互干扰。 而多线程事务想要实现的是 A 线程异常了。A,B 线程的事务一起回滚。 事务的特性里面就卡的死死的。所以,多线程事务从理论上就是行不通的。 ....

Seata原理

Seata原理

Seata 术语 TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。 TM (Transaction Manager) - 事务管理器 定义全局事务的范围:开始全局事务、提交或回滚全局事务。 RM (Resource Manager) - 资源管理器 管理分支事务处理的资源,与 TC 交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。 原理图

分布式事务seata

分布式事务seata

Seata 是什么 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。AT 模式是阿里首推的模式,阿里云上有商用版本的 GTS(Global Transaction Service 全局事务服务) 官网:https://seata.io/zh-cn/index.html 源码: https://github.com/seata/seata 官方 Demo: https://github.com/seata/seata-samples seata 版本:v1.4.0 Seata 的三大角色 在 Seata 的架构中,一共有三个角色 TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。 TM (Transaction Manager) - 事务管理器 定义全局事务的范围:开始全局事务、提交或回滚全局事务。 RM (Resource Manager) - 资源管理器 管理分支事务....

人民有信仰 民族有希望 国家有力量