hbase高可用架构(HBaseAPI及协处理器)
hbase高可用架构(HBaseAPI及协处理器)
2024-06-29 01:08:58  作者:小帅气  网址:https://m.xinb2b.cn/sport/sbz437291.html
HBase API 应用

引入依赖

<dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>1.3.1</version></dependency>

HBase API 使用示例:

public class HBaseClient { Connection connection; Admin admin; @Before public void init() throws IOException { Configuration configuration = HBaseConfiguration.create(); configuration.set("hbase.zookeeper.quorum","linux2,linux3,linux4"); configuration.set("hbase.zookeeper.property.clientPort","2181"); connection = ConnectionFactory.createConnection(configuration); } @Test public void createTable() throws IOException { admin = connection.getAdmin(); //创建表描述器 HTableDescriptor teacher = new HTableDescriptor(TableName.valueOf("teacher")); //设置列族 teacher.addFamily(new HColumnDescriptor("info")); admin.createTable(teacher); System.out.println("创建teacher表成功"); } @Test public void putData() throws IOException { Table teacher = connection.getTable(TableName.valueOf("teacher")); //设置rowkey Put put = new Put(Bytes.tobytes("003")); put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("xiaoqing")); put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes("13")); teacher.put(put); teacher.close(); } @Test public void getData() throws IOException { HTable teacher = (HTable) connection.getTable(TableName.valueOf("teacher")); Get get=new Get(Bytes.toBytes("001")); get.addFamily(Bytes.toBytes("info")); Result result = teacher.get(get); Cell[] cells = result.rawCells(); for (Cell cell : cells){ String cellFamily = Bytes.toString(CellUtil.cloneFamily(cell)); String column = Bytes.toString(CellUtil.cloneQualifier(cell)); String value = Bytes.toString(CellUtil.cloneValue(cell)); String rowkey = Bytes.toString(CellUtil.cloneRow(cell)); System.out.println("rowkey:" rowkey "," cellFamily "__" column "__" value); } } @Test public void scanAll() throws IOException { HTable teacher = (HTable) connection.getTable(TableName.valueOf("teacher")); Scan scan=new Scan(); ResultScanner resultScanner = teacher.getScanner(scan); for (Result result : resultScanner){ Cell[] cells = result.rawCells(); for (Cell cell : cells){ String cellFamily = Bytes.toString(CellUtil.cloneFamily(cell)); String column = Bytes.toString(CellUtil.cloneQualifier(cell)); String value = Bytes.toString(CellUtil.cloneValue(cell)); String rowkey = Bytes.toString(CellUtil.cloneRow(cell)); System.out.println("rowkey:" rowkey "," cellFamily "__" column "__" value); } } } @Test public void scanRowKey() throws IOException { HTable teacher = (HTable) connection.getTable(TableName.valueOf("teacher")); Scan scan=new Scan(); scan.setStartRow("001".getBytes(StandardCharsets.UTF_8)); scan.setStopRow("002".getBytes(StandardCharsets.UTF_8)); ResultScanner resultScanner = teacher.getScanner(scan); for (Result result : resultScanner){ Cell[] cells = result.rawCells(); for (Cell cell : cells){ String cellFamily = Bytes.toString(CellUtil.cloneFamily(cell)); String column = Bytes.toString(CellUtil.cloneQualifier(cell)); String value = Bytes.toString(CellUtil.cloneValue(cell)); String rowkey = Bytes.toString(CellUtil.cloneRow(cell)); System.out.println("rowkey:" rowkey "," cellFamily "__" column "__" value); } } } @Test public void deleteData() throws IOException { Table teacher = (Table) connection.getTable(TableName.valueOf("teacher")); Delete delete=new Delete(Bytes.toBytes("001")); teacher.delete(delete); teacher.close(); System.out.println("删除数据成功"); } @After public void destory(){ if(admin != null){ try { admin.close(); } catch (IOException e) { e.printStackTrace(); } } if(connection != null){ try { connection.close(); } catch (IOException e) { e.printStackTrace(); } } }}

HBase 协处理器

通常查询 HBase 数据是使用 scan 或者 get,再根据获取到的数据进行业务计算。但是在数据量非常大的时候,比如一个有上亿行及十万个列的数据集,再按照常用方式获取数据就会获得性能问题。客户端也需要有强大的计算能力以及足够的内存来处理这么多的数据。

此时就可以考虑使用 Coprocessor(协处理器),将业务运算代码封装到 Coprocessor 中并在 RegionServer 上运行,即在数据实际存储位置执行,最后将运算结果返回到客户端。利用协处理器,用于可以编写运行在 HBase Server 端的代码。

协处理器类型:

1. Observer:

协处理器与触发器类似,在一些特定事件发生时回调函数(也称作钩子函数)被执行。这些事包括一些用户产生的事件,也包括服务端内部自动产生的事件。

协处理器框架提供的接口如下:

RegionObserver:用户可以用这种的处理器处理数据修改事件MasterObserver:可以被用作管理或 DDL 类型的操作,这些是集群级事件WALObserver:提供控制 WAL 的钩子函数

案例实战:

实现 HBase 当中向 t1 表中插入一条数据,指定的 t2 表也要插入一条一模一样的数据。

1.先创建两个表

create 't1','info'create 't2','info'

2.引入依赖

<dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-server</artifactId> <version>1.3.1</version></dependency>

3.代码编写

public class MyProcessor extends BaseRegionObserver { @Override public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException { //把自己需要执行的逻辑定义在此处,向t2表插入数据,数据具体是什么内容与Put一样 final HTableInterface t2 = e.getEnvironment().getTable(TableName.valueOf("t2")); //解析t1表的插入对象put final Cell cell = put.get(Bytes.toBytes("info"), Bytes.toBytes("name")).get(0); //table对象.put final Put put1 = new Put(put.getRow()); put1.add(cell); t2.put(put1); //执行向t2表插入数据 t2.close(); }}

4.打成 jar 包,上传到 hdfs

hdfs dfs -mkdir -p /processorhdfs dfs -put hbase-1.0-SNAPSHOT.jar /processor

5.挂载协处理器

alter 't1',METHOD => 'table_att','Coprocessor'=>'hdfs://linux2:9000/processor/hbase-1.0-SNAPSHOT.jar|com.lagou.hbase.MyProcessor|1001|'

挂载完成后,可以通过 以下命令看看挂载成功没

describe 't1'

hbase高可用架构(HBaseAPI及协处理器)(1)

这样就是挂载成功了

6.验证

put 't1','rk1','info:name','lisi'

向 t1 表插入数据后,发现 t2 表也插入了数据。

卸载协处理器

disable 't1'alter 't1',METHOD=>'table_att_unset',NAME=>'coprocessor$1'enable 't1'

2. Endpoint

这类协处理器类似传统数据库中的存储过程,客户端可以调用这些 Endpoint 协处理器在 Regionserver 中执行一段代码,并将 RegionServer 端执行结果返回给客户端进一步处理。

常见用途

如:聚合操作。假设需要找出一张表中最大的数据,普通做法是全表扫描,然后在 Client 端内遍历结果,并执行求最大值的操作。这种方式存在的弊端是无法利用底层集群的并发运算能力,把所有计算都集中到 Client 端,效率低下。

使用 Endpoint Coprocessor,用户可以把求最大值的代码部署到 RegionServer 端,HBase 会利用集群中多个节点的优势来并发执行求最大值的操作。也就是每个 Region 范围内求最大值,将每个 Region 的最大值在 RegionServer 端算出,仅仅将 max 值返回给 Client。在 Client 进一步将多个 Region 的最大值进行比较找到全局的最大值即可。

Endpoint Coprocessor 的应用借助于 Phoenix 非常容易就能实现。

HBase 表的 RowKey 设计

1.RowKey 字典顺序

RowKey 是基于 ASCII 码值进行字典排序的。先比较第一个字节,如果相同,就比较第二个字节。如果到第 X 个字节,其中一个已经超出了 rowkey 的长度,短 的rowkey 排在前面。

2.RowKey 长度原则

rowkey 是一个二级制码流,可以是任意字符串,最大长度 64kb,实际应用中一般为 10-100bytes,以 byte[]形式保存,一般设计成定长。

建议越短越好,不要超过 16 个字节。设计过长会降低 Memstore 内存的利用率和 HFile 存储数据的效率

3.RowKey 散列原则

建议将 rowkey 的高位作为散列字段,这样将提高数据均衡分布在每个 RegionServer,以实现负载均衡的几率

4.RowKey 唯一原则

必须在设计上保证其唯一性。访问 hbase table 中的行,有三种方式:

单个 rowkeyrowkey 的 range全表扫描(尽量避免全表扫描)

5.RowKey 排序原则

HBase 的 RowKey 是按照 ASCII 有序设计的,我们设计 RowKey 时要充分利用这点。

HBase 表的热点

什么是热点?

检索 hbase 的记录首先要通过 rowkey 来定位数据行,当大量的 client 访问 hbase 集群的一个或少数几个节点,造成少数 region server 请求过多,而其他 region server 请求很少,就造成了“热点”现象。

热点的解决方案

1.预分区

预分区的目的是让表的数据可以均衡的分散在集群中,而不是默认只有一个 region 分布在集群的一个节点上。

2.加盐

这里的“加盐”指的是在 rowkey 的前面增加随机数,具体就是给 rowkey 分配一个随机前缀以使得它和之前的 rowkey 的开头不同

3.哈希

哈希会使同一行永远用同一个前缀加盐。哈希也可以使负载分散到整个集群,但是读却是可以预测的。使用确定的哈希可以让客户端重构完整的 rowkey,可以使用 get 操作准确获取某一个行数据。

原始数据: abc1,abc2,abc3 哈希:md5(abc1)=92231b…, 9223-abc1md5(abc2) =32a131122…, 32a1-abc2md5(abc3) = 452b1…, 452b-abc3.

4.反转

反转固定长度或者数字格式的 rowkey,这样可以使得 rowkey 中经常改变的部分放在前面,这样可以有效的随机 rowkey,但是牺牲了 rowkey 的有序性。

HBase 应用技巧

二级索引

HBase 按照 rowkey 查询性能是最高的,rowkey 就相当于 hbase 表的一级索引。

为了 HBase 的数据查询更高效、适应更多的场景。如:使用非 rowkey 字段检索也能秒级相应,或者支持多个字段组合查询或模糊查询等。因此需要在 HBase 上构建二级索引,以满足现实中复杂多样的业务需求。

hbase 的二级索引其本质就是建立 hbase 表中列与行键的映射关系。

常见的二级索引我们一般可以借助各种其他的方式来实现,例如 Phoenix、Solr、Es。

布隆过滤器的应用

之前在讲 hbase 的数据存储原理的时候,我们知道 hbase 的读操作需要访问大量的文件,大部分的实现通过布隆过滤器来避免大量的读文件操作。

