头歌实践教学平台:大数据存储2023(十三2)

头歌实践教学平台:大数据存储2023(十三2) 十三、HBase开发 Java API 管理表第2关修改表任务描述本关任务修改指定表的结构。相关知识想要修改一个已经存在的表一般有两种办法1.删除后重建2.在原有的基础上修改。第一种方式很方便不过有一个缺点那就是无法保存原有表的数据我们在当前表中如果有重要数据要保存的情况下去删除表然后重建是不能满足需求的。这个时候我们就需要在原有的基础上修改表。修改列族在修改表之前我们要了解表中列族各个属性的意义才能做出有效的修改也才能知道我们修改了之后会产生什么结果。块大小blocksize配置HBase在存储数据的时候会将数据切割成块来存储在集群中不同的位置。块大小是HBase的一个重要配置选项默认块大小为6553664K,默认单位是字节采用这种细粒度目的是块操作时更加有效加载和缓存数据对于不同的业务数据块大小的合理设置对读写性能有很大的影响。而对块大小的调整主要取决于两点用户平均读取数据的大小。理论上讲如果用户平均读取数据的大小较小建议将块大小设置较小这样可以使得内存可以缓存更多block读性能自然会更好。相反建议将块大小设置较大。随着BlockSize的增大系统随机读的吞吐量不断降低延迟不断增大。对于以随机读为主的业务可以适当调低BlockSize的大小以获得更好的读性能。对于以scan为主的业务可以适当增大BlockSize的大小以获得更好的读性能。可见如果业务请求以Get请求为主可以考虑将块大小设置较小如果以Scan请求为主可以将块大小调大默认的64K块大小是在Scan和Get之间取得的一个平衡。数据平均键值对规模。那如何设置缓存大小呢示例ColumnFamilyDescriptorBuilder buildFamily ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(data));//创建builder对象buildFamily.setBlocksize(100000);//设置缓存大小设置块缓存设置缓存应该是一个要谨慎考虑的工作。把数据放进读缓存但工作负载却经常不能从中获得性能提升——例如如果一张表或表里的列族只被顺序化扫描访问或者很少被访问你不会介意Get或Scan花费时间是否有点长。在这种情况下你可以选择关闭那些列族的缓存。如果你只是执行很多顺序化扫描你会多次倒腾缓存并且可能会滥用缓存把应该放进缓存获得性能提升的数据给排挤出去。如果关闭缓存你不仅可以避免上述情况发生而且可以让出更多缓存给其他表和同一表的其他列族使用。使用Java代码设置是否开启缓存buildFamily.setBlockCacheEnabled(false);//设置关闭缓存默认是true激进缓存的配置你可以选择一些列族赋予它们在数据块缓存里有更高的优先级LRU缓存。如果你预期一个列族比另一个列族随机读更多这个特性肯定能派上用场。设置是否开启激进缓存buildFamily.setInMemory(value); //默认是false生存时间配置TTL 生存时间当一个数据超过一定时间想要删掉这个是以秒s为单位的设置一个时间超过后数据会被加上删除标记。如何设置buildFamily.setTimeToLive(value); //以秒为单位超过这个时间设置的就会在下一次大合并中被删除压缩设置压缩配置可以提高CPU的使用率充分压榨CPU的性能。示例buildFamily.setCompressionType(Compression.Algorithm.NONE);//默认是NONE可选项有单元时间版本HBase可以设置多个时间版本也可以获取多个版本中的数据我们在设置的时候要根据业务来划分版本是历史记录版本增多意味更大的空间消耗。buildFamily.setMinVersions(0);buildFamily.setMaxVersions(5);知道了上述配置属性之后我们就可以来对表进行修改了。例如我们要将表test的data列族块大小设置为2M可以使用如下代码TableName tableName TableName.valueOf(test);ColumnFamilyDescriptorBuilder buildFamily ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(data));//构建Builder对象buildFamily.setBlocksize(1024*1024*2);ColumnFamilyDescriptor family buildFamily.build();//构建Family对象admin.modifyColumnFamily(tableName, family);//调用修改方法方法接收两个参数TableNameColumnFamilyDescriptor删除列族表中不需要的列族可以删掉使用deleteColumnFamily(TableName tableName, byte[] columnFamily)方法即可。admin.deleteColumnFamily(tableName, Bytes.toBytes(data));//删除表中名为data的列族编程要求好啦是时候操练一下了在右侧编辑器begin-end处编写程序修改表的结构要求如下修改表t_emp2修改列族data的bolckSize为1M关闭列族data的块缓存设置列族data的压缩格式为GZ修改表t_dept2设置列族data1的最小单元时间版本为2最大时间版本为5开启列族data1的激进缓存策略设置列族data1的生存时间为一天删除表t_emp2的列族data1删除表t_dept2的列族data。测试说明预期输出Tablet_emp2columndatablockSize1048576BlockCacheEnabledfalseisInMemoryfalseMinVersions0MaxVersions1TTL2147483647CompressionTypeGZTablet_dept2columndata1blockSize65536BlockCacheEnabledtrueisInMemorytrueMinVersions2MaxVersions5TTL86400CompressionTypeNONE每次点击测评平台会删除之前的表并重新创建两张表免受上次测评影响。开始你的任务吧祝你成功package step2;import java.io.IOException;import org.apache.hadoop.conf.*;import org.apache.hadoop.hbase.*;import org.apache.hadoop.hbase.client.*;import org.apache.hadoop.hbase.io.compress.Compression;import org.apache.hadoop.hbase.util.*;public class Task {public void updateTables()throws Exception{/********* Begin *********/Configuration conf HBaseConfiguration.create(); //使用create()静态方法就可以得到Configuration对象Connection conn ConnectionFactory.createConnection(conf); //config为前文的配置对象Admin admin conn.getAdmin(); //使用连接对象获取Admin对象TableName tableName1 TableName.valueOf(t_emp2);TableName tableName2 TableName.valueOf(t_dept2);ColumnFamilyDescriptorBuilder buildFamily ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(data));//创建builder对象buildFamily.setBlocksize(1024*1024);//设置缓存大小buildFamily.setBlockCacheEnabled(false);//设置关闭缓存默认是truebuildFamily.setCompressionType(Compression.Algorithm.GZ);//默认是NONEColumnFamilyDescriptor family buildFamily.build();//构建Family对象admin.modifyColumnFamily(tableName1, family);//调用修改方法方法接收两个参数TableNameColumnFamilyDescriptoradmin.deleteColumnFamily(tableName1, Bytes.toBytes(data1));//删除表中名为data的列族ColumnFamilyDescriptorBuilder buildFamily1 ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(data1));//创建builder对象buildFamily1.setMinVersions(2);buildFamily1.setMaxVersions(5);buildFamily1.setInMemory(true); //默认是falsebuildFamily1.setTimeToLive(60*60*24); //以秒为单位超过这个时间设置的就会在下一次大合并中被删除ColumnFamilyDescriptor family1 buildFamily1.build();//构建Family对象admin.modifyColumnFamily(tableName2, family1);//调用修改方法方法接收两个参数TableNameColumnFamilyDescriptoradmin.deleteColumnFamily(tableName2, Bytes.toBytes(data));//删除表中名为data的列族/********* End *********/}}有任何问题都可以随时关注私信