调用了listFiles(filePath, true)引发的血案

如代码所示使用Filesystem读文件目录,发现线上读取一个36万个文件的本地目录,任务卡住30分钟都没结束,冷汗下来了...

看线程栈位置在it.hasNext()位置,加日志看到一直有读取,大概每读1000个文件要8秒左右。改为listStatus然后自己实现递归读取,每1000个文件100多毫秒就能读完,看源码好像是listLocatedStatus和listStatus的区别,难道这个RemoteIterator迭代器成本很高吗

RemoteIterator<LocatedFileStatus> it = fs.listFiles(filePath, true);
            while (it.hasNext()) {
                fileList.add(it.next().getPath().toString().replace(replacedValue, ""));
            }

谜底就在谜面上,程序逻辑本意是读一下fileStatus,记录status的文件路径,但断点发现实际还去扫描了文件内容!

从线程堆栈上看到LocatedFileStatus有一些额外的操作,通过shell来读取文件系统权限相关信息,而这个在fileStatus中是没有的:

  public LocatedFileStatus(FileStatus stat, BlockLocation[] locations)
  throws IOException {
    this(stat.getLen(), stat.isDirectory(), stat.getReplication(),
        stat.getBlockSize(), stat.getModificationTime(),
        stat.getAccessTime(), stat.getPermission(), stat.getOwner(),
        stat.getGroup(), null, stat.getPath(), locations);
    if (stat.isSymlink()) {
      setSymlink(stat.getSymlink());
    }
  }

继续往下看stat.getPermission():

一开始没注意这里应该看具体的实现,而不是这个抽象类

   @Override
    public FsPermission getPermission() {
      if (!isPermissionLoaded()) {
        loadPermissionInfo();
      }
      return super.getPermission();
    }

上面可以发现loadPermissionInfo会去读文件,这个确实很伤!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值