tencent cloud

Dual-Active Instance Development Guide
Last updated:2025-07-15 11:07:57
Dual-Active Instance Development Guide
Last updated: 2025-07-15 11:07:57

Application Scenario

Use Java to access the EMR Serverless HBase Dual-Active instances through the high-availability client (hbase-ha-client) and perform operations, including table creation and queries.

Preparations

1. The EMR Serverless HBase Dual-Active instances have been created and are in the running status.
2. A CVM instance that is sharing the same VPC and same subnet with the EMR Serverless HBase Dual-Active instances has been created (hereinafter referred to as the CVM client).
3. The Java environment has been installed, and environment variables have been configured on the CVM client. A JDK version 1.8 or later can be installed as required. If it is not installed, visit https://tencent.github.io/konajdk/.
4. The ZooKeeper addresses of the Serverless HBase primary and secondary instances have been obtained on the EMR Serverless HBase primary/secondary Dual-Active instances information page.
Note:
To learn more information about HBase API usage, visit the official website of Apache HBase.

Directions

Settings.xml Configuration

Ensure that an appropriate JDK version is available in the development environment, and install and configure the Maven environment variables. If you are using an IDE, set the Maven-related configurations in the IDE. If needed, use the Tencent Cloud image source to accelerate Maven, and add the following repository mirror and profile to the Maven configuration file settings.xml.
<mirror>
<id>nexus-tencentyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus tencentyun</name>
<url>http://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
</mirror>
<profiles>
<profile>
<id>Repository Proxy</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>tencentemr-hbase-ha-client-releases</id>
<name>releases</name>
<url>https://tencentemr-maven.pkg.coding.net/repository/hbase-ha-client/releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>

Creating a Maven Project

Go to the directory where you want to create the project on the command line and enter the following command to create a Maven project.
mvn archetype:generate -DgroupId=com.tencent.cloud -DartifactId=test-serverless-hbase -Dversion=1.0 -DarchetypeArtifactId=maven-archetype-quickstart
After successful creation, a project folder named test-serverless-hbase will be generated in the project directory. The file structure within is as follows. The pom.xml file is mainly used for dependency management and packaging configurations, while the Java folder contains your source code.
test-hbase
├── pom.xml
└── src
├── main
│ └── java
│ └── com
│ └── tencent
│ └── cloud
│ └── App.java
└── test
└── java
└── com
└── tencent
└── cloud
└── AppTest.java

Adding Configurations and Sample Code

Add Maven dependency, packaging, and compilation plugins in the pom.xml file.
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.hbase/hbase-client -->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>com.tencentcloud.emr</groupId>
<artifactId>hbase-ha-client</artifactId>
<version>1.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<!-- Specify the class for the main method entry here -->
<mainClass>com.tencent.cloud.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

[Optional] If you encounter sample execution failures during subsequent debugging and need to obtain logs from standard output to pinpoint errors, or if you want to save operation logs to the specified directory target/serverless-hbase.log, you can create a Java configuration file directory named resources under the main folder, create a log4j.properties file within it, and add configuration details for the log4j log information printing module in the log4j.properties file.
log4j.rootLogger=INFO, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/serverless-hbase.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
The sample code in App.java is as follows.
package com.tencent.cloud;

import com.tencentcloud.emr.HAConnection;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

import static org.apache.hadoop.hbase.HConstants.REPLICATION_SCOPE_GLOBAL;

/**
* Access the Serverless HBase Dual-Active instances through the Java API.
*/
public class App {
public static void main(String[] args) throws IOException {
// $quorum and $standbyQuorum are the ZooKeeper addresses of the primary and secondary instances, respectively. They can be obtained from the ZooKeeper addresses found in the access method module under the instance information page of the console.
// Example: conf.set("hbase.zookeeper.quorum", "10.0.0.8,10.0.0.11,10.0.0.5");
// Example: conf.set("hbase.zookeeper.quorum.standby", "10.0.0.21,10.0.0.22,10.0.0.24");
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "$quorum");
conf.set("hbase.zookeeper.quorum.standby", "$standbyQuorum");

// hbase.client.pause specifies the client retry interval in milliseconds, with a default value of 100 milliseconds.
// hbase.client.retries.number specifies the number of client retries; the default is 15 times.
// After the maximum number of request retries for the same instance is reached, it will automatically switch to the secondary instance for retries. After the maximum number of request retries for both instances is reached , an error will be returned.
conf.setInt("hbase.client.pause", 10);
conf.setInt("hbase.client.retries.number", 5);

HAConnection connection;
connection = new HAConnection(conf);

Admin admin = connection.getAdmin();

String TABLE_NAME = "test1";
String COLUMN_FAMILY = "cf";

TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(TableName.valueOf(TABLE_NAME));
// Set global replication.
tableDescriptorBuilder.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(COLUMN_FAMILY)).setScope(REPLICATION_SCOPE_GLOBAL).build());
TableDescriptor tableDescriptor = tableDescriptorBuilder.build();

