├── .dockerignore ├── .gitignore ├── Dockerfile ├── Makefile ├── README.md ├── build-hbase.sh ├── cleanup-hbase.sh ├── config-hbase.sh ├── hbase-server ├── hbase-site.xml ├── prepare-hbase.sh ├── replace-hostname ├── start-hbase.py ├── start-hbase.sh ├── test_hbase.py └── zoo.cfg /.dockerignore: -------------------------------------------------------------------------------- 1 | data/ 2 | hbase*.tar* 3 | old/ 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | data/ 3 | logs 4 | old/ 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # HBase in Docker 2 | # 3 | # Version 0.5 4 | 5 | # http://docs.docker.io/en/latest/use/builder/ 6 | 7 | FROM ubuntu:bionic 8 | MAINTAINER Dave Beckett 9 | 10 | COPY *.sh /build/ 11 | 12 | ENV HBASE_VERSION 2.2.4 13 | 14 | RUN /build/prepare-hbase.sh && \ 15 | cd /opt/hbase && /build/build-hbase.sh \ 16 | cd / && /build/cleanup-hbase.sh && rm -rf /build 17 | 18 | VOLUME /data 19 | 20 | ADD ./hbase-site.xml /opt/hbase/conf/hbase-site.xml 21 | 22 | ADD ./zoo.cfg /opt/hbase/conf/zoo.cfg 23 | 24 | ADD ./replace-hostname /opt/replace-hostname 25 | 26 | ADD ./hbase-server /opt/hbase-server 27 | 28 | # REST API 29 | EXPOSE 8080 30 | # REST Web UI at :8085/rest.jsp 31 | EXPOSE 8085 32 | # Thrift API 33 | EXPOSE 9090 34 | # Thrift Web UI at :9095/thrift.jsp 35 | EXPOSE 9095 36 | # HBase's Embedded zookeeper cluster 37 | EXPOSE 2181 38 | # HBase Master web UI at :16010/master-status; ZK at :16010/zk.jsp 39 | EXPOSE 16010 40 | 41 | CMD ["/opt/hbase-server"] 42 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | IMAGE_NAME=dajobe/hbase 2 | IMAGE_TAG=latest 3 | 4 | HBASE_VERSION=$(shell awk '/^ENV HBASE_VERSION/ {print $3}' Dockerfile) 5 | 6 | build: 7 | @echo "Building hbase docker image $(HBASE_VERSION)" 8 | docker build -t $(IMAGE_NAME) . 9 | 10 | # This won't work unless you have already set up the repository config 11 | push: 12 | @echo "Pushing image to https://hub.docker.com/" 13 | docker push $(IMAGE_NAME):$(IMAGE_TAG) 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HBase in Docker 2 | =============== 3 | 4 | This configuration builds a docker container to run HBase (with 5 | embedded Zookeeper) running on the files inside the container. 6 | 7 | NOTE 8 | ---- 9 | 10 | The approach here requires editing the local server's `/etc/hosts` 11 | file to add an entry for the container hostname. This is because 12 | HBase uses hostnames to pass connection data back out of the 13 | container (from it's internal Zookeeper). 14 | 15 | Hopefully this can be improved with Docker's newer networking 16 | but this hasn't been fixed yet. 17 | 18 | 19 | Build Image 20 | ----------- 21 | 22 | $ docker build -t dajobe/hbase . 23 | 24 | 25 | Pull image 26 | ---------- 27 | 28 | If you want to pull the image already built then use this 29 | 30 | $ docker pull dajobe/hbase 31 | 32 | More details at https://hub.docker.com/r/dajobe/hbase/ 33 | 34 | 35 | Run HBase 36 | --------- 37 | 38 | I recommend using the start-hbase.sh script which will start the 39 | container and inspect it to determine all the local API ports and Web 40 | UIs plus will offer to edit /etc/hosts to add an alias for the 41 | container IP, if not already present. 42 | 43 | $ ./start-hbase.sh 44 | start-hbase.sh: Starting HBase container 45 | start-hbase.sh: Container has ID b2db2fb3c3a67e20e2addd5e4d2ffc9a51abaafc3f9b36f464af7739e82f6446 46 | start-hbase.sh: /etc/hosts already contains hbase-docker hostname and IP 47 | start-hbase.sh: Connect to HBase at localhost on these ports 48 | REST API 127.0.0.1:32874 49 | Rest Web UI http://127.0.0.1:32873/ 50 | Thrift API 127.0.0.1:32872 51 | Thrift Web UI http://127.0.0.1:32871/ 52 | HBase ZK 127.0.0.1:32875 53 | HBase Master Web UI http://127.0.0.1:32870/ 54 | 55 | start-hbase.sh: OR Connect to HBase on container hbase-docker 56 | REST API hbase-docker:8080 57 | Rest Web UI http://hbase-docker:8085/ 58 | Thrift API hbase-docker:9090 59 | Thrift Web UI http://hbase-docker:9095/ 60 | HBase ZK hbase-docker:2181 61 | HBase Master Web UI http://hbase-docker:16010/ 62 | 63 | start-hbase.sh: For docker status: 64 | start-hbase.sh: $ id=b2db2fb3c3a67e20e2addd5e4d2ffc9a51abaafc3f9b36f464af7739e82f6446 65 | start-hbase.sh: $ docker inspect $id 66 | 67 | The localhost ports on the Host machine listed above 32870-32874 will 68 | vary for every container and are ephemeral ports. 69 | 70 | Alternatively, to run HBase by hand: 71 | 72 | $ mkdir data 73 | $ id=$(docker run --name=hbase-docker -h hbase-docker -d -v $PWD/data:/data dajobe/hbase) 74 | 75 | and you will have to `docker inspect $id` to find all the ports. 76 | 77 | If you want to run multiple hbase dockers on the same host, you can 78 | give them different hostnames with the '-h' / '--hostname' argument. 79 | You may have to give them different ports though. Not tested. 80 | 81 | If you want to customize the hostname used, set the 82 | `HBASE_DOCKER_HOSTNAME` envariable on the docker command line 83 | 84 | 85 | Find Hbase status 86 | ----------------- 87 | 88 | Master status if docker container DNS name is 'hbase-docker' 89 | 90 | http://hbase-docker:16010/master-status 91 | 92 | The region servers status pages are linked from the above page. 93 | 94 | Thrift UI 95 | 96 | http://hbase-docker:9095/thrift.jsp 97 | 98 | REST server UI 99 | 100 | http://hbase-docker:8085/rest.jsp 101 | 102 | (Embedded) Zookeeper status 103 | 104 | http://hbase-docker:16010/zk.jsp 105 | 106 | 107 | See HBase Logs 108 | -------------- 109 | 110 | If you want to see the latest logs live use: 111 | 112 | $ docker attach $id 113 | 114 | Then ^C to detach. 115 | 116 | To see all the logs since the HBase server started, use: 117 | 118 | $ docker logs $id 119 | 120 | and ^C to detach again. 121 | 122 | To see the individual log files without using `docker`, look into 123 | the data volume dir eg $PWD/data/logs if invoked as above. 124 | 125 | 126 | Test HBase is working via python over Thrift 127 | -------------------------------------------- 128 | 129 | Here I am connecting to a the container's thrift API port (such as 130 | created by the start-hbase.sh script). The port 32872 is the Thrift 131 | API port exported to the host because [Happybase][1] [2] uses Thrift 132 | to talk to HBase. 133 | 134 | $ python3 135 | Python 3.8.5 (default, Jul 21 2020, 10:48:26) 136 | [Clang 11.0.3 (clang-1103.0.32.62)] on darwin 137 | Type "help", "copyright", "credits" or "license" for more information. 138 | >>> import happybase 139 | >>> connection = happybase.Connection('127.0.0.1', 32872) 140 | >>> connection.create_table('table-name', { 'family': dict() } ) 141 | >>> connection.tables() 142 | [b'table-name'] 143 | >>> table = connection.table('table-name') 144 | >>> table.put('row-key', {'family:qual1': 'value1', 'family:qual2': 'value2'}) 145 | >>> for k, data in table.scan(): 146 | ... print(k, data) 147 | ... 148 | b'row-key' {b'family:qual1': b'value1', b'family:qual2': b'value2'} 149 | >>> 150 | 151 | (Simple install for happybase: `sudo pip install happybase` although I 152 | use `pip install --user happybase` to get it just for me) 153 | 154 | 155 | Test HBase is working from Java 156 | ------------------------------- 157 | 158 | $ docker run --rm -it --link $id:hbase-docker dajobe/hbase hbase shell 159 | HBase Shell 160 | Use "help" to get list of supported commands. 161 | Use "exit" to quit this interactive shell. 162 | For Reference, please visit: http://hbase.apache.org/2.0/book.html#shell 163 | Version 2.1.2, r1dfc418f77801fbfb59a125756891b9100c1fc6d, Sun Dec 30 21:45:09 PST 2018 164 | Took 0.0472 seconds 165 | hbase(main):001:0> status 166 | 1 active master, 0 backup masters, 1 servers, 0 dead, 2.0000 average load 167 | Took 0.7255 seconds 168 | hbase(main):002:0> list 169 | TABLE 170 | table-name 171 | 1 row(s) 172 | Took 0.0509 seconds 173 | => ["table-name"] 174 | hbase(main):003:0> 175 | 176 | Showing the `table-name` table made in the happybase example above. 177 | 178 | Alternatively if you have the Hbase distribution available on the 179 | host you can use `bin/hbase shell` if the hbase configuration has 180 | been set up to connect to host `hbase-docker` zookeeper port 2181 to 181 | get the servers via configuration property `hbase.zookeeper.quorum` 182 | 183 | 184 | 185 | Proxy HBase UIs locally 186 | ----------------------- 187 | 188 | If you are running docker on a remote machine, it is handy to see 189 | these server-private urls in a local browser so here is a 190 | ~/.ssh/config fragment to do that 191 | 192 | Host my-docker-server 193 | Hostname 1.2.3.4 194 | LocalForward 127.0.0.1:16010 127.0.0.1:16010 195 | LocalForward 127.0.0.1:9095 127.0.0.1:9095 196 | LocalForward 127.0.0.1:8085 127.0.0.1:8085 197 | 198 | When you `ssh my-docker-server` ssh connects to the docker server and 199 | forwards request on your local machine on ports 16010 / 16030 to the 200 | remote ports that are attached to the hbase container. 201 | 202 | The bottom line, you can use these URLs to see what's going on: 203 | 204 | * http://localhost:16010/master-status for the Master Server 205 | * http://localhost:9095/thrift.jsp for the thrift UI 206 | * http://localhost:8085/rest.jsp for the REST server UI 207 | * http://localhost:16010/zk.jsp for the embedded Zookeeper 208 | 209 | to see what's going on in the container and since both your local 210 | machine and the container are using localhost (aka 127.0.0.1), even 211 | the links work! 212 | 213 | 214 | 215 | 216 | 217 | Notes 218 | ----- 219 | 220 | [1] http://happybase.readthedocs.org/en/latest/ 221 | 222 | [2] https://github.com/wbolster/happybase 223 | -------------------------------------------------------------------------------- /build-hbase.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | . /build/config-hbase.sh 4 | 5 | here=$(pwd) 6 | 7 | # delete files that are not needed to run hbase 8 | rm -rf docs *.txt LEGAL 9 | rm -f */*.cmd 10 | 11 | # Set Java home for hbase servers 12 | sed -i "s,^. export JAVA_HOME.*,export JAVA_HOME=$JAVA_HOME," conf/hbase-env.sh 13 | 14 | # Set interactive shell defaults 15 | cat > /etc/profile.d/defaults.sh < $logs_dir/hbase-thrift.log 2>&1 & 16 | 17 | # REST server (background) 18 | # Ports: 8080 API 19 | echo "hbase rest start logging to $logs_dir/hbase-rest.log" 20 | hbase rest start > $logs_dir/hbase-rest.log 2>&1 & 21 | 22 | # Master server (Foreground) that also starts the region server 23 | # Ports: Master: 16000 API, 16010 UI; 2181 ZK; Region: 16020 API, 16030 UI 24 | echo "hbase master start logging to $logs_dir/hbase-master.log" 25 | exec hbase master start 2>&1 | tee $logs_dir/hbase-master.log 26 | -------------------------------------------------------------------------------- /hbase-site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | hbase.zookeeper.quorum 6 | hbase-docker 7 | 8 | 9 | hbase.rootdir 10 | file:////data/hbase 11 | 12 | 13 | 14 | hbase.master.info.bindAddress 15 | hbase-docker 16 | 17 | 18 | 19 | hbase.regionserver.info.bindAddress 20 | hbase-docker 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /prepare-hbase.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | . /build/config-hbase.sh 4 | 5 | apt-get update -y 6 | 7 | apt-get install $minimal_apt_get_args $HBASE_BUILD_PACKAGES 8 | 9 | cd /opt 10 | 11 | curl -SL $HBASE_DIST/$HBASE_VERSION/hbase-$HBASE_VERSION-bin.tar.gz | tar -x -z && mv hbase-${HBASE_VERSION} hbase 12 | -------------------------------------------------------------------------------- /replace-hostname: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Script that replaces the default hostname in files with the environments 4 | # ${HOSTNAME} variable. 5 | # 6 | # This script is intended to be run before starting hbase-server to ensure 7 | # that the hostname matches the configured environment variable. i.e. 8 | # the -h --hostname flag. 9 | # 10 | declare -a files=( 11 | '/opt/hbase/conf/hbase-site.xml' 12 | '/opt/hbase/conf/zoo.cfg' 13 | ) 14 | 15 | # Optional custom hostname replacement 16 | REPLACEMENT_HOSTNAME=${HBASE_DOCKER_HOSTNAME:-$HOSTNAME} 17 | 18 | for file in "${files[@]}"; do 19 | if [ -f "${file}.bak" ]; then 20 | cp "${file}.bak" "${file}" 21 | else 22 | cp "${file}" "${file}.bak" 23 | fi 24 | 25 | sed -i "s/hbase-docker/${REPLACEMENT_HOSTNAME}/g" "${file}" 26 | done 27 | -------------------------------------------------------------------------------- /start-hbase.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Script to start hbase-docker and update the /etc/hosts file to 4 | # point to the hbase-docker container 5 | # 6 | # hbase thrift and master server logs are written to the 7 | # startup-relative 'data/logs' directory 8 | # 9 | 10 | import json 11 | import logging 12 | import os 13 | import os.path 14 | from shutil import (rmtree) 15 | from subprocess import (check_output, run) 16 | 17 | 18 | # Image 19 | IMAGE_NAME = 'dajobe/hbase' 20 | 21 | # Docker container name to use 22 | CONTAINER_NAME = 'hbase-docker' 23 | 24 | # Maps to $PWD/data 25 | DATA_DIR_IN_CONTAINER = '/data' 26 | 27 | # List of Tuples of (Label, Port number, use: api or web) 28 | CONFIG = [ 29 | ('REST API', 8080, 'api'), 30 | ('REST UI', 8085, 'web'), 31 | ('Thrift API', 9090, 'api'), 32 | ('Thrift UI', 9095, 'web'), 33 | ('Zookeeper API', 2181, 'api'), 34 | ('Master UI', 16010, 'web'), 35 | ] 36 | 37 | 38 | 39 | def main(): 40 | ''' Start HBase in docker ''' 41 | 42 | logging.basicConfig() 43 | #logging.basicConfig(level=logging.DEBUG) 44 | 45 | cwd = os.getcwd() 46 | data_dir = os.path.join(cwd, 'data') 47 | 48 | # Set up data directory 49 | if os.path.exists(data_dir): 50 | rmtree(data_dir, ignore_errors=False) 51 | if not os.path.exists(data_dir): 52 | os.makedirs(data_dir) 53 | 54 | # force kill any existing container 55 | cmd = ['docker', 'rm', '-f', CONTAINER_NAME] 56 | logging.debug(cmd) 57 | # Do not care about output (or exit code) 58 | run(cmd, check=False) 59 | 60 | print('Starting HBase container') 61 | cmd = ['docker', 'run', 62 | f'--name={CONTAINER_NAME}', '-h', CONTAINER_NAME, 63 | '-d', '-P', '-v', f'{data_dir}:{DATA_DIR_IN_CONTAINER}', IMAGE_NAME] 64 | logging.debug(cmd) 65 | container_id = check_output(cmd, encoding='utf-8').strip() 66 | 67 | print(f'Container has ID {container_id}') 68 | 69 | # Get the container configuration 70 | cmd = ['docker', 'inspect', container_id] 71 | logging.debug(cmd) 72 | config_json = check_output(cmd, encoding='utf-8') 73 | logging.debug(config_json) 74 | config = json.loads(config_json) 75 | logging.debug(json.dumps(config)) 76 | 77 | docker_hostname = config[0]['Config']['Hostname'] 78 | docker_ip = config[0]['NetworkSettings']['IPAddress'] 79 | 80 | hosts_hbase_docker_ip = '' 81 | with open('/etc/hosts') as hosts_file: 82 | for line in hosts_file.readlines(): 83 | fields = line.split() 84 | if len(fields) > 2 and fields[1] == docker_hostname: 85 | hosts_hbase_docker_ip = fields[0] 86 | break 87 | 88 | if hosts_hbase_docker_ip == docker_ip: 89 | print(f'/etc/hosts already contains {docker_hostname} hostname and IP') 90 | else: 91 | print(f'Updating /etc/hosts to make {docker_hostname} point to {docker_ip} ({docker_hostname})') 92 | print('Running sudo - expect to type your password') 93 | if hosts_hbase_docker_ip == '': 94 | cmd_input = f'docker_ip {CONTAINER_NAME} {docker_hostname}' 95 | cmd = ['sudo', 'tee', '-a', '/etc/hosts'] 96 | run(cmd, input=cmd_input, check=True) 97 | else: 98 | sed_script = \ 99 | f's/^.*{CONTAINER_NAME}.*$/{docker_ip} {CONTAINER_NAME} {docker_hostname}/' 100 | cmd = ['sudo', 'sed', '-i.bak', sed_script, '/etc/hosts'] 101 | run(cmd, check=True) 102 | 103 | hostname = 'localhost' 104 | print(f'\nConnect to HBase at {hostname} on these endpoints') 105 | for cfg in CONFIG: 106 | (label, port, typ) = cfg 107 | 108 | mapped_port = config[0]['NetworkSettings']['Ports'][f'{port}/tcp'][0]['HostPort'] 109 | key = f'{hostname}:{mapped_port}' 110 | if typ == 'web': 111 | key = f'http://{key}/' 112 | print(f' {label:<15} {key}') 113 | 114 | hostname = docker_hostname 115 | print(f'\nOR Connect to HBase on container {hostname} at these endpoints') 116 | for cfg in CONFIG: 117 | (label, port, typ) = cfg 118 | 119 | key = f'{hostname}:{port}' 120 | if typ == 'web': 121 | key = f'http://{key}/' 122 | print(' {0:<15s} {1:s}'.format(label, key)) 123 | 124 | print('\nFor docker status:') 125 | print(f'$ id={container_id}') 126 | print('$ docker inspect $id') 127 | 128 | 129 | if __name__ == '__main__': 130 | main() 131 | -------------------------------------------------------------------------------- /start-hbase.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # Script to start docker and update the /etc/hosts file to point to 4 | # the hbase-docker container 5 | # 6 | # hbase thrift and master server logs are written to the local 7 | # logs directory 8 | # 9 | 10 | IMAGE_NAME="dajobe/hbase" 11 | CONTAINER_NAME="hbase-docker" 12 | 13 | program=$(basename "$0") 14 | 15 | echo "$program: Starting HBase container" 16 | data_dir="$PWD/data" 17 | rm -rf "$data_dir" 18 | mkdir -p "$data_dir" 19 | 20 | # force kill any existing container 21 | docker rm -f "${CONTAINER_NAME}" >/dev/null 22 | 23 | id=$(docker run --name=${CONTAINER_NAME} -h ${CONTAINER_NAME} -d -P -v "$data_dir:/data" "$IMAGE_NAME") 24 | 25 | echo "$program: Container has ID $id" 26 | 27 | # Get the hostname and IP inside the container 28 | docker inspect "$id" > config.json 29 | 30 | trap "rm -f config.json; exit 0" INT QUIT 31 | 32 | docker_hostname=$(python -c 'from __future__ import print_function; import json; c=json.load(open("config.json")); print(c[0]["Config"]["Hostname"])') 33 | docker_ip=$(python -c 'from __future__ import print_function; import json; c=json.load(open("config.json")); print(c[0]["NetworkSettings"]["IPAddress"])') 34 | 35 | hosts_hbase_docker_ip=$(awk "{if(\$2 == \"${docker_hostname}\") { print \$1 }}" /etc/hosts) 36 | if [ "$hosts_hbase_docker_ip" == "$docker_ip" ]; then 37 | echo "$program: /etc/hosts already contains ${docker_hostname} hostname and IP" 38 | else 39 | echo "$program: Updating /etc/hosts to make ${docker_hostname} point to $docker_ip ($docker_hostname)" 40 | echo "$program: Running sudo - expect to type your password" 41 | if [ "$hosts_hbase_docker_ip" == "" ]; then 42 | echo "docker_ip ${CONTAINER_NAME} $docker_hostname" | \ 43 | sudo tee -a /etc/hosts > /dev/null 44 | else 45 | sudo sed -i.bak "s/^.*${CONTAINER_NAME}.*\$/$docker_ip ${CONTAINER_NAME} $docker_hostname/" /etc/hosts 46 | fi 47 | fi 48 | 49 | declare -a config=( 50 | "REST API@8080@api" 51 | "REST UI@8085@web" 52 | "Thrift API@9090@api" 53 | "Thrift UI@9095@web" 54 | "Zookeeper API@2181@api" 55 | "Master UI@16010@web" 56 | ) 57 | 58 | echo "$program: Connect to HBase at localhost on these ports" 59 | for config_data in "${config[@]}"; do 60 | IFS=@ read -r label port type <<< "$config_data" 61 | 62 | mapped_port=$(python -c "from __future__ import print_function; import json; c=json.load(open(\"config.json\")); print(c[0][\"NetworkSettings\"][\"Ports\"][\"${port}/tcp\"][0][\"HostPort\"])") 63 | key="127.0.0.1:$mapped_port" 64 | if [ "$type" == "web" ]; then 65 | key="http://${key}/" 66 | fi 67 | printf " %-15s %s\n" "$label" "$key" 68 | done 69 | echo "" 70 | echo "$program: OR Connect to HBase on container ${docker_hostname}" 71 | for config_data in "${config[@]}"; do 72 | IFS=@ read -r label port type <<< "$config_data" 73 | 74 | key="${docker_hostname}:$port" 75 | if [ "$type" == "web" ]; then 76 | key="http://${key}/" 77 | fi 78 | printf " %-15s %s\n" "$label" "$key" 79 | done 80 | echo "" 81 | echo "$program: For docker status:" 82 | echo "$program: $ id=$id" 83 | echo "$program: $ docker inspect \$id" 84 | -------------------------------------------------------------------------------- /test_hbase.py: -------------------------------------------------------------------------------- 1 | # https://happybase.readthedocs.org/en/latest/ 2 | # https://github.com/wbolster/happybase 3 | import happybase 4 | 5 | def main(): 6 | HOST='hbase-docker' 7 | PORT=9090 8 | # Will create and then delete this table 9 | TABLE_NAME='table-name' 10 | ROW_KEY='row-key' 11 | 12 | connection = happybase.Connection(HOST, PORT) 13 | 14 | tables = connection.tables() 15 | print "HBase has tables {0}".format(tables) 16 | 17 | if TABLE_NAME not in tables: 18 | print "Creating table {0}".format(TABLE_NAME) 19 | connection.create_table(TABLE_NAME, { 'family': dict() } ) 20 | 21 | 22 | table = connection.table(TABLE_NAME) 23 | 24 | print "Storing values with row key '{0}'".format(ROW_KEY) 25 | table.put(ROW_KEY, {'family:qual1': 'value1', 26 | 'family:qual2': 'value2'}) 27 | 28 | print "Getting values for row key '{0}'".format(ROW_KEY) 29 | row = table.row(ROW_KEY) 30 | print row['family:qual1'] 31 | 32 | print "Printing rows with keys '{0}' and row-key-2".format(ROW_KEY) 33 | for key, data in table.rows([ROW_KEY, 'row-key-2']): 34 | print key, data 35 | 36 | print "Scanning rows with prefix 'row'" 37 | for key, data in table.scan(row_prefix='row'): 38 | print key, data # prints 'value1' and 'value2' 39 | 40 | print "Deleting row '{0}'".format(ROW_KEY) 41 | row = table.delete(ROW_KEY) 42 | 43 | print "Deleting table {0}".format(TABLE_NAME) 44 | connection.delete_table(TABLE_NAME, disable=True) 45 | 46 | if __name__ == "__main__": 47 | main() 48 | -------------------------------------------------------------------------------- /zoo.cfg: -------------------------------------------------------------------------------- 1 | clientPort=2181 2 | clientPortAddress=hbase-docker 3 | server.1=hbase-docker:2181 4 | --------------------------------------------------------------------------------