kudu环境搭建和基本使用(centos-7)
注:本文只记录kudu的安装,不涉及其它工具或组件
一、前言
安装 kudu有多种方式,本文介绍使用yum源在线安装的方式(kudu不像CM那样安装包很大,在线安装不会有什么问题)。博主当前准备四个节点:192.168.0.198、192.168.0.210、192.168.0.211、192.168.0.212。
现做如下规划(tserver节点数量得是奇数):
节点 | 角色 |
192.168.0.198 | tserver |
192.168.0.210 | tserver |
192.168.0.211 | master |
192.168.0.212 | tserver |
我们先配置一个master节点,等安装完成后再演示一下如何扩展更多的master节点,正常情况master节点数量是要大于1的。
二、安装
2.1 环境准备
为了方便,直接将每台机器的hostname都设置为对应的ip,修改对应的/etc/hostname即可。
2.1 准备repo文件
根据服务器版本到http://archive.cloudera.com/kudu下载对应的cloudera-kudu.repo文件,博主当前环境为64位centos-7,所以下载的文件为:
http://archive.cloudera.com/kudu/redhat/7/x86_64/kudu/cloudera-kudu.repo
然后将下载的文件放到每台机器对应的源目录,不同的系统目录有差异,博主的centos环境对应的目录为:/etc/yum.repos.d
2.2 引入 RPM-GPG-KEY
这个key用于验证软件版权,在每台机器上执行以下命令即可引入(url参照2.1步骤repo文件的路径):
>sudo rpm --import https://archive.cloudera.com/kudu/redhat/7/x86_64/kudu/RPM-GPG-KEY-cloudera
2.3 安装
注:在安装开始之前,我们要规划好哪些机器用作master节点,哪些机器用作tserver节点,当然前面已经做了说明。
首先要在集群中的每台机器上都安装kudu公共组件:
>yum -y install kudu
2.3.1 安装kudu-master
在master机器(192.168.0.211)上安装kudu-master:
>yum -y install kudu-master
安装完成之后,会自动在/etc/kudu/conf目录生成master对应的配置文件:master.gflagfile,内容如下(更多配置项可以参考官方文档):
# Do not modify these two lines. If you wish to change these variables,
# modify them in /etc/default/kudu-master.
--fromenv=rpc_bind_addresses
--fromenv=log_dir
--fs_wal_dir=/var/lib/kudu/master
--fs_data_dirs=/var/lib/kudu/master
# 当前只有一个节点,暂时可以不用配置
--master_addresses=192.168.0.211:7051
文件内容中有清晰的注释,--fromenv配置来源于:/etc/default/kudu-master,如果要修改该配置,不要直接在gflagfile中修改,更新kudu-master文件即可,我修改了rpc_bind_addresses为本机ip+7051:
export FLAGS_log_dir=/var/log/kudu
export FLAGS_rpc_bind_addresses=192.168.0.211:7051
2.3.2 安装kudu-tserver
在tserver机器(192.168.0.198,192.168.0.210,192.168.0.212)上安装kudu-tserver,流程和安装master类似:
>yum -y install kudu-tserver
安装完成之后,也会在/etc/kudu/conf目录生成tserver对应的配置文件:tserver.gflagfile,稍作修改,内容如下:
# Do not modify these two lines. If you wish to change these variables,
# modify them in /etc/default/kudu-tserver.
--fromenv=rpc_bind_addresses
--fromenv=log_dir
--fs_wal_dir=/var/lib/kudu/tserver
--fs_data_dirs=/var/lib/kudu/tserver
# master节点地址,逗号分隔,就是master中的FLAGS_rpc_bind_addresses配置
# 我们当前只有一个master节点
--tserver_master_addrs=192.168.0.211:7051
和master节点类似,--fromenv参数依赖/etc/default/kudu-tserver文件,如果需要更新,修改该文件即可(ip为本机ip):
export FLAGS_log_dir=/var/log/kudu
export FLAGS_rpc_bind_addresses=192.168.0.198:7050
博主当前有三个tserver节点,所以在192.168.0.212和192.168.0.210节点上重复该步骤即可。
注:kudu-client0和kudu-client-devel并不是必须的,如果需要C++客户端开发库或者kudu SDK,则需要安装,安装比较简单,直接在节点上执行以下命令即可:
>yum -y install kudu-client0
>yum -y install kudu-client-devel
2.4 配置服务自动启动(可选)
master节点:
>chkconfig kudu-master on
tserver节点:
>chkconfig kudu-tserver on
2.5 启动服务
master节点:
>systemctl start kudu-master
tserver节点:
>systemctl start kudu-tserver
三、验证
通过ps命令可以查看是否启动成功:
master节点:
tserver节点:
如果没有启动成功,查看对应的日志输出即可,默认日志目录为:/var/log/kudu
启动成功后,可以通过浏览器进入对应的UI界面:
master地址为: <hostName>:8051,博主的环境为:192.168.0.211:8051,界面显示如下:
上面显示了基本的版本信息,kudu版本为1.4。
tserver地址为:<hostName>:8050,我们进入:192.168.0.198:8050,界面显示如下:
当然,端口信息,包括用户名和密码等等都是可以配置的。
四、扩展master节点(停机)
我们目前只有一个192.168.0.211作为master节点,现在将192.168.0.210节点扩展为master节点。
4.1 首先停止集群中的所有kudu服务
>systemctl stop kudu-master
>systemctl stop kudu-tserver
4.2 安装kudu-master
这个上面已经介绍过了,我们在新节点192.168.0.210上执行 yum -y install kudu-master即可,安装完毕之后会在对应的目录生成好默认配置文件。
4.3 初始化新节点的 fs_wal_dir
在新节点192.168.0.210上执行以下命令初始化目录:
>kudu fs format --fs_wal_dir=<master_data_dir>
其中master_data_dir默认为/var/lib/kudu/master,如果自定义了新路径,照着修改就行。当前环境直接执行:
>kudu fs format --fs_wal_dir=/var/lib/kudu/master
执行该命令后,会初始化好标准的/var/lib/kudu/master目录:
注:consensus-meta目录初始为空,在我们后面的步骤处理。
初始化好之后我们需要获取一个标识master节点的uuid,将其记录下来,后面会使用,使用以下命令输出uuid:
>kudu fs dump uuid --fs_wal_dir=<master_data_dir> 2>/dev/null
其中的master_data_dir和前一个步骤一样,输出示例如下:
注:需要记录每个master节点的uuid,我们的环境就是192.168.0.211和192.168.0.210两个节点,命令都是一样的
4.4 更新raft配置
更新配置用到的命令(在非新的master节点上执行,当前为192.168.0.211)如下:
>kudu local_replica cmeta rewrite_raft_config --fs_wal_dir=<master_data_dir> <tablet_id> <all_masters>
其中:
fs_wal_dir:和前面命令提到的一样,默认为/var/lib/kudu/master;
tablet_id:固定为00000000000000000000000000000000
(32个0);
all_masters:为扩展之后的所有master节点列表,格式为uuid:ip:port,多个节点空格分隔,uuid就是我们前面记录下来的数据。
在我们的环境中,命令是这样的:
>kudu local_replica cmeta rewrite_raft_config --fs_wal_dir=/var/lib/kudu/master 00000000000000000000000000000000 a3f3fb4e7aba4f559bae12f6aa50a96a:192.168.0.211:7051 453df4dcbb2d41c7b672e2cef99c6c45:192.168.0.210:7051
执行该命令后,/var/lib/kudu/master/consensus-meta/目录会生成一个新的00000000000000000000000000000000
文件,
同时之前的文件会添加.pre_rewrite.timestamp后缀作为一个备份:
4.5 同步配置
将上述步骤生成的新的00000000000000000000000000000000文件拷贝到其它机器上,kudu提供了copy_from_remote指令,由于我暂时没有去配置免密登录,所有直接使用scp命令,将192.168.0.211最新的00000000000000000000000000000000文件发送到新的节点192.168.0.210:
>cd /var/lib/kudu/master/consensus-meta
>scp 00000000000000000000000000000000 aaa@qq.com:/var/lib/kudu/master/consensus-meta
在192.168.0.210节点确认文件:
但是这样生成的00000000000000000000000000000000文件不归kudu:kudu用户所有,在启动的时候可能会出现Permission denied (error 13)的异常信息,所以我们修改00000000000000000000000000000000文件的归属:
>chown -R kudu:kudu /var/lib/kudu/master/consensus-meta00000000000000000000000000000000
最后,新旧节点(192.168.0.210和192.168.0.211)的配置文件:master.gflagfile也都要完整配置master节点列表:
# Do not modify these two lines. If you wish to change these variables,
# modify them in /etc/default/kudu-master.
--fromenv=rpc_bind_addresses
--fromenv=log_dir
--fs_wal_dir=/var/lib/kudu/master
--fs_data_dirs=/var/lib/kudu/master
# 现在是两个master节点
--master_addresses=192.168.0.211:7051,192.168.0.210:7051
到这里master扩展已经完成了,我们还需要修改所有tserver节点的tserver.gflagfile文件的tserver_master_addrs配置,增加新的master节点192.168.0.210,以190.168.0.210为例(210也是一个tserver节点):
--fromenv=rpc_bind_addresses
--fromenv=log_dir
--fs_wal_dir=/var/lib/kudu/tserver
--fs_data_dirs=/var/lib/kudu/tserver
# 增加192.168.0.210节点
--tserver_master_addrs=192.168.0.211:7051,192.168.0.210:7051
在192.168.0.198和192.168.0.212节点做出同样修改即可。现在我们的210节点同时充当master和tserver的角色。
4.6 验证
重新启动所有master和tserver节点,进入WEB页面查看状态信息,首先查看master信息:
我们看到,已经有两个master节点了,210为leader,211为follower。
查看tablets信息:
我们看到,有三个tserver节点,分别为198、210、212。
4.7 总结
整个新增master节点的步骤可以简单归纳为:
>1.新节点安装kudu-master
>2.在旧节点使用kudu提供的命令更新00000000000000000000000000000000文件
>3.同步最新的00000000000000000000000000000000文件到其它master节点(修改文件权限)
>4.修改每个master节点的master.gflagfile,完善--master_addresses配置
>5.修改每个tserver节点的tserver.gflagfile文件,完善--tserver_master_addrs配置
>6.启动
五、使用
这里简单使用java操作一下kudu,代码来源于github:kudu/examples。
import java.util.ArrayList;
import java.util.List;
import org.apache.kudu.ColumnSchema;
import org.apache.kudu.Schema;
import org.apache.kudu.Type;
import org.apache.kudu.client.*;
/**
* Author huangzhilin
* Date 2019/5/14
*/
public class Example {
private static final String KUDU_MASTERS = "192.168.0.211:7051,192.168.0.210:7051";
static void createExampleTable(KuduClient client, String tableName) throws KuduException {
// Set up a simple schema.
List<ColumnSchema> columns = new ArrayList<>(2);
columns.add(new ColumnSchema.ColumnSchemaBuilder("key", Type.INT32)
.key(true)
.build());
columns.add(new ColumnSchema.ColumnSchemaBuilder("value", Type.STRING).nullable(true)
.build());
Schema schema = new Schema(columns);
// Set up the partition schema, which distributes rows to different tablets by hash.
// Kudu also supports partitioning by key range. Hash and range partitioning can be combined.
// For more information, see http://kudu.apache.org/docs/schema_design.html.
CreateTableOptions cto = new CreateTableOptions();
List<String> hashKeys = new ArrayList<>(1);
hashKeys.add("key");
int numBuckets = 2;
cto.addHashPartitions(hashKeys, numBuckets);
// Create the table.
client.createTable(tableName, schema, cto);
System.out.println("Created table " + tableName);
}
static void insertRows(KuduClient client, String tableName, int numRows) throws KuduException {
// Open the newly-created table and create a KuduSession.
KuduTable table = client.openTable(tableName);
KuduSession session = client.newSession();
for (int i = 0; i < numRows; i++) {
Insert insert = table.newInsert();
PartialRow row = insert.getRow();
row.addInt("key", i);
// Make even-keyed row have a null 'value'.
if (i % 2 == 0) {
row.setNull("value");
} else {
row.addString("value", "value " + i);
}
session.apply(insert);
}
// Call session.close() to end the session and ensure the rows are
// flushed and errors are returned.
// You can also call session.flush() to do the same without ending the session.
// When flushing in AUTO_FLUSH_BACKGROUND mode (the default mode recommended
// for most workloads, you must check the pending errors as shown below, since
// write operations are flushed to Kudu in background threads.
session.close();
if (session.countPendingErrors() != 0) {
System.out.println("errors inserting rows");
org.apache.kudu.client.RowErrorsAndOverflowStatus roStatus = session.getPendingErrors();
org.apache.kudu.client.RowError[] errs = roStatus.getRowErrors();
int numErrs = Math.min(errs.length, 5);
System.out.println("there were errors inserting rows to Kudu");
System.out.println("the first few errors follow:");
for (int i = 0; i < numErrs; i++) {
System.out.println(errs[i]);
}
if (roStatus.isOverflowed()) {
System.out.println("error buffer overflowed: some errors were discarded");
}
throw new RuntimeException("error inserting rows to Kudu");
}
System.out.println("Inserted " + numRows + " rows");
}
public static void main(String[] args) {
System.out.println("-----------------------------------------------");
System.out.println("Will try to connect to Kudu master(s) at " + KUDU_MASTERS);
System.out.println("Run with -DkuduMasters=master-0:port,master-1:port,... to override.");
System.out.println("-----------------------------------------------");
String tableName = "java_example-" + System.currentTimeMillis();
KuduClient client = new KuduClient.KuduClientBuilder(KUDU_MASTERS).build();
try {
createExampleTable(client, tableName);
int numRows = 150;
insertRows(client, tableName, numRows);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
client.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
上述代码创建了一个table,设置的2个分区,并且插入了150条数据。
这里要注意一点,使用的kudu-client版本最好和集群版本一致,不然可能会出现各种异常情况,我们当前安装的是1.4的kudu。
创建成功之后,进入tables标签查看:
我们已经能看到该表了, 表名为java_example-1557818213749,并且有个tableId,点进去可以看到该table的详细信息:
参考:
https://www.cloudera.com/documentation/kudu/5-12-x/topics/kudu_installation.html