System.out.println("Creating table. ");
if (admin.tableExists(tableDescriptor.getTableName())) {
admin.disableTable(tableDescriptor.getTableName());
admin.deleteTable(tableDescriptor.getTableName());
}
admin.createTable(tableDescriptor);

System.out.println("Put data. ");
Table table1 = connection.getTable(TableName.valueOf(TABLE_NAME));
Put put1 = new Put(Bytes.toBytes("row1"));
put1.addColumn(Bytes.toBytes(COLUMN_FAMILY), Bytes.toBytes("a"),
Bytes.toBytes("value1"));
table1.put(put1);
Put put2 = new Put(Bytes.toBytes("row2"));
put2.addColumn(Bytes.toBytes(COLUMN_FAMILY), Bytes.toBytes("b"),
Bytes.toBytes("value2"));
table1.put(put2);
Put put3 = new Put(Bytes.toBytes("row3"));
put3.addColumn(Bytes.toBytes(COLUMN_FAMILY), Bytes.toBytes("c"),
Bytes.toBytes("value3"));
table1.put(put3);

System.out.println("Get data. ");
Get get1 = new Get(Bytes.toBytes("row1"));
Result row = table1.get(get1);
if (row.isEmpty()) {
System.out.println("No row data found");
return;
}
System.out.println("Row key: " + Bytes.toString(row.getRow()));
byte[] value = row.getValue(Bytes.toBytes(COLUMN_FAMILY), Bytes.toBytes("a"));
if (value != null) {
System.out.println("Value: " + Bytes.toString(value));
}

connection.close();

System.out.println(" Done.");
}
}

Compiling and Packaging Code for Upload

Use the local command line to go to the project directory and execute the following command to compile and package the project.
mvn package
The log printing build success indicates that the operation was successful. You can find the packaged JAR file in the target folder of the project directory. You need to upload the JAR package with the with-dependencies suffix to the CVM client using the file upload feature in the CVM instance console.
If the CVM client can be accessed via the public network IP address, you can also run the following command in the local command line mode to upload the file.
Scp $localfile root@public network IP address:$remotefolder
Here, $localfile is the path and the name of your local file; root is the username of the CVM server. You can look up the public network IP address in the CVM client console. $remotefolder is the path where you want to store the file in the CVM server. After completing the upload, you can check whether the file is in the corresponding folder on the CVM client command line.

Executing the Sample and Checking the Results

Log in to the CVM client, switch to the corresponding folder, and use the following command to execute the sample.
java -jar $package.jar
After executing the code, if "Done" is output in the console, it indicates that all operations are completed. You can switch to the HBase shell and use the list command to check if the HBase tables created using the API are successful on both the primary and secondary instances. If successful, you can use the scan command to view the specific contents of the tables.
hbase:001:0> list 'test1'
TABLE
test1
1 row(s)
Took 0.4315 seconds
=> ["test1"]
hbase:002:0> scan 'test1'
ROW COLUMN+CELL
row1 column=cf:a, timestamp=2024-07-16T16:20:38.685, value=value1
row2 column=cf:b, timestamp=2024-07-16T16:20:38.690, value=value2
row3 column=cf:c, timestamp=2024-07-16T16:20:38.695, value=value3
3 row(s)
Took 0.1231 seconds
hbase:003:0> exit
Was this page helpful?
You can also Contact Sales or Submit a Ticket for help.
Yes
No

Feedback