docker搭建hbase环境_docker hbase_luffy5459的博客-程序员秘密

技术标签: hbaseadmin  hadoop  hbase  springboot  table  云计算  docker  

    hbase是hadoop生态中的一员,最早搭建hbase,需要先安装hadoop,然后安装zookeeper,再安装hbase。现在通过docker可以直接安装hbase,而且容器中并不需要hadoop。

    安装很简单。直接拉取镜像,然后运行即可。

docker run -d --name hbase -p 2181:2181 -p 16010:16010 -p 16020:16020 -p 16030:16030 harisekhon/hbase

    这里注意一点,对于端口映射,hbase用到了很多端口,有的地方直接使用-P参数,而不是用-p做端口一一映射。 

docker run -d --name hbase -P harisekhon/hbase

    如果通过-P参数,会将容器内部所有监听的端口都映射为随机端口,我们可以看看容器状态:

[[email protected] ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                                                                                                                                                                                                                 NAMES
748f76bf11f3        harisekhon/hbase    "/entrypoint.sh"    31 minutes ago      Up 31 minutes       0.0.0.0:32776->2181/tcp, 0.0.0.0:32775->8080/tcp, 0.0.0.0:32774->8085/tcp, 0.0.0.0:32773->9090/tcp, 0.0.0.0:32772->9095/tcp, 0.0.0.0:32771->16000/tcp, 0.0.0.0:32770->16010/tcp, 0.0.0.0:32769->16201/tcp, 0.0.0.0:32768->16301/tcp   hbase

    其中,16010端口是hbase提供的webui界面暴露的端口,映射为了32770,我们可以通过虚拟机地址,以及这个端口访问hbase webui。

     到了这里,通过web界面能够看到hbase状态,然后,可以进入容器,运行hbase shell,执行建表,添加数据,扫描数据都没有问题。但是如果外部程序,比如java需要操作hbase,就非常麻烦。

    所以,这里不建议直接使用-P(大写)的方式启动hbase。

    推荐的启动方式:docker run -d --name hbase -p 2181:2181 -p 16010:16010 -p 16020:16020 -p 16030:16030 harisekhon/hbase

    不推荐的启动方式:docker run -d --name -P harisekhon/hbase

    springboot与hbase整合

    1、通过docker搭建hbase环境虽然简单,但是有个问题,就是它的主机映射直接使用的是容器ID,所以,我们外部java程序如果需要连接hbase,需要对容器ID添加到本机的hosts列表中。

192.168.61.150	docker dd13ff2dca8e

    2、引入hbase依赖库,这里,只需要额外引入hbase-client依赖即可。

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

   3、配置文件application.properties

hbase.config.hbase.zookeeper.quorum=192.168.61.150
hbase.config.hbase.zookeeper.property.clientPort=2181

   4、配置文件对应Java类,HbaseProperties.java

package com.xx.hbase.config;

import java.util.Map;

import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "hbase")
public class HbaseProperties {
	private Map<String,String> config;
	
	public void setConfig(Map<String, String> config) {
		this.config = config;
	}
	
	public Map<String, String> getConfig() {
		return config;
	}
}

    5、HbaseConfig.java

package com.xx.hbase.config;

import java.io.IOException;
import java.util.Map;

import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(HbaseProperties.class)
public class HbaseConfig {
	private final HbaseProperties props;
	
	public HbaseConfig(HbaseProperties props) {
		this.props = props;
	}
	
	@Bean
	public org.apache.hadoop.conf.Configuration configuration(){
		org.apache.hadoop.conf.Configuration conf = HBaseConfiguration.create();
		Map<String, String> config = props.getConfig();
		config.forEach(conf::set);
		return conf;
	}
	
	@Bean
	public Connection getConnection() throws IOException{
		return ConnectionFactory.createConnection(configuration());
	}
	
	@Bean
	public HBaseAdmin hBaseAdmin() throws IOException {
		return (HBaseAdmin) getConnection().getAdmin();
	}
}

    6、HbaseService.java

package com.xx.hbase.config;

import java.io.IOException;
import java.util.Map;

