本站总访问量 doris单节点搭建 - Jerry的小站

Jerry Gao

上帝就是真理,真理就是上帝

Apache Doris 是基于 MPP 架构的新一代开源实时数据仓库,使用更简便,性能更高,适用于大数据分析。

doris 文档

构建镜像

Doris BE

目录结构:

1
2
3
4
5
.
├── Dockerfile
└── resource
├── apache-doris-be-1.1.4-bin-x86_64.tar.gz
└── init_be.sh
  1. 下载文件
1
wget https://archive.apache.org/dist/doris/1.1/1.1.4-rc01/apache-doris-be-1.1.4-bin-x86_64.tar.gz
  1. 编写 Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 选择基础镜像
FROM openjdk:8u342-jdk

# 设置环境变量
ENV JAVA_HOME="/usr/local/openjdk-8/" \
PATH="/opt/apache-doris/be/bin:$PATH"

# 下载软件至镜像内,可根据需要替换
ADD resource/apache-doris-be-1.1.4-bin-x86_64.tar.gz /opt/

RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list && \
apt-get update && \
apt-get install -y default-mysql-client && \
apt-get clean && \
mkdir /opt/apache-doris && \
cd /opt && \
mv apache-doris-be-1.1.4-bin-x86_64 /opt/apache-doris/be

ADD resource/init_be.sh /opt/apache-doris/be/bin
RUN chmod 755 /opt/apache-doris/be/bin/init_be.sh

ENTRYPOINT ["/opt/apache-doris/be/bin/init_be.sh"]
  1. 编写 init_be.sh
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

FE_SERVERS=""
BE_ADDR=""

ARGS=$(getopt -o -h: --long fe_servers:,be_addr: -n "$0" -- "$@")

eval set -- "${ARGS}"

while [[ -n "$1" ]]; do
case "$1" in
--fe_servers)
FE_SERVERS=$2
shift
;;
--be_addr)
BE_ADDR=$2
shift
;;
--) ;;

*)
echo "Error option $1"
break
;;
esac
shift
done

#echo FE_SERVERS = $FE_SERVERS
echo "DEBUG >>>>>> FE_SERVERS=[${FE_SERVERS}]"
echo "DEBUG >>>>>> BE_ADDR=[${BE_ADDR}]"

feIpArray=()
feEditLogPortArray=()

IFS=","
# shellcheck disable=SC2206
feServerArray=(${FE_SERVERS})

for i in "${!feServerArray[@]}"; do
val=${feServerArray[i]}
val=${val// /}
tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, ""); print$1}')
tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$3}')
feIpArray[tmpFeId]=${tmpFeIp}
feEditLogPortArray[tmpFeId]=${tmpFeEditLogPort}
done

be_ip=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$1}')
be_heartbeat_port=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$2}')

echo "DEBUG >>>>>> feIpArray = ${feIpArray[*]}"
echo "DEBUG >>>>>> feEditLogPortArray = ${feEditLogPortArray[*]}"
echo "DEBUG >>>>>> masterFe = ${feIpArray[1]}:${feEditLogPortArray[1]}"
echo "DEBUG >>>>>> be_addr = ${be_ip}:${be_heartbeat_port}"

priority_networks=$(echo "${be_ip}" | awk -F '.' '{print$1"."$2"."$3".0/24"}')
echo "DEBUG >>>>>> Append the configuration [priority_networks = ${priority_networks}] to /opt/apache-doris/be/conf/fe.conf"
echo "priority_networks = ${priority_networks}" >>/opt/apache-doris/be/conf/be.conf

registerMySQL="mysql -uroot -P9030 -h${feIpArray[1]} -e \"alter system add backend '${be_ip}:${be_heartbeat_port}'\""
echo "DEBUG >>>>>> registerMySQL = ${registerMySQL}"

registerShell="/opt/apache-doris/be/bin/start_be.sh &"
echo "DEBUG >>>>>> registerShell = ${registerShell}"

for ((i = 0; i <= 20; i++)); do

## check be register status
echo "mysql -uroot -P9030 -h${feIpArray[1]} -e \"show backends\" | grep \" ${be_ip} \" | grep \" ${be_heartbeat_port} \""
mysql -uroot -P9030 -h"${feIpArray[1]}" -e "show backends" | grep "[[:space:]]${be_ip}[[:space:]]" | grep "[[:space:]]${be_heartbeat_port}[[:space:]]"
be_join_status=$?
echo "DEBUG >>>>>> The " "${i}" "time to register BE node, be_join_status=${be_join_status}"
if [[ "${be_join_status}" == 0 ]]; then
## be registe successfully
echo "DEBUG >>>>>> run command ${registerShell}"
eval "${registerShell}"
else
## be doesn't registe
echo "DEBUG >>>>>> run commnad ${registerMySQL}"
eval "${registerMySQL}"
if [[ "${i}" == 20 ]]; then
echo "DEBUG >>>>>> BE Start Or Register FAILED!"
fi
sleep 5
fi
done
  1. 构建镜像
