云服务器内容精选

  • 建议3.4 禁止针对普通列存表进行实时INSERT操作 违反规范的影响: 针对普通列存表实时小批量入库会导致小CU膨胀严重,影响存储空间和查询性能。 方案建议: 实时INSERT场景评估单次入库数据量和数据总量,总量小的场景可以改为行存表。 实时INSERT场景前端攒批,保证单次、单表、单分区、单DN入库数据量接近6W,建议最低不少于5K。 实时INSERT场景使用Hstore列存表(8.3.0及以上版本)。
  • 建议3.4 禁止针对普通列存表进行实时INSERT操作 违反规范的影响: 针对普通列存表实时小批量入库会导致小CU膨胀严重,影响存储空间和查询性能。 方案建议: 实时INSERT场景评估单次入库数据量和数据总量,总量小的场景可以改为行存表。 实时INSERT场景前端攒批,保证单次、单表、单分区、单DN入库数据量接近6W,建议最低不少于5K。 实时INSERT场景使用Hstore列存表(8.3.0及以上版本)。
  • Coordinator和Executor分离部署,Coordinator根据集群规模部署2-5个 Coordinator承担缓存元数据,解析SQL执行计划,和响应客户端请求的功能主要使用jvm内存,而Executor承担数据读写,算子计算等功能,主要使用offheap内存;拆分后可有效提升内存使用率;另外,所有的SQL执行统计均在Coordinator中记录,分离后可通过访问几个Coordinator节点获取整个集群的SQL运行情况,可减少运维压力。
  • Configuration实例的创建 该类应该通过调用HBaseConfiguration的create()方法来实例化。否则,将无法正确加载HBase中的相关配置项。 正确示例: //该部分,应该是在类成员变量的声明区域声明 private Configuration hbaseConfig = null; //建议在类的构造函数中,或者初始化方法中实例化该类 hbaseConfig = HBaseConfiguration.create(); 错误示例: hbaseConfig = new Configuration();
  • 资源释放 关于ResultScanner和Table实例,在用完之后,需要调用它们的Close方法,将资源释放掉。Close方法,要放在finally块中,来确保一定会被调用到。 正确示例: ResultScanner scanner = null; try { scanner = demoTable.getScanner(s); //Do Something here. } finally { scanner.close(); } 错误示例: 在代码中未调用scanner.close()方法释放相关资源。 scanner.close()方法未放置在finally块中。 ResultScanner scanner = null; scanner = demoTable.getScanner(s); //Do Something here. scanner.close();
  • Table实例的创建 public abstract class TableOperationImpl { private static Configuration conf = null; private static Connection connection = null; private static Table table = null; private static TableName tableName = TableName.valueOf("sample_table"); public TableOperationImpl() { init(); } public void init() { conf = ConfigurationSample.getConfiguration(); try { connection = ConnectionFactory.createConnection(conf); table = conn.getTable(tableName); } catch (IOException e) { e.printStackTrace(); } } public void close() { if (table != null) { try { table.close(); } catch (IOException e) { System.out.println("Can not close table."); } finally { table = null; } } if (connection != null) { try { connection.close(); } catch (IOException e) { System.out.println("Can not close connection."); } finally { connection = null; } } } public void operate() { init(); process(); close(); } }
  • 共享Configuration实例 HBase客户端代码通过创建一个与ZooKeeper之间的HConnection,来获取与一个HBase集群进行交互的权限。一个ZooKeeper的HConnection连接,对应着一个Configuration实例,已经创建的HConnection实例,会被缓存起来。也就是说,如果客户端需要与HBase集群进行交互的时候,会传递一个Configuration实例到缓存中去,HBase Client部分通过已缓存的HConnection实例,来判断属于这个Configuration实例的HConnection实例是否存在,如果不存在,会创建一个新的HConnection,如果存在,则会直接返回相应的实例。 因此,如果频繁地创建Configuration实例,会导致创建很多不必要的HConnection实例,很容易达到ZooKeeper的连接数上限。 建议在整个客户端代码范围内,都共用同一个Configuration对象实例。
  • HDFS创建文件 通过"FileSystem.mkdirs(Path f)"可在HDFS上创建文件夹,其中f为文件夹的完整路径。 正确示例: public class CreateDir { public static void main(String[] args) throws Exception{ Configuration conf=new Configuration(); FileSystem hdfs=FileSystem.get(conf); Path dfs=new Path("/TestDir"); hdfs.mkdirs(dfs); } }
  • 多线程安全登录方式 如果有多线程进行login的操作,当应用程序第一次登录成功后,所有线程再次登录时应该使用relogin的方式。 login的代码样例: private Boolean login(Configuration conf){ boolean flag = false; UserGroupInformation.setConfiguration(conf); try { UserGroupInformation.loginUserFromKeytab(conf.get(PRINCIPAL), conf.get(KEYTAB)); System.out.println("UserGroupInformation.isLoginKeytabBased(): " +UserGroupInformation.isLoginKeytabBased()); flag = true; } catch (IOException e) { e.printStackTrace(); } return flag; } relogin的代码样例: public Boolean relogin(){ boolean flag = false; try { UserGroupInformation.getLoginUser().reloginFromKeytab(); System.out.println("UserGroupInformation.isLoginKeytabBased(): " +UserGroupInformation.isLoginKeytabBased()); flag = true; } catch (IOException e) { e.printStackTrace(); } return flag; } 多次重复登录会导致后建立的会话对象覆盖掉之前登录建立的,将会导致之前建立的会话无法被维护监控,最终导致会话超期后部分功能不可用。
  • HDFS初始化方法 HDFS初始化是指在使用HDFS提供的API之前,需要做的必要工作。 大致过程为:加载HDFS服务配置文件,并进行Kerberos安全认证,认证通过后再实例化Filesystem,之后使用HDFS的API。此处Kerberos安全认证需要使用到的keytab文件,请提前准备。 正确示例: private void init() throws IOException { Configuration conf = new Configuration(); // 读取配置文件 conf.addResource("user-hdfs.xml"); // 安全模式下,先进行安全认证 if ("kerberos".equalsIgnoreCase(conf.get("hadoop.security.authentication"))) { String PRINCIPAL = "username.client.kerberos.principal"; String KEYTAB = "username.client.keytab.file"; // 设置keytab密钥文件 conf.set(KEYTAB, System.getProperty("user.dir") + File.separator + "conf" + File.separator + conf.get(KEYTAB)); // 设置kerberos配置文件路径 */ String krbfilepath = System.getProperty("user.dir") + File.separator + "conf" + File.separator + "krb5.conf"; System.setProperty("java.security.krb5.conf", krbfilepath); // 进行登录认证 */ SecurityUtil.login(conf, KEYTAB, PRINCIPAL); } // 实例化文件系统对象 fSystem = FileSystem.get(conf); }
  • HDFS上传本地文件 通过FileSystem.copyFromLocalFile(Path src,Patch dst)可将本地文件上传到HDFS的指定位置上,其中src和dst均为文件的完整路径。 正确示例: public class CopyFile { public static void main(String[] args) throws Exception { Configuration conf=new Configuration(); FileSystem hdfs=FileSystem.get(conf); //本地文件 Path src =new Path("D:\\HebutWinOS"); //HDFS为止 Path dst =new Path("/"); hdfs.copyFromLocalFile(src, dst); System.out.println("Upload to"+conf.get("fs.default.name")); FileStatus files[]=hdfs.listStatus(dst); for(FileStatus file:files){ System.out.println(file.getPath()); } } }
  • 查看HDFS文件的最后修改时间 通过FileSystem.getModificationTime()可查看指定HDFS文件的修改时间。 正确示例: public static void main(String[] args) throws Exception { Configuration conf=new Configuration(); FileSystem hdfs=FileSystem.get(conf); Path fpath =new Path("/user/hadoop/test/file1.txt"); FileStatus fileStatus=hdfs.getFileStatus(fpath); long modiTime=fileStatus.getModificationTime(); System.out.println("file1.txt的修改时间是"+modiTime); }
  • MapReduce中间文件存放路径 MapReduce默认中间文件夹存放路径只有一个,${hadoop.tmp.dir}/mapred/local,建议修改为每个磁盘下均可存放中间文件。 例如:/hadoop/hdfs/data1/mapred/local、/hadoop/hdfs/data2/mapred/local、/hadoop/hdfs/data3/mapred/local等,不存在的目录会自动忽略。
  • HDFS需要开启DataNode数据存储路径 DataNode默认存储路径配置为:${BIGDATA_DATA_HOME}/hadoop/dataN/dn/datadir(N≥1),N为数据存放的目录个数。 例如:${BIGDATA_DATA_HOME}/hadoop/data1/dn/datadir、${BIGDATA_DATA_HOME}/hadoop/data2/dn/datadir 设置后,数据会存储到节点上每个挂载磁盘的对应目录下面。
  • HDFS提高读取写入性能方式 写入数据流程:HDFS Client收到业务数据后,从NameNode获取到数据块编号、位置信息后,联系DataNode,并将需要写入数据的DataNode建立起流水线,完成后,客户端再通过自有协议写入数据到Datanode1,再有DataNode1复制到DataNode2、DataNode3(三备份)。写完的数据,将返回确认信息给HDFS Client。 合理设置块大小,如设置dfs.blocksize为 268435456(即256MB)。 对于一些不可能重用的大数据,缓存在操作系统的缓存区是无用的。可将以下两参数设置为false: dfs.datanode.drop.cache.behind.reads和dfs.datanode.drop.cache.behind.writes