import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.util.Bytes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class HbaseService {
	@Autowired
	private HBaseAdmin admin;
	
	@Autowired
	private Connection connection;
	
	public void createTable(String name,String colFamily) throws IOException {
		TableName table = TableName.valueOf(name);
		if(admin.tableExists(table)) {
			System.out.println("table ["+name+"] exist.");
		}
		
		ColumnFamilyDescriptor cfd = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(colFamily))
				.setMaxVersions(1).build();
		
		TableDescriptor tableDes = TableDescriptorBuilder.newBuilder(table).setColumnFamily(cfd).build();
		admin.createTable(tableDes);
		
	}
	
	public void putData(String name,String colFamily,String rowKey,Map<String, String> data) throws IOException {
		TableName table = TableName.valueOf(name);
		if(admin.tableExists(table)) {
			Table t = connection.getTable(table);
			Put put = new Put(Bytes.toBytes(rowKey));
			for(Map.Entry<String, String> entry:data.entrySet()) {
				put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue()));	
			}
			t.put(put);
		}else {
			System.out.println("table ["+name+"] does not exist.");
		}
	}
	
	public void getData(String name) throws IOException{
		TableName table = TableName.valueOf(name);
		Table t = connection.getTable(table);
		ResultScanner rs = t.getScanner(new Scan());
		for(Result r:rs) {
			System.out.println("row:"+new String(r.getRow()));
			for(Cell cell:r.rawCells()) {
				System.out.println("colFamily:"+Bytes.toString(cell.getFamilyArray(),cell.getFamilyOffset(),cell.getFamilyLength())+""
						+",qualifier:"+Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength())+
						",value:"+Bytes.toString(cell.getValueArray(),cell.getValueOffset(),cell.getValueLength()));
			}
		}
	}
	
	
}

    7、springboot启动类

package com.xx.hbase;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HbaseApp {
	public static void main(String[] args) {
		SpringApplication.run(HbaseApp.class, args);
	}
}

    8、hbase单元测试类

package com.xx.mybatis;

import java.io.IOException;
import java.util.Map;

import org.apache.hbase.thirdparty.org.apache.commons.collections4.map.HashedMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.xx.hbase.HbaseApp;
import com.xx.hbase.config.HbaseService;

