Doris数据库编译、容器化及踩坑

Doris目前被我们拿来给Tidb减轻压力,主要是两个用途

  1. 把大数据相关组件生成的的超大中间表从Tidb转移到Doris
  2. 定时同步线上的大表到Doris相当于一个只读库。这样大数据相关组件可以在只更改数据源情况下,将批量读写操作都放在Doris从而把Tidb还给业务

这里记录以下编译和容器化中的坑,以及如果要在容器中使用可以直接用现成的镜像febe,文章也可以跳过编译进入启动,编译还是挺慢的

以下内容基于当前(2021-02-02)的最新版(0.13.0),可能不适用于之后的版本

编译

参照最新版本的教程使用docker编译

可以在此基础上构建一个新的镜像,修改一些配置来加速fe的打包

Dockerfile

1
2
3
4
5
6
7
8
9
FROM apachedoris/doris-dev:build-env-1.2 AS builder

ARG APP_NAME

ENV APP_NAME=${APP_NAME}

COPY package/output.sh /tmp/output.sh
COPY package/settings.xml /root/.m2/settings.xml
COPY package/$APP_NAME.src.tar.gz /src/$APP_NAME.src.tar.gz

output.sh

这里是就是使用了官方的build.sh来进行编译

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env bash

DORIS_HOME=/tmp/$APP_NAME

mkdir -p /src/${APP_NAME} && cd /src/${APP_NAME} &&
tar -xzf /src/${APP_NAME}.src.tar.gz --strip-components=1 &&
sh build.sh &&
mv -u /src/${APP_NAME}/output/* /tmp/${APP_NAME} &&
chmod +x /tmp/${APP_NAME}/fe/bin/*.sh &&
chmod +x /tmp/${APP_NAME}/be/bin/*.sh

chown -R 1000:1000 ${DORIS_HOME}

settings.xml

主要是为了处理fe的一些仓库无法使用,并使用国内镜像加速

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

<mirrors>
<mirror>
<id>aliyun</id>
<name>Aliyun Maven Central</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>spring-plugins</id>
<name>Spring Plugins Central</name>
<url>https://maven.aliyun.com/repository/spring-plugin</url>
<mirrorOf>spring-plugins</mirrorOf>
</mirror>
<mirror>
<id>cloudera-plugins</id>
<name>Cloudera Plugins Central</name>
<url>https://repository.cloudera.com/artifactory/libs-release-local</url>
<mirrorOf>cloudera-plugins</mirrorOf>
</mirror>
<mirror>
<id>cloudera-thirdparty</id>
<name>Cloudera Thirdparty Central</name>
<url>https://repository.cloudera.com/artifactory/ext-release-local</url>
<mirrorOf>cloudera-thirdparty</mirrorOf>
</mirror>
</mirrors>
</settings>

build.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
APP='doris'
NAME='apache-doris'
VERSION=0.13.0

# 打包镜像
docker build \
--build-arg APP_NAME=${APP} \
-t dneht/${NAME}-dist:${VERSION}

# 开始编译并输出到本机目录
docker run -it --rm \
-v 本机目录:/tmp/${APP} \
dneht/${NAME}-dist:${VERSION} bash /tmp/output.sh

启动

注意,doris只记录解析后的ip,所以无论是fe还是be最好都使用hostNetwork

fe

fe使用StatefulSet,需要首先把副本数设置为1,先启动一个follower作为master

然后使用mysql或者sequel之类的登陆,默认无密码(设置密码后较新的mysql可能无法连接,请使用5.1.x的版本)添加新的fe

ALTER SYSTEM ADD FOLLOWER “host:edit_log_port”;

推荐3-5个follower,起的fe均作为observer

ALTER SYSTEM ADD OBSERVER “host:edit_log_port”;

如果是多网卡且同网段,选定的ip和请求master的ip不一致,同样会导致无法添加新的follower,此时需要添加请求ip作为follower,等待添加成功后drop掉

ALTER SYSTEM ADD FOLLOWER “req_ip:edit_log_port”;

最后修改StatefulSet添加环境变量,并调整副本数,使后来的follower使用--helper

1
2
3
4
{
"name": "DORIS_MASTER_HOST",
"value": "master_ip"
}

具体逻辑在entrypoint.sh

1
2
3
4
5
START_HELPER=""
if [[ ! -f "${DORIS_META_DIR}/image/ROLE" ]] && [[ -n "${DORIS_MASTER_HOST}" ]]; then
START_HELPER="${DORIS_MASTER_HOST}:${EDIT_LOG_PORT}"
echo "start doris fe with helper: ${START_HELPER}"
fi

这里也比较麻烦,因为配置修改,可能会重启第一个pod,重启之后master会发生变更从而导致ALTER SYSTEM语句无法使用,此时查询新的master并重新登陆

SHOW PROC ‘/frontends’;

be

be使用Deployment,如果使用多个目录目前最好的解决方案就是hostPath

添加同上,登陆fe添加所有要使用的机器

ALTER SYSTEM ADD BACKEND “host:heartbeat_service_port”;

在容器里启动be可能会有一个大坑:配置检查无误,直接在本机测试无问题,但k8s无论如何都启动不起来(我们k8s里使用的是containerd),最终通过日志定位问题及排查源码发现了问题

我们每台机器挂了3个盘,报错的日志如下

1
W0218 18:15:09.108532    99 storage_engine.cpp:162] _init_store_map failed, error: Internal error: init path failed, error=IO error: setmntent file /data/sdd failed, err=No such file or directory;IO error: setmntent file /data/sde failed, err=No such file or directory;IO error: setmntent file /data/sdf failed, err=No such file or directory;

olap/data_dir.cpp中有对kMtabPath即/etc/mtab的读取

1
2
3
4
5
6
if ((mount_tablet = setmntent(kMtabPath, "r")) == NULL) {
RETURN_NOT_OK_STATUS_WITH_WARN(
Status::IOError(strings::Substitute("setmntent file $0 failed, err=$1", _path,
errno_to_string(errno))),
"setmntent file failed");
}

而在containerd中不存在这个文件,容器环境下使用/proc/self/mounts,简单的添加个链接即可

1
2
3
if [[ ! -f /etc/mtab ]]; then
ln -s /proc/self/mounts /etc/mtab
fi

以上配置和踩坑在entrypoint.sh中都有体现


Doris数据库编译、容器化及踩坑
https://back.pub/post/doris-runin-container/
作者
Dash
发布于
2021年2月2日
许可协议