如何实现高效的导入和导出,是我们在日常开发中,经常会遇到的问题,进行Excel的导入和导出,有时候数据量大,导入导出很慢,怎么办?
AGEIPort来替你解决这个问题,AGEIPort是阿里巴巴开源的一款高性能导入导出方案。
AGEIPort 是数字供应链孵化并在阿里巴巴集团内广泛使用的一套性能卓越、稳定可靠、功能丰富、易于扩展、生态完整的数据导入导出方案,致力于帮助开发者在toB复杂业务场景下能够快速交付高性能、体验优、易维护的数据导入导出功能,如用户页面上的Excel/CSV数据文件上传和下载。目前在阿里巴巴集团内部已有盒马、菜鸟、本地生活、阿里健康、钉钉、淘系等部门有较多使用,并成为多个技术组件的基础底座,经历多次618和双11大促考验,稳定导入导出数据300~400亿条/月。
一、AGEIPort 使用
首先,可以基于example进行测试使用
基于这两个类,我们可以进行测试debug跟踪其实现的过程。
二、导入
其中executeTask是最重要的方法:
TaskExecuteResult response = ageiPort.getTaskService().executeTask(request);
然后会根据创建的主任务,通过eventbus通知子任务执行任务。
三、导出
获取任务的阶段信息可以看到也有对应的provider:
导入导出的provider,通过getStages()可以获取具体的执行任务的过程:
四、导入导出执行任务的具体实现操作worker
执行任务拿到相关信息的过程:
获取任务中的参数信息 获取任务注册信息 创建创建主任务请求参数 获取任务客户端TaskServerClient 通过taskServiceClient拿到主任务的mainTaskId和主任务 执行接收accept=> ageiPort.getTaskAcceptor().accept(mainTask) 返回任务执行响应结果
其中ageiPort.getTaskAcceptor().accept(mainTask)这个过程中很重要。
根据主任务task拿到code,从而拿到对应的任务,进行主任务创建,同时对主任务时间进行获取 创建一个task主任务事件 进入发布消息阶段,执行post发布消息 接着相关监听会执行任务,可以看到其基于eventbus实现的订阅@Subscribe
执行任务的过程中会对对应的阶段进行记录,同时调用next获取下一个阶段信息stage,然后执行对应的任务。
从记录的stage来看,可以看到其先由主任务执行的过程中,会通知subTask执行任务,这个过程会将task进行分片,然后均摊到对应的处理中,然后执行处理,处理的过程中完成后,执行任务合并,然后进行返回。
List<ImportSlice> slices = sliceStrategy.slice(context); context.load(slices); // 执行分片操作 for (ImportSlice slice : slices) { String subTaskId = TaskIdUtil.genSubTaskId(mainTaskId, slice.getNo()); System.out.println("----通知子任务进行subTask操作ImportMainTaskWorker-----"); ageiPort.getEventBusManager().getEventBus(executeType).post(TaskStageEvent.subTaskEvent(subTaskId, subTaskCreated)); }
调用subTask执行。
五、执行任务的操作流程流转
导入和导出的相关执行的相关过程类似,这里以导出的流程进行归纳:
六、导出流程
导出主任务流程
导出子任务流程:
七、分片策略
分片的策略可以看到目前一种:均摊策略 AvgImportSliceStrategy,同时分片的数量是以1000为一片进行处理的。
int sliceCount = (items.size() - 1) / pageSize + 1;
eventBus实现类似于Spring的事件。
任务进度完成添加日志后,更新主任务监控事件发布信息。
以上是基于ageiport使用整理