  • 思域发动机解剖(这家伙竟然花1300个小时组装了一台思域)
  • 2024-06-29这家伙竟然花1300个小时组装了一台思域2018年全球首台1:1乐高布加迪Chiron亮相,其中共涉及100万个乐高零件,与真车的精细程度不相上下不到半年,在澳大利亚的乐高真人秀节目中,同样是乐高积木搭建而成的本田思域TYPER再次震惊全网。
  • 西安你不知道的芦荡巷故事(西安广运潭每一天)
  • 2024-06-29西安广运潭每一天1下午4:00整,老涂打开放在玄关的袋子,重新检查了一番:泳镜,泳帽,泳裤还有游泳时跟在身后的橙色安全袋,装备都齐全又从阳台窗户向外望了眼,依然是万里无云的艳阳天和家人说了声“游泳去了”,老涂就利落地。
  • 沪深300期权实盘策略(510050期权套利怎么做)
  • 2024-06-29510050期权套利怎么做本文来源于公号:期权懂50期权的买卖过程还是很简单的,只要你操作过股票交易,很快就能熟悉50期权的买卖那么510050期权套利应该怎么做呢?#上证50etf期权##期权日记##期权交易#5100。
  • 宋教仁死于什么时间(宋教仁为何自号)
  • 2024-06-29宋教仁为何自号宋教仁为何自号“渔父”?原来背后还有个非常感人的故事因为参与“刺宋”,他成为被执行绞刑第一人,有个曾孙叫洪金宝在近代中国史上,宋教仁就像一颗耀眼的流星,曾照亮过历史的天空学生时代的宋教仁,就萌生了“实。
  • 汽车引擎盖下面各部件名称图(最全的汽车内部图解)
  • 2024-06-29最全的汽车内部图解这份最全汽车各部件图解,非常值得收藏!就算是老修理工,有很多部件的名字你肯定听说过但不一定都知道在哪个位置吧打开发动机盖,就是这个样子了,(这个是4A13发动机,其他机型有可能存在差异,但大体相同)空。
  • 李连杰黄飞鸿后来怎么了(关德兴还是李连杰)
  • 2024-06-29关德兴还是李连杰香港的功夫电影一直享誉中外,说到深入民心的作品,李小龙的电影固然出色,而拍了超过100部的黄飞鸿主题电影,更被列入吉尼斯世界纪录,是全球最长系列的电影《黄飞鸿》电影开播70年原型黄飞鸿武术医术皆出色早。
  • 360物联认证(物联360宣布正式启用全新LOGO)
  • 2024-06-29物联360宣布正式启用全新LOGO摘要:今天,物联360正式宣布,商城LOGO全面升级,启用全新设计的品牌标识(详见下图)logo左侧以大象造型构成,源自“大象无形”一词意为不要过于刻意,不要过分主张,兼容百态大象力大无穷,却性情温和。
  • 柠檬和鸡蛋虾仁(食在三月芒果虾仁)
  • 2024-06-29食在三月芒果虾仁今天为女儿换了花样,芒果虾仁,买了个大芒果20块钱,虾27块,这盘菜不便宜芒果165克,虾,300克,青豆30克,鸡蛋一个,胡椒粉适量,盐一小勺.鸡蛋打撒,虾去壳去虾线洗净沥水,取碗放入虾仁,加白胡椒。
  • 越南人名字不是中文
  • 2024-06-29越南人名字不是中文越南人名不是中文,是拼音越南、朝鲜原来的官方文字都是中文的.只不过是种口音很重的中文.韩国越南自古以来,一直以汉语为官方文字,韩国一直到了1970年代才取消全部汉字改用圈圈文.而越南是在1945年正式。
  • iphone x屏幕黑屏修复(iphonex突然黑屏开不了机)
  • 2024-06-29iphonex突然黑屏开不了机iPhone突然黑屏或死机,无缘无故黑屏,对于一天到晚离不开手机的你,有没有想过哪一天iPhoneX突然就这样死机或者黑屏开不了机了,到底该怎么办呢?iphonex突然黑屏开不了机,iphoneX黑屏。
  • 岳云鹏谈吃不起饭(岳云鹏晒午餐吸引5万人点赞)
  • 2024-06-29岳云鹏晒午餐吸引5万人点赞岳云鹏大热天晒午餐,满桌都是饺子,评论区让人爆笑!都是人才岳云鹏虽然是个相声演员,但是在吃货界也是非常闻名的,有网友戏称他为“娱乐圈最会吃的人”,岳云鹏也经常在个人社交媒体上发布一些美食照片,分享自己。