二, 大数据基础架构Hadoop-HDFS入门和基本操作(基本组成, Shell操作, API操作, 读写流程) hf
一, HDFS概述
1.1 HDFS的产生背景和定义
- 随着数据量越来越大,我们需要把文件分布存储到多台计算机上,分布式文件管理系统作为一种管理多台机器上文件的系统应运而生, HDFS是其中的一种.
- HDFS定义:
- Hadoop Distributed File System,
- 通过目录树来定位文件
- 分布式的. 很多服务器联合起来实现功能,集群中的服务器有各自的角色.
- 使用场景: 适合一次写入,多次读取的场景. 一个文件经过创建,写入和关闭后就不需要改变
1.2, HDFS的优缺点:
- 优点:
高容错性(多个副本, 自动恢复)
. 数据自动保存多个副本,通过增加副本的形式,提高容错性. 某一个副本丢失,它可以自动恢复.适合处理大数据(超大文件)
. GB,TB甚至于PB级别的数据或者是百万规模以上的文件数量.可构建在廉价机器上
. 通过多副本机制,提高可靠性.
- 缺点:
不适合低延时数据访问
. 比如毫秒级的存储数据,是做不到的, HDFS是为高数据吞吐量应用优化的, 这可能会以提高时间延迟为代价, 目前来说, 对于低延迟的访问需求, HBase是更好的选择.无法高效的对大量小文件进行存储
.
- 存储大量小文件的话,它会占用NameNode大量的内存来存储文件系统的元数据. 由于NameNode的内存总是有限的,所以不可取.
- 小文件存储的寻址时间会超过读取时间,他违反了HDFS的设计目标.
不支持并发(多个用户)写入,也不支持在文件的任意位置进行修改
- 一个文件只允许一个用户写,不允许多个用户同时写
- 仅支持数据追加(append)到文件末尾, 不支持文件的随机修改.
1.3, HDFS组成架构
- NameNode(nn),即master,他是一个管理者.
- NameNode 执行的操作 主要分为三类, 如下表所示:
类别 | 说明 |
---|---|
1. 维护管理HDFS的命名空间 |
维护整个文件系统的目录树 , 文件/目录的元数据信息 和文件的数据块索引 (每个文件对应的数据块列表). 这些信息在NameNode中保存在两个文件中, 分别是 FSImame(文件系统镜像)和 Edits(编辑日志)
|
2. 确定数据块-DataNode的映射关系 |
client读取数据先访问NameNode, 由NN获取数据所在的DN, 然后client读取目标DN得到数据. 注意: 数据块-DataNode的映射关系是由NameNode根据DataNode上报的文件块信息动态重建 的而不是持久化保存,从而减轻了NameNode的负担
|
3. 管理DataNode结点的状态报告 | 包括DataNode的健康状态报道和其所在结点上数据块的状态报告, 以便能够及时处理失效的DataNode |
注意:
- FSImage-文件系统镜像, 在NameNode启动时对整个文件系统的快照;
- edits-编辑日志, 在NameNode启动之后, 记录对文件系统的改动序列;
- DataNode,即Slave,NameNode下达命令.DataNode执行实际的操作, 如下表所示:
类别 | 说明 |
---|---|
1. 负责实际执行自身结点上数据的读写和存储
|
一般是文件系统客户端需要请求对NN指定的DataNode结点进行读写操作, DataNode作为数据结点的服务进程与文件系统打交道. |
2. 定期向NameNode报告状态
|
每个DataNode会周期性地向NameNode发送心跳信号和文件块报告(心跳是每3秒一次,心跳返回结果带有namenode给该datanode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个datanode的心跳,则认为该节点不可用) |
3. 执行数据的流水线复制
|
当文件系统客户端从NameNode服务器进程获取到要进行复制的数据块列表后, 由DataNode完成文件块和块副本的流水线复制 |
Client,客户端
- 文件切分.文件上传HDFS的时候,Client将文件切分为一个个的Block,然后进行上传;
- 与NameNode交互,获取文件的位置信息;
- 与DataNode交互,读取或写入数据;
- Client提供一些命令来管理HDFS,比如NameNode格式化;
- Client可以通过一些命令来访问HDFS,比如对HDFS增删改查操作.
Secondary NameNode: 并非NameNode的热备份,当NameNode挂掉后,并不会马上替换NameNode并提供服务
- 辅助NameNode,分担其工作量,比如定期合并Fsimage和Edits,并推送给Namenode(保持一个较新的文件系统快照);
- 在紧急情况下,可辅助恢复NameNode.
对2NN的详细说明
1.4 HDFS文件块大小(面试重点)
HDFS中的文件在物理上是分块存储的(Block),块的大小可以通过配置参数(hdfs-default.xml文件中的dfs.blocksize)来规定, 默认大小在Hadoop2.x/3.x版本中是128M, 1.x版本中是64M.
Q: 为什么块的大小不能设置太小,也不能设置太大?
- HDFS块的大小设置主要取决于磁盘传输速率;
- HDFS的块设置
太小,会增加寻址时间,程序一直在找块的开始位置
; - 如果块设置的
太大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间.
导致程序在处理这块数据时, 会非常慢
.
- 总结: HDFS的块大小主要取决于磁盘传输速率。
二, HDFS的Shell操作
2.1 HDFS的常用命令
- 格式:
hadoop fs 具体命令
ORhdfs dfs 具体命令
2.2, 上传文件
- 先在HDFS创建一个测试文件夹
hdfs dfs -mkdir shellTest
注意: 不要忘记带路径符号正斜杠, ‘/’
- 本地
剪切
文件到HDFS
-moveFromLocal ./文件名 /目标目录
(命令大小写严格区分噢, movefromlocal就不对)
示例:
进入HDFS web管理页面(bigdata01:9870), 点击可以查看目录和文件
- 本地
上传
文件到HDFS
-put ./文件名 /目标目录
或者是,-copyFromLocal ./文件名 /目标目录名
- 追加文件到另一个已经存在文件的末尾
-appendToFile ./文件名 /目录名/文件名
举个栗子:
在本地新建一个cal.txt, 然后把cal指令(显示本月日历)结果追加到cal.txt(其实追加命令自己可以新建文件哈), 之后在hdfs中-touch新建一个time.txt, cal.txt追加到hdfs的
/shellTest/time.txt
中, 并-cat打印输出结果.
2.3, 下载文件
- 从HDFS下载文件到本地
-get /目录/文件 ./
或者是,-copyToLocal /目录名/文件名
示例:
- 如果你下载文件同时
并改个名
,
2.4, 常用Shell命令
-ls 查指定路径文件和目录的详细信息
注意:
HDFS的 -ls 操作等用于于的是 linux 的 ll操作
-cat 打印输出文件内容
-chmod(-chgrp -chown) 修改文件所属权限
-mkdir 创建目录
-cp, -mv 复制,移动文件;从HDFS的一个路径到另一个路径
-rm 删除文件或目录(-rm -r)
-tail 显示一个文件的末尾的1kb的数据
Q: 为什么要查看末尾? 因为末尾的文件内容随着追加操作不断更新,时效性较强.比如.日志文件.
- -du 统计文件夹的大小信息 ( -du -s 汇总加和, -h 以人类易读的方式显示)
第一列是文件的大小,第二列除以第一列的值是文件的副本数量;
如shuguo.txt这个文件大小是7B, 有14/7=2个副本;
-du -h -s 是文件夹的所有文件的信息
-du -h 是文件夹的总体信息
- -setrep (replication)设置HDFS中文件的副本数量
- 实际还是只有三个副本, 因为目前只有这三台DataNode节点
这里设置的副本数只是记录在NameNode 的元数据中
,是否真的会有这么多副本,还得看DataNode的数量。因为目前只有3台设备,最多也就3个副本,只有节点数的增加到8台时,副本数才能达到8。
!!! 一台机器一个副本,多了没意义!
三, 基于JAVA的HDFS的API操作
参见此文: 二-0, 大数据基础架构Haoop- 在Windows客户机上对HDFS的API操作
四, HDFS的读写流程(面试重点)
4.1, HDFS写数据流程
4.1.1 HDFS文件写入剖析(需要进一步深入)
具体步骤:
- 客户端通过 DistributedFileSystem模块向NameNode
请求上传文件
,NameNode检查目录结构(检查目标文件是否存在,父目录是否存在,权限是否满足); - NameNode
返回请求
是否可以上传; - 客户端对待传文件进行切分,分为若干个block (每个block的大小为64M 或者 128M),然后向NameNode
请求上传第一个Block
到哪几个DataNode服务器上; NameNode考虑每一个节点是否可用, 节点距离最近, 负载均衡等因素返回3个DataNode节点
,分别为dn1,dn2,dn3;- 客户端通过
FSDataOutputStream模块请求dn1上传数据
,dn1收到请求后会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成; - dn1,dn2,dn3
逐级应答客户端
; - 客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),
以Packet为单位
(大小为64k, 由多个chunk512字节+chunkSum4字节组成),dn1收到一个Packet就会传给dn2,dn2传给dn3; dn1每传一个packet会放入一个应答队列等待应答(); - 当一个Block传输完成之后,客户端再次请求NameNode上传第二个BLock的的服务器(重复执行3-7步).
待参考的文章
待参考文章2
4.1.2 网络拓扑-节点距离计算
在HDFS写数据的过程中,NameNode会选择离上传数据最近距离的DataNode接收数据,那么这个最近距离是如何计算的呢?
节点距离: 两个节点到达最近的共同祖先的距离总和
( 什么是共同祖先, 比如一个机架中两个结点的共同祖先就是这个机架; ab两个机架中的两个节点的共同祖先就是ab两个机架构成的集群)
示例:
4.1.3 机架感知(副本存储节点选择)
选择策略(假如集群有三个副本)
- 第一个副本在Client所处的节点上,如果客户端在集群外,随机选一个;(节点越近,上传速率越快)
- 第二个副本在另一个机架的随机一个节点上;(保证数据的可靠性)
- 第三个副本在第二个副本所在机架的随机节点;(同时兼顾效率)
三个副本的机架感知概括如下:
跟Client同机架的其他一个节点
,别的机架A上的一个节点
,别的机架A上一个随机节点
.
4.2, HDFS 读数据流程
具体步骤:
- 客户端通过 DistributedFileSystem
向 Namenode请求下载文件
, NameNode通过查询元数据,找到文件块所在的DataNode地址; 挑选一台DataNode(节点最近,负载均衡 )服务器
,请求读取数据;DataNode开始传输数据给客户端
(从磁盘里面读取数据输入流,以Packet为单位来做校验);- 客户端
以Packet为 单位接收
,先在本地缓存,然后写入目标文件;
五, NameNode和Secondary NameNode
5.1, NN和2NN工作机制-引言
首先思考一个问题: NameNode中的元数据是存储在哪里的?
- 如果把元数据存放在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,所以必然会效率过低; 因此我们要
把元数据存放到内存中
.- 但是,如果元数据只存在内存中,一旦断电,元数据丢失,整个集群就完犊子了, 所以我们引出了
在磁盘中备份元数据,叫FsImage
;- 然而新问题又来了,当在内存中的元数据更新时,如果同时去更新FsImage,又会导致效率过低, 但是不更新的话又会发生一致性问题, 一旦NameNode断电,数据又丢了个鸡儿的.因此我们引入了
Edits文件(只进行追加操作,效率很高),每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中
.这样, 一旦NameNode节点断电,可以通过FsImage和Edits的合并,合并出当时的元数据
.- 但是! 如果长时间添加数据到Edits中而不及时合并,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长.因此, 需要
定期进行FsImage和Edits的合并
, 如果这个操作由NameNode节点完成,又会导致效率过低,所以,我们又引入了一个新的节点Secondary NameNode, 专门用于FsImage和Edits的合并
.
Fsimage 在磁盘中备份元数据;
Edits 记录对数据发生的修改;
Secondary NameNode定时合并上面两个文件;
参见此文: Secondary NameNode:它究竟有什么作用?
5.2, NN和2NN工作机制-详述
第一阶段: NameNode启动
- 第一次启动NameNode格式化后,
创建Fsimage和Edits文件
.如果不是第一次启动,则直接加载编辑日志和镜像文件到内存
; - 客户端对元数据进行
增删改的请求
; - NameNode
记录操作日志,更新滚动日志
(记录到edits_inprogress); - NameNode
在内存中对元数据进行增删改
;
- 第一次启动NameNode格式化后,
第二阶段: Secondary NameNode工作
- Secondary NameNode
询问NameNode是否需要CheckPoint
. 直接带回NameNode是否检查结果; - Secondary NameNode
执行CheckPoint
; NameNode 滚动正在写的Edits日志
;- 将
滚动前
的编辑日志(Edits)和镜像文件(fsimage)拷贝到
Secondary NameNode; - Secondary NameNode
加载
编辑日志和镜像文件到内存,并进行合并
; 生成新的镜像文件
fsimage.chkpoint;拷贝fsimage.chkpoint回
到NameNode;- NameNode将fsimage.chkpoint重新命名为 fsimage,覆盖原来的fsimage.
- Secondary NameNode
checkpoint的触发条件:
- 定时时间到
- Edit中的数据满了
5.3, Fsimage和Edits文件的解析
NameNode 被格式化以后,将在/hadoop安装目录/data/tmp/dfs/name/current 目录下产生如下文件:
- fsimage文件: HDFS文件系统元数据的一个永久的检查点,其中
包含HDFS文件系统的所有目录和inode的序列化信息
; - edits文件:
存放HDFS文件系统的所有更新操作的路径
,文件系统客户端执行的所有写操作首先
会被记录到Edits文件中;
每次NameNode启动的时候都会将Fsimage文件读入内存,加载Edits里面的更新操作,保证内存中的元数据是最新的,同步的,可以看成
NameNode启动的时候就将Fsimage和Edits文件进行了合并
.
- seen_txid文件: 保存的是一个数字,就是
最后一个edits_的数字
;
- VERSION文件: 记录 NameNode节点对应的命名空间的id, HDFS 集群的唯一标识符cluster_id(这些标识符与DataNode一致, 用于防止 DataNode 意外注册到属于不同集群的不正确 NameNode。)
5.3.1, 使用oiv命令查看 fsimage文件
oiv 和 oev
基本语法:
hdfs oiv -p 文件类型 -i镜像文件 -o\转换后文件输出路径
- 案例实操:
- 我们在xshell中使用
sz fsimage
把该文件下载到本地, 用BowPad打开查看, 比如 我们要查看hdfs中/user/win10/abb.txt
的目录信息:
- 我们可以在其中的一个BLOCK中查找到这些文件或目录名.
- 在fsimage靠后的位置存储着, 上面文件和目录的parent-child 归属关系
通过查看fsimage我们可以清楚的知道, NN只负责记录文件的元数据信息, 并不知道文件的具体存储位置, 而是由DN负责告知的.
5.3.2, 使用oev查看Edits文件
- 基本语法
hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径
- 案例实操
- 我们先对HDFS执行一次操作, 这里我随便上传一个文件到HDFS中.
- 提取日志文件到Windows中, 用BowPad打开.
- 下面是我在操作HDFS上传文件后, edits中的记录
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EDITS><EDITS_VERSION>-64</EDITS_VERSION><RECORD><OPCODE>OP_START_LOG_SEGMENT</OPCODE><DATA><TXID>1197</TXID></DATA></RECORD><RECORD><OPCODE>OP_ADD</OPCODE><DATA><TXID>1198</TXID><LENGTH>0</LENGTH><INODEID>16614</INODEID><PATH>/apiTest/text.txt._COPYING_</PATH><REPLICATION>3</REPLICATION><MTIME>1625197340573</MTIME><ATIME>1625197340573</ATIME><BLOCKSIZE>134217728</BLOCKSIZE><CLIENT_NAME>DFSClient_NONMAPREDUCE_947767106_1</CLIENT_NAME><CLIENT_MACHINE>192.168.182.100</CLIENT_MACHINE><OVERWRITE>true</OVERWRITE><PERMISSION_STATUS><USERNAME>win10</USERNAME><GROUPNAME>supergroup</GROUPNAME><MODE>420</MODE></PERMISSION_STATUS><ERASURE_CODING_POLICY_ID>0</ERASURE_CODING_POLICY_ID><RPC_CLIENTID>6b6c7166-b01f-42bd-a859-d5963b730497</RPC_CLIENTID><RPC_CALLID>3</RPC_CALLID></DATA></RECORD><RECORD><OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE><DATA><TXID>1199</TXID><BLOCK_ID>1073741964</BLOCK_ID></DATA></RECORD><RECORD><OPCODE>OP_SET_GENSTAMP_V2</OPCODE><DATA><TXID>1200</TXID><GENSTAMPV2>1140</GENSTAMPV2></DATA></RECORD><RECORD><OPCODE>OP_ADD_BLOCK</OPCODE><DATA><TXID>1201</TXID><PATH>/apiTest/text.txt._COPYING_</PATH><BLOCK><BLOCK_ID>1073741964</BLOCK_ID><NUM_BYTES>0</NUM_BYTES><GENSTAMP>1140</GENSTAMP></BLOCK><RPC_CLIENTID/><RPC_CALLID>-2</RPC_CALLID></DATA></RECORD><RECORD><OPCODE>OP_CLOSE</OPCODE><DATA><TXID>1202</TXID><LENGTH>0</LENGTH><INODEID>0</INODEID><PATH>/apiTest/text.txt._COPYING_</PATH><REPLICATION>3</REPLICATION><MTIME>1625197342135</MTIME><ATIME>1625197340573</ATIME><BLOCKSIZE>134217728</BLOCKSIZE><CLIENT_NAME/><CLIENT_MACHINE/><OVERWRITE>false</OVERWRITE><BLOCK><BLOCK_ID>1073741964</BLOCK_ID><NUM_BYTES>21359</NUM_BYTES><GENSTAMP>1140</GENSTAMP></BLOCK><PERMISSION_STATUS><USERNAME>win10</USERNAME><GROUPNAME>supergroup</GROUPNAME><MODE>420</MODE></PERMISSION_STATUS></DATA></RECORD><RECORD><OPCODE>OP_RENAME_OLD</OPCODE><DATA><TXID>1203</TXID><LENGTH>0</LENGTH><SRC>/apiTest/text.txt._COPYING_</SRC><DST>/apiTest/text.txt</DST><TIMESTAMP>1625197342157</TIMESTAMP><RPC_CLIENTID>6b6c7166-b01f-42bd-a859-d5963b730497</RPC_CLIENTID><RPC_CALLID>8</RPC_CALLID></DATA></RECORD>
</EDITS>
Q-A:
- NameNode如何确定下次集群启动时合并哪些信息?
- 当前的 fsImage文件我们是已知的, fsImage的文件名也是已知的, 所以
只需合并edits文件名中的序号大于 fsImage文件名序号的部分 edits文件即可
.
- 当前的 fsImage文件我们是已知的, fsImage的文件名也是已知的, 所以
- NN 和 2NN的差异文件?
- edits-inprogress
- edits-inprogress
5.4, CheckPoint时间设置
定时
通常情况下,Secondary NameNode 每隔一小时执行一次
定次数
一分钟检查一次操作次数,当操作次数达到一百万时,SecondaryNameNode执行一次;
六, DataNode
6.1, DataNode工作机制
- 一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件, 一个是
数据本身
, 另一个是元数据
(.meta文件)(包括数据块的长度,块数据的校验和,以及时间戳); - DataNode启动后向NameNode注册(报告块信息),NN返回注册成功的消息. 为避免中途宕机, DataNode会周期性(6小时)的向NameNode上传所有的块信息;
- 心跳(告诉NN本DN还活着)是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令比如复制块数据到另一台机器,或是删除某个数据块. 如果超过十分钟没有收到某个DataNode的心跳(10分钟+ 30秒, 即十分钟再加上十次心跳),则认为该节点不可用;
- 集群运行中可以安全加入和退出一些机器.
6.2, 数据完整性
- DataNode节点保证数据完整性的方法:
- 当DataNode读取Block的时候,它会计算CheckSum;
- 如果计算后的CheckSum, 与Block创建时值不一样,说明Block已经损坏;
- Client读取其他DataNode上的Block;
- 常见的校验算法 crc(32), md5, sha1;
- DataNode在其文件创建后周期验证ChechSum;
6.3 掉线时限参数设置
10分钟 + 30s
二, 大数据基础架构Hadoop-HDFS入门和基本操作(基本组成, Shell操作, API操作, 读写流程) hf相关推荐
- 大数据基础架构Hadoop,终于有人讲明白了
导读:大数据正在成为经济社会发展的新的驱动力.随着云计算.移动互联网等网络新技术的应用和发展,社会信息化进程进入大数据时代,海量数据的产生与流转成为常态.而大数据技术也如雨后春笋般正在蓬勃发展中.Ha ...
- 大数据基础之Hadoop(一)—— Hadoop概述
Hadoop系列 大数据基础之Hadoop(一)-- Hadoop概述 大数据基础之Hadoop(二)-- HDFS 大数据基础之Hadoop(三)-- MapReduce 大数据基础之Hadoop( ...
- 大数据基础之Hadoop(三)—— MapReduce
作者:duktig 博客:https://duktig.cn (文章首发) 优秀还努力.愿你付出甘之如饴,所得归于欢喜. 本篇文章源码参看:https://github.com/duktig666/b ...
- 车联网大数据框架_大数据基础:ORM框架入门简介
作为大数据开发技术者,需要掌握扎实的Java基础,这是不争的事实,所以对于Java开发当中需要掌握的重要框架技术,也需要有相应程度的掌握,比如说ORM框架.今天的大数据基础分享,我们就来具体讲一讲OR ...
- 大数据_07 【hadoop HDFS的shell命令操作】
大数据_07 [hadoop HDFS的shell命令操作] 01 基本语法 02 常用普通命令实操 03 HDFS常用高级命令 04 HDFS适用场景 05 HDFS不适用场景 06 hdfs的安全 ...
- 大数据培训:Hadoop HDFS 实现原理
一.HDFS体系结构 1.1 HDFS 简介 Hadoop分布式文件系统 (HDFS) 是运行在通用硬件(commodity hardware)上的分布式文件系统(Distributed File S ...
- 大数据技术之Hadoop(快速入门)
目录 第一章 Hadoop概述 1.1 什么是Hadoop 1.2 Hadoop 产生背景 Hadoop之父:Doug cutting 1.3 Hadoop 三大发行版本 Hadoop 三大发行版 ...
- 大数据基础(hadoop环境搭建及使用)
大数据 大数据概念 大数据特点(4V) Volume(大量) Velocity(高速) Variety(多样) Value(低价值密度) Hadoop Hadoop是什么 Hadoop 三大发行版本 ...
- 大数据技术之Hadoop(入门)概述、运行环境搭建、运行模式
文章目录 1 Hadoop 概述 1.1 Hadoop 是什么 1.2 Hadoop 优势 1.3 Hadoop 组成(面试重点) 1.3.1 HDFS 架构概述 1.3.2 YARN 架构概述 1. ...
最新文章
- Apache Mina 介绍
- CentOs下php连mssql并配置unixODBC
- linux内存使用策略swap,Linux Swap使用分析
- php强制转成字符串,php怎么强制转成字符串
- 网盘运营太难了!百度网盘因“用户激励计划”起风波并致歉
- c 语言比较三个整数大小,C 语言 —— 比较三个整数的大小并从大到小输出
- PowerShell命令行窗口中设置环境变量 (简介,以及与cmd、shell、linux命令对比)
- python写股票指标_一文看懂KDJ指标及Python实现
- 啊哈C语言 第三章 【代码】【习题答案】
- 在arcgis中进行拓扑检查
- 华为价值评价体系的四个基本假设
- C++——以任意数为底的对数
- saas 系统租户个性化域名租户绑定自己域名的解决方案
- 村田 | 用于人机界面和生命体征检测的压电薄膜传感器
- 多个excel工作簿、工作表合并
- 前端寒假css(100-181)
- AD根据已有的PCB封装链接至原理图
- Python matplotpy颜色表(python画图常用颜色)
- 初级会计实务--第三章第四节、应交税费
- 100000行级别数据的 Excel 导入优化之路
热门文章
- mysql association_在mybatis的xml中添加association不生效
- libsvm的使用svm-scale和svm-train与svm-predict
- 谷歌浏览器 翻译无法使用的问题
- java堆栈总结、JVM
- 关于fastapi框架的异步
- android studio抛出,Android Studio升级到3.0,抛出Aapt2Exception异常
- 【树莓派】一、新坑入门-购买篇、基础配置篇
- 基于.net的大型web开源免费erp
- html手机陀螺仪,手机中的陀螺仪竟然也不值得信任
- MySQL Kill出现Killed死锁处理