1
docker build -t apache-doris-be:1.1.4 .

Doris FE

目录结构

1
2
3
4
5
.
├── Dockerfile
└── resource
├── apache-doris-fe-1.1.4-bin.tar.gz
└── init_fe.sh
  1. 下载资源
1
wget https://archive.apache.org/dist/doris/1.1/1.1.4-rc01/apache-doris-fe-1.1.4-bin.tar.gz
  1. 编写 Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 选择基础镜像
FROM openjdk:8u342-jdk

# 设置环境变量
ENV JAVA_HOME="/usr/local/openjdk-8/" \
PATH="/opt/apache-doris/fe/bin:$PATH"

# 下载软件至镜像内,可根据需要替换
ADD resource/apache-doris-fe-1.1.4-bin.tar.gz /opt/

RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list && \
apt-get update && \
apt-get install -y default-mysql-client && \
apt-get clean && \
mkdir /opt/apache-doris && \
cd /opt && \
mv apache-doris-fe-1.1.4-bin /opt/apache-doris/fe

ADD resource/init_fe.sh /opt/apache-doris/fe/bin
RUN chmod 755 /opt/apache-doris/fe/bin/init_fe.sh

CMD ["/opt/apache-doris/fe/bin/init_fe.sh"]
  1. 编写 init_fe.sh
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

FE_ID=0
FE_SERVERS=""

ARGS=$(getopt -o -h: --long fe_id:,fe_servers: -n "$0" -- "$@")

eval set -- "${ARGS}"

while [[ -n "$1" ]]; do
case "$1" in
--fe_id)
FE_ID=$2
shift
;;
--fe_servers)
FE_SERVERS=$2
shift
;;
--) ;;

*)
echo "Error option $1"
break
;;
esac
shift
done

echo "DEBUG >>>>>> FE_ID = [${FE_ID}]"
echo "DEBUG >>>>>> FE_SERVERS = [${FE_SERVERS}]"

feIpArray=()
feEditLogPortArray=()

IFS=","
# shellcheck disable=SC2206
feServerArray=(${FE_SERVERS})

for i in "${!feServerArray[@]}"; do

val=${feServerArray[i]}
val=${val// /}
tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, ""); print$1}')
tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$3}')
echo "DEBUG >>>>>> tmpFeId = [${tmpFeId}]"
echo "DEBUG >>>>>> tmpFeIp = [${tmpFeIp}]"
echo "DEBUG >>>>>> tmpFeEditLogPort = [${tmpFeEditLogPort}]"

feIpArray[tmpFeId]=${tmpFeIp}
feEditLogPortArray[tmpFeId]=${tmpFeEditLogPort}

done

echo

echo "DEBUG >>>>>> feIpArray = ${feIpArray[*]}"
echo "DEBUG >>>>>> feEditLogPortArray = ${feEditLogPortArray[*]}"
echo "DEBUG >>>>>> masterFe = ${feIpArray[1]}:${feEditLogPortArray[1]}"
echo "DEBUG >>>>>> currentFe = ${feIpArray[FE_ID]}:${feEditLogPortArray[FE_ID]}"

priority_networks=$(echo "${feIpArray[FE_ID]}" | awk -F '.' '{print$1"."$2"."$3".0/24"}')
echo "DEBUG >>>>>> Append the configuration [priority_networks = ${priority_networks}] to /opt/doris-fe/conf/fe.conf"
echo "priority_networks = ${priority_networks}" >>/opt/apache-doris/fe/conf/fe.conf

if [[ "${FE_ID}" != 1 ]]; then

## if current node is not master
## PREPARE1: registe follower from mysql client
## PREPARE2: call start_fe.sh using --help optional
## STEP1: check master fe service works
## STEP2: if feMasterStat == true; register PREPARE1 & PREPARE2 [retry 3 times, sleep 10s]

## PREPARE1: registe follower from mysql client
registerMySQL="mysql -uroot -P9030 -h${feIpArray[1]} -e \"alter system add follower '${feIpArray[FE_ID]}:${feEditLogPortArray[FE_ID]}'\""

## PREPARE2: call start_fe.sh using --help optional
registerShell="/opt/apache-doris/fe/bin/start_fe.sh --helper '${feIpArray[1]}:${feEditLogPortArray[1]}'"

