HDFS多线程追加写数据踩坑

在将缓存系统从storm改造成Redis的过程中,遇到HDFS多线程追加写入的挑战。Hadoop官方不支持多线程写入,但通过Redis公平锁实现多线程安全写入。关键步骤包括:单例获取分布式锁、使用公平锁写HDFS、类锁关闭文件系统、理解HDFS租约机制,以及确保及时关闭文件流以避免数据丢失问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一个同事使用storm框架,在Bolt的prepare中执行定时任务,将缓存数据利用HDFS原生API定时写入HDFS。
最近将缓存系统改成了Redis,改写代码过程中,发现多线程调用HDFS的API进行追加写的代码各种报错。
下面将踩坑总结如下:
Hadoop的官方说明书明确指明,HDFS不可以多线程写,可以多线程读。
通过测试,使用redis公平锁的方式,可以将数据多线程写入HDFS中。
具体方式见最后代码。

注意事项:
  1. 关闭FileSystem的实例的时候,注意使用类锁的方式。
    否则会报java.io.IOException: Filesystem closed 的错误

  2. HDFS的租约机制(** lease holder**)
    应在关闭文件流之后,再将公平锁打开。否则由于租约机制会导致追加异常。
    报错如下:
    org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.protocol.AlreadyBeingCreatedException): Failed to APPEND_FILE /文件目录 on because DFSClient_NONMAPREDUCE_-2020766150_154 is already the current lease holder.

  3. HDFS只创建了文件没有数据的问题。
    一定注意程序的最后先将文件流closed(flush并不能把数据刷到HDFS中)。
    通常情况下关流和关闭FileSystem实例会放在Finally中执行,但是由于实时数据处理框架的特点,应注意调用完毕文件流之后就直接关闭文件流,以保证数据写入。

单例拿到分布式锁
public class RedissonUtils {
   
   
public static RedissonClient client;
   static{
   
   
      client=getInstance();
   }
   public static RedissonClient getClient(){
   
   
      
      if(client==null){
   
   
         client = RedissonUtils.getInstance();
      }
      return client;
   }
   public static RedissonClient getInstance(){
   
   
      Config config = new Config();
      config.useClusterServers
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值