欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

kudu环境搭建和基本使用(centos-7)

程序员文章站 2022-04-29 08:07:31
...

注:本文只记录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节点:

kudu环境搭建和基本使用(centos-7)

tserver节点:

kudu环境搭建和基本使用(centos-7)

如果没有启动成功,查看对应的日志输出即可,默认日志目录为:/var/log/kudu

启动成功后,可以通过浏览器进入对应的UI界面:

master地址为: <hostName>:8051,博主的环境为:192.168.0.211:8051,界面显示如下:

kudu环境搭建和基本使用(centos-7)

上面显示了基本的版本信息,kudu版本为1.4。

tserver地址为:<hostName>:8050,我们进入:192.168.0.198:8050,界面显示如下:

kudu环境搭建和基本使用(centos-7)

当然,端口信息,包括用户名和密码等等都是可以配置的。

四、扩展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目录:

kudu环境搭建和基本使用(centos-7)

注:consensus-meta目录初始为空,在我们后面的步骤处理。

初始化好之后我们需要获取一个标识master节点的uuid,将其记录下来,后面会使用,使用以下命令输出uuid:

>kudu fs dump uuid --fs_wal_dir=<master_data_dir> 2>/dev/null

其中的master_data_dir和前一个步骤一样,输出示例如下:

kudu环境搭建和基本使用(centos-7)

注:需要记录每个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后缀作为一个备份:

kudu环境搭建和基本使用(centos-7)

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节点确认文件:

kudu环境搭建和基本使用(centos-7)

但是这样生成的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信息:

kudu环境搭建和基本使用(centos-7)

我们看到,已经有两个master节点了,210为leader,211为follower。

查看tablets信息:

kudu环境搭建和基本使用(centos-7)

我们看到,有三个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标签查看:

kudu环境搭建和基本使用(centos-7)

我们已经能看到该表了, 表名为java_example-1557818213749,并且有个tableId,点进去可以看到该table的详细信息:

kudu环境搭建和基本使用(centos-7)

参考:

https://www.cloudera.com/documentation/kudu/5-12-x/topics/kudu_installation.html

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