echo "DEBUG >>>>>> FE is follower, fe_id = ${FE_ID}"
echo "DEBUG >>>>>> registerMySQL = 【${registerMySQL}】"
echo "DEBUG >>>>>> registerShell = 【${registerShell}】"
echo "DEBUG >>>>>> feMasterStat = 【mysql -uroot -P9030 -h ${feIpArray[1]} -e \"show frontends\" | grep \"${feIpArray[1]}_9010\" | grep -E \"true[[:space:]]*true\"】"

## STEP1: check FE master status

for ((i = 0; i <= 2000; i++)); do

## run STEP1 & STEP2, and then break
echo "Run registerShell command, [ registerMySQL = ${registerMySQL} ]"
eval "${registerMySQL}"
sleep 2

## followerJoined: Joined = 0, doesn't join = 1
mysql -uroot -P9030 -h"${feIpArray[1]}" -e "show frontends" | grep "${feIpArray[FE_ID]}_9010" | grep -E "false[[:space:]]*false"
followerJoined=$?

if [[ "${followerJoined}" == 0 ]]; then
echo "Run registerShell command, [ registerShell = ${registerShell} ]"
eval "${registerShell}"
echo "The resutl of run registerShell command, [ res = $? ]"
fi
sleep 5
done

else
registerShell="/opt/apache-doris/fe/bin/start_fe.sh"
eval "${registerShell}"
echo "DEBUG >>>>>> FE is master, fe_id = ${FE_ID}"
echo "DEBUG >>>>>> registerShell = ${registerShell}"
fi
  1. 构建镜像
1
docker build -t apache-doris-fe:1.19.0 .

Doris Broker

目录结构

1
2
3
4
5
.
├── Dockerfile
└── resource
├── apache_hdfs_broker.tar.gz
└── init_broker.sh
  1. 准备资源

可以从 这里 下载资源

  1. 编写 Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 选择基础镜像
FROM openjdk:8u342-jdk

# 设置环境变量
ENV JAVA_HOME="/usr/local/openjdk-8/" \
PATH="/opt/apache-doris/broker/bin:$PATH"

# 下载软件至镜像内,此处 broker 目录被同步压缩至 FE 的二进制包,需要自行解压重新打包,可根据需要替换
ADD resource/apache_hdfs_broker.tar.gz /opt/

RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list && \
apt-get update && \
apt-get install -y default-mysql-client && \
apt-get clean && \
mkdir /opt/apache-doris && \
cd /opt && \
mv apache_hdfs_broker /opt/apache-doris/broker

ADD resource/init_broker.sh /opt/apache-doris/broker/bin
RUN chmod 755 /opt/apache-doris/broker/bin/init_broker.sh

ENTRYPOINT ["/opt/apache-doris/broker/bin/init_broker.sh"]
  1. 编写 init_broker.sh
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

FE_SERVERS=""
BROKER_ADDR=""

ARGS=$(getopt -o -h: --long fe_servers:,broker_addr: -n "$0" -- "$@")

eval set -- "${ARGS}"

while [[ -n "$1" ]]; do
case "$1" in
--fe_servers)
FE_SERVERS=$2
shift
;;
--broker_addr)
BROKER_ADDR=$2
shift
;;
--) ;;

*)
echo "Error option $1"
break
;;
esac
shift
done

#echo FE_SERVERS = $FE_SERVERS
echo "DEBUG >>>>>> FE_SERVERS=[${FE_SERVERS}]"
echo "DEBUG >>>>>> BROKER_ADDR=[${BROKER_ADDR}]"

feIpArray=()
feEditLogPortArray=()

IFS=","
# shellcheck disable=SC2206
feServerArray=(${FE_SERVERS})

for i in "${!feServerArray[@]}"; do
val=${feServerArray[i]}
val=${val// /}
tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, ""); print$1}')
tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$3}')
feIpArray[tmpFeId]=${tmpFeIp}
feEditLogPortArray[tmpFeId]=${tmpFeEditLogPort}
done

