hbase高可用架构(HBaseAPI及协处理器)
hbase高可用架构(HBaseAPI及协处理器)
2024-07-02 11:24:00  作者:小帅气  网址:https://m.xinb2b.cn/tech/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 的读操作需要访问大量的文件,大部分的实现通过布隆过滤器来避免大量的读文件操作。

  • 床头不宜朝哪个方向摆放(床头不能朝哪个方向)
  • 2024-07-03床头不能朝哪个方向卧室是人们休憩的重要场所,很多人在摆放床的时候都会有个疑问:“床头朝哪个方向好?”“床头不能朝哪个方向?”大家似乎很关心到底放在哪里才更好其实,床头放哪边并没有什么具体的讲究和说法,怎么放还是要按房间。
  • 李一桐杨洋花絮(元气满满的哥哥杨洋李一桐玩游戏好甜)
  • 2024-07-03元气满满的哥哥杨洋李一桐玩游戏好甜由陈歆宇工作室和安德胜工作室联合制作的湖南卫视代际互动观察类游戏综艺《元气满满的哥哥》第九期节目将于今晚8点10分播出本期节目中,元气哥哥们依然驻留在风景隽秀、气候宜人的山东青岛,开启全新一轮热火朝天。
  • 韭菜肉木耳粉条包子(韭菜粉条鸡蛋包子-三鲜大包子)
  • 2024-07-03韭菜粉条鸡蛋包子-三鲜大包子今天再来教大家一个素馅儿大包子的做法吧,喜欢的朋友们给点个赞关注一下,谢谢大家的支持首先老规矩,我们先和面,1斤面粉,加入6g的酵母,3g白糖,泡打粉1g,温水250g和匀醒发20分钟三颗鸡蛋炒碎,晾。
  • u3手机怎么样
  • 2024-07-03u3手机怎么样u3手机还是不错的!1、iQOOU3这款手机采用的是天玑800U处理器,整体性能是非常不错的,跑分成绩达到了33万分左右2、续航能力方面,iQOOU3这款手机的电池容量达到了5000毫安3、iQOOU。
  • 高清大屏电视机哪个好(大屏电视终极选购指南)
  • 2024-07-03大屏电视终极选购指南1大屏电视终极选购指南虽然高端电视在画质、做工上有着一定的优势,但是在价格上却高出普通电视产品一倍甚至几倍的价钱在国内电视市场,目前中低端市场依然火爆,很多高性价比电视产品在面板涨价风波逐渐退去的同时。
  • 魔哒解说ar游戏实况(电竞浮梦第十五期)
  • 2024-07-03电竞浮梦第十五期Bobo王者荣耀大神团视频解说口头禅:可以啊大兄弟!解说萌妹子主播身材娇小古灵精怪学生党处女座能歌善舞自我介绍:大家好,我就是文能挂机坑队友,武能越塔送人头进可孤身一挑五,退可坐等六分投的宇宙无敌小可。
  • 李玉湖黄奕古装(42岁黄奕披古风嫁衣颜值惊艳)
  • 2024-07-0342岁黄奕披古风嫁衣颜值惊艳饿了吗?戳右边关注我们,每天给您送上最新出炉的娱乐硬核大餐!如果提到古装造型令人印象深刻的女星,黄奕想必一定不能落下尽管现在提起她,更多的是想到那些狗血情感故事,可年轻的时候,她的古装造型是很多人心头。
  • 无性姻缘该怎么过(无性的婚姻可以维持吗)
  • 2024-07-03无性的婚姻可以维持吗我满心期待的走进婚姻,想和他白头到老为他生儿育女,但现在我们结婚还不到一年时间,就遇到让人难以言表而又无法解决的矛盾我们在夫妻的性生活上非常不协调,为此我很苦恼,但每次和他谈这个问题都是不欢而散请问性。