@SpringBootTest(classes = HbaseApp.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class HbaseTest {
	@Autowired
	private HbaseService hbaseService;
	
	@Test
	public void createTable() {
		try {
			hbaseService.createTable("stu", "info");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void putData() {
		String name = "stu";
		String colFamily = "info";
		String rowKey = "2";
		Map<String, String> data = new HashedMap<>();
		data.put("name", "bbb");
		data.put("email", "[email protected]");
		try {
			hbaseService.putData(name, colFamily, rowKey, data);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void getData() {
		try {
			hbaseService.getData("stu");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

    这里单元测试类,没有使用断言,只是调用了一下建表,插入数据,查询数据三个方法,证明java调用hbase接口操作hbase是没有问题的。 

    9、在docker容器中操作hbase

    总结:

         1、启动容器,不要使用-P随机端口映射,这样对后续java外部程序接入hbase造成很大麻烦。

         2、docker启动的hbase,使用了容器ID作为host,所以如果是外部程序要接入hbase,需要在本机hosts中加入容器ID对应的主机映射。 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/feinifi/article/details/121174846

智能推荐

chrome无法连接到代理服务器,IE也上不了,但是QQ可以登陆,其他软件可以用的解决方法_Afterwards_的博客-程序员秘密

出现这个问题,是昨天做了一些逆向的东西,曾经开过WireShark,用360禁用无关的网络访问,其他的好像也没做什么WireShark只是做监听而已 也不会做什么设置上的改变所以肯定就是360动了设置了.  把他卸了是当然,不过卸载了也不会好也肯定是当然.因为他的设置已经生效,臭苍蝇甩蛆行为已经发生了.(就是这么恶心)所以你在用IE打开网页的时候 会发现有跳转什么 360.cn

JavaWeb调用顺序_java web运行顺序_旷野历程的博客-程序员秘密

分享知识 传递快乐JavaWeb调用顺序如图:请求客户端请求进来会按照 filter -&gt; servlet -&gt; interceptor -&gt; controllerAdvice -&gt; aspect -&gt; controller的顺序调用。controller返回也会按照controller -&gt; aspect -&gt; controllerAdvice -&gt; interceptor -&gt; servlet -&gt; filter来依次返回。

tiva学习_朽木白露的博客-程序员秘密

https://blog.csdn.net/qq_42263796/article/details/93494690https://blog.csdn.net/weixin_43679759/article/details/95070000https://blog.csdn.net/d_xingguang/article/details/89433171

【转】2.2[译]async/await中阻塞死锁_async await 获取结果阻塞ui_sinolover的博客-程序员秘密

这篇博文主要是讲解在async/await中使用阻塞式代码导致死锁的问题,以及如何避免出现这种死锁。内容主要是从作者Stephen Cleary的两篇博文中翻译过来.原文1:Don'tBlock on Async Code原文2:why the AspNetSynchronizationContext was removed示例代码:async_await中阻塞死锁.rar一、async/await异步代码运行流程async/await是在.NE...

android m壁纸驱动之家,微软打造的良心壁纸App,仅4.2M_weixin_39828960的博客-程序员秘密

上次小编介绍了一系列的电脑壁纸自动换软件,收到了不少好评。不过有不少网友问有没有手机上的壁纸自动换APP呢?手机上的壁纸软件还真不少,这不必应壁纸也出了个手机版的,一起来看看吧。和电脑版一样,必应壁纸的手机版也是小巧玲珑且易用的。只有4.2M大小的它让你不用担心占用过多存储空间。打开必应壁纸手机版,它就会自动载入壁纸,并且将壁纸分为了日常壁纸、壁纸库与纯色。每日更新日常壁纸轻松设为壁纸在日常壁纸...

Elasticsearch Document写入、删除、查询以及搜索原理_爱喝咖啡的程序员的博客-程序员秘密

Document写入原理一. Document写入原理一. Document写入原理ES为了实现进实时搜索,在写入Document时利用了Buffer(内存),OS Cache(系统缓存,属于系统内存的一部分),Disk(磁盘)三种存储方式,尽可能的提升搜索的能力。ES的底层lucene实现的,在 luncene中一个index会被分为若干个数据段segment,每一个segment都会存放i...

随便推点

Transformer网络理解_江汉似年的博客-程序员秘密

https://zhuanlan.zhihu.com/p/48508221http://jalammar.github.io/illustrated-transformer/https://blog.csdn.net/yujianmin1990/article/details/85221271

git自动打tag,再生成增量包_git 自动tag_wuxing164的博客-程序员秘密

#!/bin/bash#author kingboy#description: create tag list for update#获取当前项目的配置名称gitdir="tdwnews"#要输出的目录路径dir="/home/git/$gitdir"#当前操作目录pwdPath=$(pwd)#判断是否有该目录没有则创建if test -e ${dir}then echo

@Data注解 与 lombok的作用与用法_lamb @data的作用_左眼看成爱的博客-程序员秘密

@Data 注解的主要作用是提高代码的简洁,使用这个注解可以省去代码中大量的get()、 set()、 toString()等方法;示例:建一个User 实体类(我们加了@Data注解,可以看见未添加任何get,set方法)import lombok.Data;/** * @author wh445306 * @version 1.0 * @Desciption:User lombok插件的作用与用法 * @date 2021-01-07 22:57 */@Datapu

Ansible自动化运维(1)_zhangshaohuas的博客-程序员秘密

目录一:ansible介绍二:ansible特性三:ansible环境部署3.1:ansible工作模式3.2:ansible安装3.3: ansible 配置3.3.1: ansible 主机清单一:ansible介绍Ansible 是个与 Puppet, SaltStack, Chef 并驾齐驱的组态设定 (Infrastructure as Code) 工具,其简单易用的特性让人爱不释手,在 DevOps 界更佔有一席之地。Ansible 提供一种最简单的方式用于发布、管理和编排计算机系统的工

asp.net core 3.1的swagger传文件正确的schema_如鹿渴慕泉水的博客-程序员秘密

"post": { "tags": [ "FuzzTemplate" ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "f.

推荐文章

热门文章

相关标签