broker_name=$(echo "${BROKER_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$1}')
broker_ip=$(echo "${BROKER_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$2}')
broker_ipc_port=$(echo "${BROKER_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$3}')

echo "DEBUG >>>>>> feIpArray = ${feIpArray[*]}"
echo "DEBUG >>>>>> feEditLogPortArray = ${feEditLogPortArray[*]}"
echo "DEBUG >>>>>> masterFe = ${feIpArray[1]}:${feEditLogPortArray[1]}"
echo "DEBUG >>>>>> broker_addr = ${broker_ip}:${broker_ipc_port}"

dropMySQL="/usr/bin/mysql -uroot -P9030 -h${feIpArray[1]} -e \"alter system drop broker ${broker_name} '${broker_ip}:${broker_ipc_port}'\""
echo "DEBUG >>>>>> dropMySQL = ${dropMySQL}"
eval "${dropMySQL}" && echo "DEBUG >>>>>> drop history registe SUCCESS!" || echo "DEBUG >>>>>> drop history registe FAILED!"

# register broker to FE through mysql
registerMySQL="/usr/bin/mysql -uroot -P9030 -h${feIpArray[1]} -e \"alter system add broker ${broker_name} '${broker_ip}:${broker_ipc_port}'\""
echo "DEBUG >>>>>> registerMySQL = ${registerMySQL}"
eval "${registerMySQL}" && echo "DEBUG >>>>>> mysql register is SUCCESS!" || echo "DEBUG >>>>>> mysql register is FAILED!"

# start broker
registerShell="/opt/apache-doris/broker/bin/start_broker.sh &"
echo "DEBUG >>>>>> registerShell = ${registerShell}"
eval "${registerShell}" && echo "DEBUG >>>>>> start_broker SUCCESS!" || echo "DEBUG >>>>>> start_broker FAILED!"

for ((i = 0; i <= 20; i++)); do
sleep 10
## check broker register status
echo "DEBUG >>>>>> run commnad mysql -uroot -P9030 -h${feIpArray[1]} -e \"show proc '/brokers'\" | grep \" ${broker_ip} \" | grep \" ${broker_ipc_port} \" | grep \" true \""
mysql -uroot -P9030 -h"${feIpArray[1]}" -e "show proc '/brokers'" | grep "[[:space:]]${broker_ip}[[:space:]]" | grep "[[:space:]]${broker_ipc_port}[[:space:]]" | grep "[[:space:]]true[[:space:]]"
broker_join_status=$?
echo "DEBUG >>>>>> The " "${i}" "time to register Broker node, broker_join_status=${broker_join_status}"
if [[ "${broker_join_status}" == 0 ]]; then
## broker registe successfully
echo "BROKER START SUCCESS!!!"
break
else
## broker doesn't registe
echo "DEBUG >>>>>> run commnad ${registerMySQL}"
eval "${registerMySQL}"
if [[ "${i}" == 20 ]]; then
echo "DEBUG >>>>>> Broker Start Or Register FAILED!"
fi
sleep 3
fi
done
  1. 构建镜像
1
docker build -t apache-hdfs-broker:1.1.4 .

Kubernetes

service和pvc都以部署在Google Cloud的Kubernetes平台为例

  1. 创建 Pvc
1
2
3
4
5
6
7
8
9
10
11
12
13
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: doris-be
namespace: stable-db
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: standard-rwo
volumeMode: Filesystem
  1. 创建 ConfigMap
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
kind: ConfigMap
apiVersion: v1
metadata:
name: doris-config
namespace: stable-db
data:
be-conf: |-
PPROF_TMPDIR="$DORIS_HOME/log/"
sys_log_level = INFO
be_port = 9060
webserver_port = 8040
heartbeat_service_port = 9050
brpc_port = 8060
priority_networks = 10.35.0.192/26
storage_root_path = /data
be-conf-2: |-
PPROF_TMPDIR="$DORIS_HOME/log/"
sys_log_level = INFO
be_port = 29060
webserver_port = 28040
heartbeat_service_port = 29050
brpc_port = 28060
priority_networks = 10.35.0.192/26
storage_root_path = /data
be-init: |-
cp /doris/be.conf /opt/apache-doris/be/conf/be.conf
mkdir /data
chmod 0755 /opt/apache-doris/be/conf/be.conf
bash /opt/apache-doris/be/bin/start_be.sh &
sleep infinity
be-init-2: |-
cp /doris/be2.conf /opt/apache-doris/be/conf/be.conf
chmod 0755 /opt/apache-doris/be/conf/be.conf
bash /opt/apache-doris/be/bin/start_be.sh &
sleep infinity
fe-conf: >-
LOG_DIR = ${DORIS_HOME}/log
DATE = `date +%Y%m%d-%H%M%S`
JAVA_OPTS="-Xmx8192m -XX:+UseMembar -XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=7 -XX:+PrintGCDateStamps -XX:+PrintGCDetails
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=80
-XX:SoftRefLRUPolicyMSPerMB=0 -Xloggc:$DORIS_HOME/log/fe.gc.log.$DATE"
JAVA_OPTS_FOR_JDK_9="-Xmx8192m -XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=7 -XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=80
-XX:SoftRefLRUPolicyMSPerMB=0
-Xlog:gc*:$DORIS_HOME/log/fe.gc.log.$DATE:time"
sys_log_level = INFO
http_port = 8030
rpc_port = 9020
query_port = 9030
edit_log_port = 9010
mysql_service_nio_enabled = true
priority_networks = 10.35.0.192/26
meta_dir = /opt/apache-doris/fe/doris-meta/
enable_binlog = true
expire_logs_days = 1
binlog_format = row
binlog_row_image = full
fe-init: |-
cp /doris/fe.conf /opt/apache-doris/fe/conf/fe.conf
chmod 0755 /opt/apache-doris/fe/conf/fe.conf
bash /opt/apache-doris/fe/bin/start_fe.sh
init.sql: |-
show frontends\G;
SET PASSWORD FOR 'root' = PASSWORD('<密码>');
ALTER SYSTEM ADD BACKEND "<backend uri>";
SHOW BACKENDS\G
  • priority_networks: 需要设置为同一个内网之下
  • PASSWORD('<密码>'): 替换为你想设置的密码
  • <backend uri>: 如192.168.100.5:9050
  1. 创建 StatefulSet
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: doris
namespace: stable-db
labels:
app: doris
spec:
replicas: 1
selector:
matchLabels:
app: doris
template:
metadata:
labels:
app: doris
spec:
volumes:
- name: doris-config
configMap:
name: doris-config
items:
- key: fe-conf
path: fe.conf
- key: fe-init
path: fe.sh
- key: be-init
path: be.sh
- key: init.sql
path: init.sql
- key: be-conf-2
path: be2.conf
- key: be-init-2
path: be2.sh
- key: be-conf
path: be.conf
defaultMode: 420
- name: doris-be
persistentVolumeClaim:
claimName: doris-be
containers:
- name: doris-fe
image: doris-tapdata-fe:1.1
command:
- bash
args:
- /doris/fe.sh
ports:
- name: http-8030
containerPort: 8030
protocol: TCP
- name: grpc-9020
containerPort: 9020
protocol: TCP
- name: tcp-9030
containerPort: 9030
protocol: TCP
- name: tcp-9010
containerPort: 9010
protocol: TCP
env:
- name: JVM_ARGS
value: '-Xmx2048m -Xms512m'
resources:
requests:
cpu: 1
memory: 2Gi
ephemeral-storage: 10Gi
limits:
cpu: 1
memory: 2Gi
ephemeral-storage: 10Gi
volumeMounts:
- name: doris-config
readOnly: true
mountPath: /doris
livenessProbe:
httpGet:
path: /api/bootstrap
port: 8030
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 1
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /api/bootstrap
port: 8030
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 1
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
startupProbe:
httpGet:
path: /api/bootstrap
port: 8030
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 1
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
- name: doris-be-1
image: doris-tapdata-be:1.1
command:
- bash
args:
- /doris/be.sh
ports:
- name: tcp-9060
containerPort: 9060
protocol: TCP
- name: tcp-8040
containerPort: 8040
protocol: TCP
- name: tcp-9050
containerPort: 9050
protocol: TCP
- name: tcp-8060
containerPort: 8060
protocol: TCP
env:
- name: JVM_ARGS
value: '-Xmx2048m -Xms512m'
resources:
requests:
cpu: 1
memory: 2Gi
ephemeral-storage: 10Gi
limits:
cpu: 1
memory: 2Gi
ephemeral-storage: 10Gi
volumeMounts:
- name: doris-config
readOnly: true
mountPath: /doris
- name: doris-be-2
image: doris-tapdata-be:1.1
command:
- bash
args:
- /doris/be2.sh
ports:
- name: tcp-9060
containerPort: 29060
protocol: TCP
- name: tcp-28040
containerPort: 28040
protocol: TCP
- name: tcp-29050
containerPort: 29050
protocol: TCP
- name: tcp-28060
containerPort: 28060
protocol: TCP
env:
- name: JVM_ARGS
value: '-Xmx2048m -Xms512m'
resources:
requests:
cpu: 1
memory: 2Gi
ephemeral-storage: 10Gi
limits:
cpu: 1
memory: 2Gi
ephemeral-storage: 10Gi
volumeMounts:
- name: doris-config
readOnly: true
mountPath: /doris
- name: doris-be
mountPath: /data
  • 2个Be,1个Fe
  • 8030:HTTP Port
  • 9020:Rpc Port
  • 9030:Query Port
  • 9010:EditLogPort
  1. 创建 Service
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
apiVersion: v1
kind: Service
metadata:
name: doris
namespace: stable-db
annotations:
cloud.google.com/l4-rbs: "enabled"
labels:
app: doris
spec:
loadBalancerIP: <your-ip>
type: LoadBalancer
externalTrafficPolicy: Cluster
ports:
- port: <your-port>
nodePort: <your-port>
targetPort: 9030
protocol: TCP
name: doris-port
- port: <your-port>
nodePort: <your-port>
targetPort: 8040
protocol: TCP
name: doris-http
selector:
app: doris

docker-compose 部署

  1. 目录结构
1
2
3
4
5
6
7
8
9
10
11
.
├── be-1
│   ├── be.conf
│   └── be.sh
├── be-2
│   ├── be.conf
│   └── be.sh
├── docker-compose.yaml
└── fe
├── fe.conf
└── fe.sh
  1. docker-compose.yaml
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
version: '3'

services:
doris-fe:
image: ghcr.io/tapdata/doris-tapdata-fe:1.1
networks:
dorisnetwork:
ipv4_address: 10.0.0.2
restart: always
ports:
- "8030:8030"
- "9020:9020"
- "9030:9030"
- "9010:9010"
environment:
JVM_ARGS: '-Xmx2048m -Xms512m'
volumes:
- ./fe:/doris
entrypoint: ["bash", "/doris/fe.sh"]
deploy:
replicas: 1
resources:
limits:
cpus: '1'
memory: 2G
reservations:
cpus: '1'
memory: 2G

doris-be-1:
image: ghcr.io/tapdata/doris-tapdata-be:1.1
networks:
dorisnetwork:
ipv4_address: 10.0.0.3
restart: always
ports:
- "9060:9060"
- "8040:8040"
- "9050:9050"
- "8060:8060"
environment:
JVM_ARGS: '-Xmx2048m -Xms512m'
volumes:
- ./be-1:/doris
- /data/doris/be-1:/data
entrypoint: ["bash", "/doris/be.sh"]
deploy:
replicas: 1
resources:
limits:
cpus: '1'
memory: 2G
reservations:
cpus: '1'
memory: 2G

doris-be-2:
image: ghcr.io/tapdata/doris-tapdata-be:1.1
networks:
dorisnetwork:
ipv4_address: 10.0.0.4
restart: always
ports:
- "19060:19060"
- "18040:18040"
- "19050:19050"
- "18060:18060"
environment:
JVM_ARGS: '-Xmx2048m -Xms512m'
volumes:
- ./be-2:/doris
- /data/doris/be-2:/data
entrypoint: ["bash", "/doris/be.sh"]
deploy:
replicas: 1
resources:
limits:
cpus: '1'
memory: 2G
reservations:
cpus: '1'
memory: 2G

networks:
dorisnetwork:
driver: bridge
ipam:
config:
- subnet: 10.0.0.0/24
  1. be

(1) be-1/be.conf

1
2
3
4
5
6
7
8
PPROF_TMPDIR="$DORIS_HOME/log/"
sys_log_level = INFO
be_port = 9060
webserver_port = 8040
heartbeat_service_port = 9050
brpc_port = 8060
priority_networks = 10.0.0.3/24
storage_root_path = /data

(2) be-1/be.sh

1
2
3
4
cp /doris/be.conf /opt/apache-doris/be/conf/be.conf
chmod 0755 /opt/apache-doris/be/conf/be.conf
bash /opt/apache-doris/be/bin/start_be.sh &
sleep infinity

(3) be-2/be.conf

1
2
3
4
5
6
7
8
PPROF_TMPDIR="$DORIS_HOME/log/"
sys_log_level = INFO
be_port = 19060
webserver_port = 18040
heartbeat_service_port = 19050
brpc_port = 18060
priority_networks = 10.0.0.4/24
storage_root_path = /data

(4) be-2/be.sh

1
2
3
4
cp /doris/be.conf /opt/apache-doris/be/conf/be.conf
chmod 0755 /opt/apache-doris/be/conf/be.conf
bash /opt/apache-doris/be/bin/start_be.sh &
sleep infinity
  1. fe

(1) fe.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
LOG_DIR = ${DORIS_HOME}/log
DATE = `date +%Y%m%d-%H%M%S`
JAVA_OPTS="-Xmx8192m -XX:+UseMembar -XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=7 -XX:+PrintGCDateStamps -XX:+PrintGCDetails
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=80
-XX:SoftRefLRUPolicyMSPerMB=0 -Xloggc:$DORIS_HOME/log/fe.gc.log.$DATE"
JAVA_OPTS_FOR_JDK_9="-Xmx8192m -XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=7 -XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=80
-XX:SoftRefLRUPolicyMSPerMB=0
-Xlog:gc*:$DORIS_HOME/log/fe.gc.log.$DATE:time"
sys_log_level = INFO
http_port = 8030
rpc_port = 9020
query_port = 9030
edit_log_port = 9010
mysql_service_nio_enabled = true
priority_networks = 10.0.0.4/24
meta_dir = /opt/apache-doris/fe/doris-meta/
enable_binlog = true
expire_logs_days = 1
binlog_format = row
binlog_row_image = full

(2) fe.sh

1
2
3
cp /doris/fe.conf /opt/apache-doris/fe/conf/fe.conf
chmod 0755 /opt/apache-doris/fe/conf/fe.conf
bash /opt/apache-doris/fe/bin/start_fe.sh

docker-compose up -d 启动即可。

  1. 配置集群

查看frontend状态

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
33
34
35
36
37
>>> mysql -uroot -P9030 -h192.168.1.184

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 0
Server version: 5.7.37 Doris version 1.1.4-rc01-8890a58dc

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show frontends\G;
*************************** 1. row ***************************
Name: 10.0.0.2_9010_1703065486666
IP: 10.0.0.2
EditLogPort: 9010
HttpPort: 8030
QueryPort: 9030
RpcPort: 9020
Role: FOLLOWER
IsMaster: true
ClusterId: 1687052301
Join: true
Alive: true
ReplayedJournalId: 26
LastHeartbeat: 2023-12-20 09:46:04
IsHelper: true
ErrMsg:
Version: 1.1.4-rc01-8890a58dc
CurrentConnected: Yes
1 row in set (0.20 sec)

ERROR:
No query specified

Alive: true表示fe正常运行
IsMaster: true表示当前fe为master

添加Be节点

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
mysql> ALTER SYSTEM ADD BACKEND "10.0.0.3:9050";
Query OK, 1 row affected (0.01 sec)

mysql> SHOW BACKENDS\G;
*************************** 1. row ***************************
BackendId: 10002
Cluster: default_cluster
IP: 10.0.0.3
HeartbeatPort: 9050
BePort: 9060
HttpPort: 8040
BrpcPort: 8060
LastStartTime: 2023-12-20 09:44:39
LastHeartbeat: 2023-12-20 09:50:29
Alive: true
SystemDecommissioned: false
ClusterDecommissioned: false
TabletNum: 0
DataUsedCapacity: 0.000
AvailCapacity: 39.887 GB
TotalCapacity: 49.976 GB
UsedPct: 20.19 %
MaxDiskUsedPct: 20.19 %
Tag: {"location" : "default"}
ErrMsg:
Version: 1.1.4-rc01-8890a58dc
Status: {"lastSuccessReportTabletsTime":"2023-12-20 09:50:19","lastStreamLoadTime":-1,"isQueryDisabled":false,"isLoadDisabled":false}
1 row in set (0.01 sec)

ERROR:
No query specified

mysql> ALTER SYSTEM ADD BACKEND "10.0.0.4:19050";
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW BACKENDS\G;
*************************** 1. row ***************************
BackendId: 10002
Cluster: default_cluster
IP: 10.0.0.3
HeartbeatPort: 9050
BePort: 9060
HttpPort: 8040
BrpcPort: 8060
LastStartTime: 2023-12-20 09:44:39
LastHeartbeat: 2023-12-20 09:53:29
Alive: true
SystemDecommissioned: false
ClusterDecommissioned: false
TabletNum: 0
DataUsedCapacity: 0.000
AvailCapacity: 39.914 GB
TotalCapacity: 49.976 GB
UsedPct: 20.13 %
MaxDiskUsedPct: 20.13 %
Tag: {"location" : "default"}
ErrMsg:
Version: 1.1.4-rc01-8890a58dc
Status: {"lastSuccessReportTabletsTime":"2023-12-20 09:53:27","lastStreamLoadTime":-1,"isQueryDisabled":false,"isLoadDisabled":false}
*************************** 2. row ***************************
BackendId: 10004
Cluster: default_cluster
IP: 10.0.0.4
HeartbeatPort: 19050
BePort: 19060
HttpPort: 18040
BrpcPort: 18060
LastStartTime: 2023-12-20 09:44:39
LastHeartbeat: 2023-12-20 09:53:29
Alive: true
SystemDecommissioned: false
ClusterDecommissioned: false
TabletNum: 0
DataUsedCapacity: 0.000
AvailCapacity: 39.916 GB
TotalCapacity: 49.976 GB
UsedPct: 20.13 %
MaxDiskUsedPct: 20.13 %
Tag: {"location" : "default"}
ErrMsg:
Version: 1.1.4-rc01-8890a58dc
Status: {"lastSuccessReportTabletsTime":"2023-12-20 09:53:30","lastStreamLoadTime":-1,"isQueryDisabled":false,"isLoadDisabled":false}
2 rows in set (0.01 sec)

ERROR:
No query specified
  1. 创建数据库
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
mysql> create database demo;
Query OK, 0 rows affected (0.03 sec)

mysql> use demo;
Database changed
mysql>
mysql> CREATE TABLE IF NOT EXISTS demo.example_tbl
-> (
-> `user_id` LARGEINT NOT NULL COMMENT "用户id",
-> `date` DATE NOT NULL COMMENT "数据灌入日期时间",
-> `city` VARCHAR(20) COMMENT "用户所在城市",
-> `age` SMALLINT COMMENT "用户年龄",
-> `sex` TINYINT COMMENT "用户性别",
-> `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "用户最后一次访问时间",
-> `cost` BIGINT SUM DEFAULT "0" COMMENT "用户总消费",
-> `max_dwell_time` INT MAX DEFAULT "0" COMMENT "用户最大停留时间",
-> `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "用户最小停留时间"
-> )
-> AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
-> DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
-> PROPERTIES (
-> "replication_allocation" = "tag.location.default: 1"
-> );
Query OK, 0 rows affected (0.61 sec)

mysql> INSERT INTO demo.example_tbl VALUES
-> (10000, '2017-10-01', '北京', 20, 0, '2017-10-01 06:00:00', 20, 10, 10),
-> (10000, '2017-10-01', '北京', 20, 0, '2017-10-01 07:00:00', 15, 2, 2),
-> (10001, '2017-10-01', '北京', 30, 1, '2017-10-01 17:05:45', 2, 22, 22),
-> (10002, '2017-10-02', '上海', 20, 1, '2017-10-02 12:59:12', 200, 5, 5),
-> (10003, '2017-10-02', '广州', 32, 0, '2017-10-02 11:20:00', 30, 11, 11),
-> (10004, '2017-10-01', '深圳', 35, 0, '2017-10-01 10:00:15', 100, 3, 3),
-> (10004, '2017-10-03', '深圳', 35, 0, '2017-10-03 10:20:22', 11, 6, 6);
Query OK, 7 rows affected (0.46 sec)
{'label':'insert_3452b37186f5443c-854dc14881ea073b', 'status':'VISIBLE', 'txnId':'2'}

mysql> select * from example_tbl;
+---------+------------+--------+------+------+---------------------+------+----------------+----------------+
| user_id | date | city | age | sex | last_visit_date | cost | max_dwell_time | min_dwell_time |
+---------+------------+--------+------+------+---------------------+------+----------------+----------------+
| 10000 | 2017-10-01 | 北京 | 20 | 0 | 2017-10-01 07:00:00 | 35 | 10 | 2 |
| 10001 | 2017-10-01 | 北京 | 30 | 1 | 2017-10-01 17:05:45 | 2 | 22 | 22 |
| 10002 | 2017-10-02 | 上海 | 20 | 1 | 2017-10-02 12:59:12 | 200 | 5 | 5 |
| 10003 | 2017-10-02 | 广州 | 32 | 0 | 2017-10-02 11:20:00 | 30 | 11 | 11 |
| 10004 | 2017-10-01 | 深圳 | 35 | 0 | 2017-10-01 10:00:15 | 100 | 3 | 3 |
| 10004 | 2017-10-03 | 深圳 | 35 | 0 | 2017-10-03 10:20:22 | 11 | 6 | 6 |
+---------+------------+--------+------+------+---------------------+------+----------------+----------------+
6 rows in set (0.20 sec)

mysql> select * from example_tbl where city='上海';
+---------+------------+--------+------+------+---------------------+------+----------------+----------------+
| user_id | date | city | age | sex | last_visit_date | cost | max_dwell_time | min_dwell_time |
+---------+------------+--------+------+------+---------------------+------+----------------+----------------+
| 10002 | 2017-10-02 | 上海 | 20 | 1 | 2017-10-02 12:59:12 | 200 | 5 | 5 |
+---------+------------+--------+------+------+---------------------+------+----------------+----------------+
1 row in set (0.08 sec)

mysql> select city, sum(cost) as total_cost from example_tbl group by city;
+--------+------------+
| city | total_cost |
+--------+------------+
| 广州 | 30 |
| 上海 | 200 |
| 北京 | 37 |
| 深圳 | 111 |
+--------+------------+
4 rows in set (0.10 sec)

评论