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 [email protected]:/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

https://github.com/cloudera/kudu/tree/master/examples

猜你喜欢

转载自blog.csdn.net/huangzhilin2015/article/details/90177988