[每周一更]-(第9期):超大文件入库处理-读写入库(2)

发布于:2023-01-04 ⋅ 阅读:(368) ⋅ 点赞:(0)

在这里插入图片描述

需求分析:
我们需要将超大文本进行入库操作,需要进行拆分拆分操作,该系列分为三篇讲解:

  • 一、文件拆分 - 将大文件拆分小文件,代码操作也能实现,但是没有Linux自带的命令效率高;
  • 二、读写入库 - 将拆分后的小文件,通过读和写协程进行,边读边写入库,批量插入数据库(无序);
  • 三、水平拆分 - 超大入库单表需要水平拆分,否则影响性能(2kw+),通过SQL命令操作,效率高;

二、读写入库

文件整体读取

文件整体读取就是将文件一次性读取到,理解上是将文件的内容第一次就读取完了

使用场景 :

  • 针对小文件比较适用(大文件读取空间和时间的消耗也很大)
  • 对于只读类型的文件也比较适用(文件也不能太大)

文件分片读取

对文件一部分一部分逐步的读取,直到文件完全读取完

PS : 每次读取文件的大小是根据设置的 分片 大小 ,所以对于读取文本类型的文件时(例如 : 日志文件)
不一定是按照你的期望逐行输出,因为不会处理文本尾部的换行符,而是按照分片大小读取内容

使用场景 :

  • 读取超大的文件
  • 读二进制类型的文件(比如:音视频文件或者资源类型文件等)

文件逐行读取

对文件一行一行的读取,直到读到文件末尾

使用场景 :

  • 读取超大的文件很合适(例如 : 超大文本文件等)
  • 读取的文件最好是有换行的(如果使用单行文件组成的大文件,需要注意)
  • 对需要分析的内容大文件
    • 统计某些数据出现的次数
    • 查询某些数据是否存在
    • 查找指定行的数据

超大txt文件的处理

针对超大txt文件,特点是有换行符,但是逐行读取入库操作还是很慢,还需要改进方案;
要想提高数据写入的速度,我们一方面要做并发的数据库写入,一方面又要尽量减少操作的次数,一次性插入尽可能多的记录;

  • 主要的性能瓶颈其实是主协程对文本的读取速度,可以事先对文件进行分割操作,然后并发地做数据读入;
  • 主协程逐条读取文本大数据,将数据封装后丢入全局数据管道;
  • 开辟10条数据库写入协程,每个写入协程使用一个独立的数据库连接;
  • 数据写入协程各自独立地从全局数据管道中获取数据,每满1000条就做一次数据库写入操作;

总结

  • 面试中常见的类似超大文件读取的问题,通常我们采用分片读取或者逐行读取的方案即可
  • 大文件的上传也可以采用类似的解决方案 , 每次读取文件的部分内容上传(写入)网络接口中,直至文件读取完毕
    普通的小文件并且对内容没有太多操作的,可以采用整体读取,速度相对较快
  • 对文件内容有操作的采用分片读取和逐行读取更合适
  • 二进制类型文件采用分片读取或者整体读取的方案比较合适
  • 文件读取不仅是本地文件,要读去网络上的文件(各种文档,音视频,图片,和其他各种类型文件)时要访问到文件获取 io.ReadCloser 或者 io.Reader 后可以采用三种方式将文件内容读取到

func ReadAll(r io.Reader) ([]byte, error) 文件完整读取

func Copy(dst Writer, src Reader) (written int64, err error) 文件读取并写入

type Reader interface {
Read(p []byte) (n int, err error)
}
    

通过Reader 接口的 Read 方法读取

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到