1、镜像构建
1.1、Doris2.0-FE基础镜像构建
由于官方镜像内对FE 上的init_fe.sh脚本mysql server端口9030做了硬编码设置,需要对特定脚本进行更改,同时需要提出各个端口用于灵活部署,Dockerfile文件如下:
FROM apache/doris:2.0.0_alpha-fe-x86_64 COPY fe.conf /tmp/ COPY init_fe.sh /opt/apache-doris/fe/bin/init_fe.sh COPY --chown=root:root entrypoint.sh /usr/local/bin/ RUN chmod +x /opt/apache-doris/fe/bin/init_fe.sh RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"]
其他配置文件参考gitlab地址:
链接:https://pan.baidu.com/s/1B7LBSEYzvPeArb8ApfvKzQ
提取码:ky3u
镜像构建命令
docker build -t xxx.xxx.xx.xx/base/apache/doris:2.0.0_alpha-fe-x86_64 .
1.2、 Doris2.0-BE基础镜像构建
由于官方镜像内对BE 上的entry_point.sh和init_be.sh脚本mysql server端口9030做了硬编码设置,需要对特定脚本进行更改,同时需要提出各个端口用于灵活部署,Dockerfile文件如下:
FROM apache/doris:2.0.0_alpha-be-x86_64 COPY be.conf /tmp/ COPY entry_point.sh /usr/local/bin/entry_point.sh COPY init_be.sh /usr/local/bin/init_be.sh COPY --chown=root:root entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/entry_point.sh RUN chmod +x /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/init_be.sh ENTRYPOINT ["entrypoint.sh"]
链接:https://pan.baidu.com/s/1B7LBSEYzvPeArb8ApfvKzQ
提取码:ky3u
镜像构建命令
docker build -t xxx.xxx.xx.xx/base/apache/doris:2.0.0_alpha-be-x86_64 .
2、doris单机部署-1FE1BE
模板:
version: '3.7' services: fe1: image: xxx.xxx.xx.xx/base/apache/doris:2.0.0_alpha-fe-x86_64 networks: hostnet: {} container_name: fe1 hostname: fe1 environment: HTTP_PORT: ${FE1_HTTP_PORT} RPC_PORT: ${FE1_RPC_PORT} QUERY_PORT: ${FE1_MYSQL_PORT} EDIT_LOG_PORT: ${FE1_EDIT_LOG_PORT} ENABLE_OUTFILE_TO_LOCAL: ${ENABLE_OUTFILE_TO_LOCAL} FE_SERVERS: fe1:${FE1_IP}:${FE1_EDIT_LOG_PORT} FE_ID: 1 volumes: - fe1_doris-meta:/opt/apache-doris/fe/doris-meta - fe1_log:/opt/apache-doris/fe/log - fe1_conf:/opt/apache-doris/fe/conf deploy: resources: limits: cpus: ${FE_CPU:-'1'} memory: ${FE_MEM:-2G} restart_policy: condition: on-failure delay: 5s max_attempts: 3 window: 120s replicas: 1 placement: constraints: - node.ip==${FE1_IP} be1: image: xxx.xxx.xx.xx/base/apache/doris:2.0.0_alpha-be-x86_64 networks: hostnet: {} container_name: be1 hostname: be1 depends_on: - fe1 environment: BE_PORT: ${BE1_BE_PORT} WEBSERVER_PORT: ${BE1_WEBSERVER_PORT} HEARTBEAT_SERVICE_PORT: ${BE1_HEARTBEAT_SERVICE_PORT} BRPC_PORT: ${BE1_BRPC_PORT} FE_SERVERS: fe1:${FE1_IP}:${FE1_EDIT_LOG_PORT} BE_ADDR: ${BE1_IP}:${BE1_HEARTBEAT_SERVICE_PORT} QUERY_PORT: ${FE1_MYSQL_PORT} volumes: - be1_storage:/opt/apache-doris/be/storage - be1_script:/docker-entrypoint-initdb.d - be1_log:/opt/apache-doris/be/log deploy: resources: limits: cpus: ${BE_CPU:-'1'} memory: ${BE_MEM:-2G} restart_policy: condition: on-failure delay: 5s max_attempts: 3 window: 120s replicas: 1 placement: constraints: - node.ip==${BE1_IP} networks: hostnet: external: true name: host volumes: fe1_doris-meta: fe1_log: fe1_conf: be1_storage: be1_script: be1_log:
在要启动BE节点的主机上执行如下命令:
sysctl -w vm.max_map_count=2000000 //临时生效,大部分机器默认65530,中间件机器262144 echo vm.max_map_count=2000000 >> /etc/sysctl.conf //永久生效
输入对应变量:
变量名称 | 说明 |
---|---|
FE1_IP | FE节点部署ip |
FE1_EDIT_LOG_PORT | FE 上的 bdbje 之间通信用的端口 |
FE1_HTTP_PORT | FE 上的 http server 端口 |
FE1_MYSQL_PORT | FE 上的 mysql server 端口 |
FE1_RPC_PORT | FE 上的 thrift server 端口,每个fe的配置需要保持一致 |
BE1_IP | BE节点部署ip |
BE1_BE_PORT | BE 上 thrift server 的端口,用于接收来自 FE 的请求 |
BE1_WEBSERVER_PORT | BE 上的 http server 的端口 |
BE1_HEARTBEAT_SERVICE_PORT | BE 上心跳服务端口(thrift),用于接收来自 FE 的心跳 |
BE1_BRPC_PORT | BE 上的 brpc 端口,用于 BE 之间通讯 |
ENABLE_OUTFILE_TO_LOCAL | 是否开启文件输出,支持sql命令导出文件功能 |
FE_CPU | FE节点cpu核数 |
FE_MEM | FE节点内存大小 |
BE_CPU | BE节点cpu核数 |
BE_MEM | BE节点内存大小 |
通过stack启动即可
3、doris集群部署-3FE3BE
模板:
version: '3.7' x-fe: &fe image: xxx.xxx.xx.xx/base/apache/doris:2.0.0_alpha-fe-x86_64 networks: hostnet: {} x-fe-environment: &fe-environment ENABLE_OUTFILE_TO_LOCAL: ${ENABLE_OUTFILE_TO_LOCAL} QUERY_PORT: ${FE_MYSQL_PORT} FE_SERVERS: fe1:${FE1_IP}:${FE1_EDIT_LOG_PORT},fe2:${FE2_IP}:${FE2_EDIT_LOG_PORT},fe3:${FE3_IP}:${FE3_EDIT_LOG_PORT} x-fe-deploy: &fe-deploy resources: limits: cpus: ${FE_CPU:-1} memory: ${FE_MEM:-2G} restart_policy: condition: on-failure delay: 5s max_attempts: 3 replicas: 1 x-be: &be image: xxx.xxx.xx.xx/base/apache/doris:2.0.0_alpha-be-x86_64 networks: hostnet: {} depends_on: - fe1 - fe2 - fe3 x-be-environment: &be-environment QUERY_PORT: ${FE_MYSQL_PORT} FE_SERVERS: fe1:${FE1_IP}:${FE1_EDIT_LOG_PORT},fe2:${FE2_IP}:${FE2_EDIT_LOG_PORT},fe3:${FE3_IP}:${FE3_EDIT_LOG_PORT} x-be-deploy: &be-deploy resources: limits: cpus: ${BE_CPU:-1} memory: ${BE_MEM:-2G} restart_policy: condition: on-failure delay: 5s max_attempts: 3 replicas: 1 services: fe1: <<: *fe container_name: fe1 hostname: fe1 environment: HTTP_PORT: ${FE1_HTTP_PORT} RPC_PORT: ${FE1_RPC_PORT} EDIT_LOG_PORT: ${FE1_EDIT_LOG_PORT} FE_ID: 1 <<: *fe-environment volumes: - fe1_doris-meta:/opt/apache-doris/fe/doris-meta - fe1_log:/opt/apache-doris/fe/log - fe1_conf:/opt/apache-doris/fe/conf deploy: <<: *fe-deploy placement: constraints: - node.ip==${FE1_IP} fe2: <<: *fe container_name: fe2 hostname: fe2 environment: HTTP_PORT: ${FE2_HTTP_PORT} RPC_PORT: ${FE2_RPC_PORT} EDIT_LOG_PORT: ${FE2_EDIT_LOG_PORT} FE_ID: 2 <<: *fe-environment volumes: - fe2_doris-meta:/opt/apache-doris/fe/doris-meta - fe2_log:/opt/apache-doris/fe/log - fe2_conf:/opt/apache-doris/fe/conf deploy: <<: *fe-deploy placement: constraints: - node.ip==${FE2_IP} fe3: <<: *fe container_name: fe3 hostname: fe3 environment: HTTP_PORT: ${FE3_HTTP_PORT} RPC_PORT: ${FE3_RPC_PORT} EDIT_LOG_PORT: ${FE3_EDIT_LOG_PORT} FE_ID: 3 <<: *fe-environment volumes: - fe3_doris-meta:/opt/apache-doris/fe/doris-meta - fe3_log:/opt/apache-doris/fe/log - fe3_conf:/opt/apache-doris/fe/conf deploy: <<: *fe-deploy placement: constraints: - node.ip==${FE3_IP} be1: <<: *be container_name: be1 hostname: be1 environment: BE_PORT: ${BE1_BE_PORT} WEBSERVER_PORT: ${BE1_WEBSERVER_PORT} HEARTBEAT_SERVICE_PORT: ${BE1_HEARTBEAT_SERVICE_PORT} BRPC_PORT: ${BE1_BRPC_PORT} BE_ADDR: ${BE1_IP}:${BE1_HEARTBEAT_SERVICE_PORT} <<: *be-environment volumes: - be1_storage:/opt/apache-doris/be/storage - be1_script:/docker-entrypoint-initdb.d - be1_log:/opt/apache-doris/be/log deploy: <<: *be-deploy placement: constraints: - node.ip==${BE1_IP} be2: <<: *be container_name: be2 hostname: be2 environment: BE_PORT: ${BE2_BE_PORT} WEBSERVER_PORT: ${BE2_WEBSERVER_PORT} HEARTBEAT_SERVICE_PORT: ${BE2_HEARTBEAT_SERVICE_PORT} BRPC_PORT: ${BE2_BRPC_PORT} BE_ADDR: ${BE2_IP}:${BE2_HEARTBEAT_SERVICE_PORT} <<: *be-environment volumes: - be2_storage:/opt/apache-doris/be/storage - be2_script:/docker-entrypoint-initdb.d - be2_log:/opt/apache-doris/be/log deploy: <<: *be-deploy placement: constraints: - node.ip==${BE2_IP} be3: <<: *be container_name: be3 hostname: be3 environment: BE_PORT: ${BE3_BE_PORT} WEBSERVER_PORT: ${BE3_WEBSERVER_PORT} HEARTBEAT_SERVICE_PORT: ${BE3_HEARTBEAT_SERVICE_PORT} BRPC_PORT: ${BE3_BRPC_PORT} BE_ADDR: ${BE3_IP}:${BE3_HEARTBEAT_SERVICE_PORT} <<: *be-environment volumes: - be3_storage:/opt/apache-doris/be/storage - be3_script:/docker-entrypoint-initdb.d - be3_log:/opt/apache-doris/be/log deploy: <<: *be-deploy placement: constraints: - node.ip==${BE3_IP} networks: hostnet: external: true name: host volumes: fe1_doris-meta: fe1_log: fe1_conf: fe2_doris-meta: fe2_log: fe2_conf: fe3_doris-meta: fe3_log: fe3_conf: be1_storage: be1_script: be1_log: be2_storage: be2_script: be2_log: be3_storage: be3_script: be3_log:
在要启动BE节点的主机上执行如下命令:
sysctl -w vm.max_map_count=2000000 //临时生效,大部分机器默认65530,中间件机器262144 echo vm.max_map_count=2000000 >> /etc/sysctl.conf //永久生效
输入对应变量:
变量名称 | 说明 |
---|---|
FE1_IP | FE1节点部署ip |
FE2_IP | FE2节点部署ip |
FE3_IP | FE3节点部署ip |
FE1_HTTP_PORT | FE1 上的 http server 端口 |
FE1_RPC_PORT | FE1 上的 thrift server 端口,每个fe的配置需要保持一致 |
FE1_EDIT_LOG_PORT | FE1 上的 bdbje 之间通信用的端口 |
FE2_HTTP_PORT | FE2 上的 http server 端口 |
FE2_RPC_PORT | FE2 上的 thrift server 端口,每个fe的配置需要保持一致 |
FE2_EDIT_LOG_PORT | FE2 上的 bdbje 之间通信用的端口 |
FE3_HTTP_PORT | FE3 上的 http server 端口 |
FE3_RPC_PORT | FE3 上的 thrift server 端口,每个fe的配置需要保持一致 |
FE3_EDIT_LOG_PORT | FE3 上的 bdbje 之间通信用的端口 |
FE_MYSQL_PORT | FE 上的 mysql server 端口,所有节点使用同一个端口,因为BE节点需要FE master节点的mysql端口作为shell脚本内初始化命令使用 |
ENABLE_OUTFILE_TO_LOCAL | 是否开启文件输出,支持sql命令导出文件功能 |
FE_CPU | FE节点cpu核数 |
FE_MEM | FE节点内存大小 |
BE1_IP | BE1节点部署ip |
BE2_IP | BE2节点部署ip |
BE3_IP | BE3节点部署ip |
BE1_BE_PORT | BE1 上 thrift server 的端口,用于接收来自 FE 的请求 |
BE1_WEBSERVER_PORT | BE1 上的 http server 的端口 |
BE1_HEARTBEAT_SERVICE_PORT | BE1 上心跳服务端口(thrift),用于接收来自 FE 的心跳 |
BE1_BRPC_PORT | BE1 上的 brpc 端口,用于 BE 之间通讯 |
BE2_BE_PORT | BE2 上 thrift server 的端口,用于接收来自 FE 的请求 |
BE2_WEBSERVER_PORT | BE2 上的 http server 的端口 |
BE2_HEARTBEAT_SERVICE_PORT | BE2 上心跳服务端口(thrift),用于接收来自 FE 的心跳 |
BE2_BRPC_PORT | BE2 上的 brpc 端口,用于 BE 之间通讯 |
BE3_BE_PORT | BE3 上 thrift server 的端口,用于接收来自 FE 的请求 |
BE3_WEBSERVER_PORT | BE3 上的 http server 的端口 |
BE3_HEARTBEAT_SERVICE_PORT | BE3 上心跳服务端口(thrift),用于接收来自 FE 的心跳 |
BE3_BRPC_PORT | BE3 上的 brpc 端口,用于 BE 之间通讯 |
BE_CPU | BE节点cpu核数 |
BE_MEM | BE节点内存大小 |
通过stack启动即可
4、doris使用
FE前端访问地址:
FE1_IP:FE1_HTTP_PORT 初始用户名/密码: root/空
BE前端访问地址:
BE1_IP:BE1_WEBSERVER_PORT 可直接访问
修改初始用户名密码连接
mysql -uroot -P${FE_MYSQL_PORT} -h${FE1_IP} SET PASSWORD FOR 'root' = PASSWORD('your_password');
分配某个数据库的读写权限给普通用户
CREATE USER 'test' IDENTIFIED BY 'test_passwd'; CREATE DATABASE example_db; GRANT ALL ON example_db TO test; //将example_db的读写权限分配给test用户
以下是一个将doris数据同步到es的简单示例:
建表:
CREATE TABLE IF NOT EXISTS `part` ( `p_partkey` int(11) NOT NULL COMMENT "", `p_name` varchar(23) NOT NULL COMMENT "", `p_mfgr` varchar(7) NOT NULL COMMENT "", `p_category` varchar(8) NOT NULL COMMENT "", `p_brand` varchar(10) NOT NULL COMMENT "", `p_color` varchar(12) NOT NULL COMMENT "", `p_type` varchar(26) NOT NULL COMMENT "", `p_size` int(11) NOT NULL COMMENT "", `p_container` varchar(11) NOT NULL COMMENT "" ) ENGINE=OLAP DUPLICATE KEY(`p_partkey`) COMMENT "OLAP" DISTRIBUTED BY HASH(`p_partkey`) BUCKETS 12 PROPERTIES ( "replication_num" = "1", "colocate_with" = "groupa5", "in_memory" = "false", "storage_format" = "DEFAULT" );
使用stream-load执行导入数据会将140万条数据导入到part表:
curl --location-trusted -u "${USER}":"${PASSWORD}" \ -H "column_separator:|" \ -H "columns:p_partkey,p_name,p_mfgr,p_category,p_brand,p_color,p_type,p_size,p_container,p_dummy" \ -T part.tbl http://"${FE_HOST}":"${FE_HTTP_PORT}"/api/"${DB}"/part/_stream_load
part.tal文件下载地址:
链接:https://pan.baidu.com/s/1B7LBSEYzvPeArb8ApfvKzQ
提取码:ky3u
通过执行sql将数据导出到csv文件
select * from part into outfile "file:///opt/apache-doris/be/storage/part_" format as CSV properties ("max_file_size" = "50MB","column_separator" = ",","line_delimiter" = "\n");
刚才的140w条数据导出了3个文件,分别是
part_7621527c5e854a5d-a6bce5451f0277c9_0.csv
part_7621527c5e854a5d-a6bce5451f0277c9_1.csv
part_7621527c5e854a5d-a6bce5451f0277c9_2.csv
将这3个文件每个里第一行插入字段名
p_partkey | p_name | p_mfgr | p_category | p_brand | p_color | p_type | p_size | p_container |
---|---|---|---|---|---|---|---|---|
然后使用elasticdump导入到es中
elasticdump --input="csv:///tmp/part_7621527c5e854a5d-a6bce5451f0277c9_0.csv" --output=http://elastic:YTRjMDc4NzIyYTdk@10.172.48.18:1029/part --csvSkipRows=1 --csvDelimiter="," elasticdump --input="csv:///tmp/part_7621527c5e854a5d-a6bce5451f0277c9_1.csv" --output=http://elastic:YTRjMDc4NzIyYTdk@10.172.48.18:1029/part --csvSkipRows=1 --csvDelimiter="," elasticdump --input="csv:///tmp/part_7621527c5e854a5d-a6bce5451f0277c9_2.csv" --output=http://elastic:YTRjMDc4NzIyYTdk@10.172.48.18:1029/part --csvSkipRows=1 --csvDelimiter=","
5、与es性能简单比较
给doris表创建倒排索引
ALTER TABLE part ADD INDEX idx_part(p_name) USING INVERTED PROPERTIES("parser" = "english") COMMENT 'idx_part INVERTED';
es查询匹配10000条数据耗时:
doris查询耗时:
SELECT * FROM part WHERE p_name MATCH_ANY 'blue snow';
简单比较:
6、集群稳定性测试
1.1、FE节点扩容测试
命令:
ALTER SYSTEM ADD FOLLOWER "follower_host:edit_log_port"; 或者 ALTER SYSTEM ADD OBSERVER "observer_host:edit_log_port";
FE 扩容注意事项:
-
Follower FE(包括 Master)的数量必须为奇数,建议最多部署 3 个组成高可用(HA)模式即可。
-
当 FE 处于高可用部署时(1个 Master,2个 Follower),我们建议通过增加 Observer FE 来扩展 FE 的读服务能力。当然也可以继续增加 Follower FE,但几乎是不必要的。
-
通常一个 FE 节点可以应对 10-20 台 BE 节点。建议总的 FE 节点数量在 10 个以下。而通常 3 个即可满足绝大部分需求。
-
helper 不能指向 FE 自身,必须指向一个或多个已存在并且正常运行中的 Master/Follower FE。
1.2、BE节点扩容测试
命令:
ALTER SYSTEM ADD BACKEND "be_host:be_heartbeat_service_port";
也可通过模板直接扩容无需执行命令
BE 扩容后,Doris 会自动根据负载情况,进行数据均衡,期间不影响使用。[存量和增量数据都会进行数据均衡]
1.3、BE节点缩容宕机测试
3FE3BE缩容影响测试,宕机不会自动下线节点
操作 | 副本数 | 副本是否自动迁移 | 数据是否丢失 | 集群是否可用 | 重启是否恢复 |
---|---|---|---|---|---|
BE宕机1台 | 1 | 否 | 是 | 否 | 是 |
BE宕机1台 | 2 | 否 | 否 | 是 | 是 |
BE宕机1台 | 3 | 否 | 否 | 是 | 是 |
BE宕机2台 | 1 | 否 | 是 | 否 | 是 |
BE宕机2台 | 2 | 否 | 是 | 否 | 是 |
BE宕机2台 | 3 | 否 | 否 | 是 | 是 |
BE宕机3台 | 1 | 否 | 是 | 否 | 是 |
BE宕机3台 | 2 | 否 | 是 | 否 | 是 |
BE宕机3台 | 3 | 否 | 是 | 否 | 是 |
命令:
ALTER SYSTEM DECOMMISSION BACKEND "be_host:be_heartbeat_service_port";
*手动下线节点,DECOMMISSION命令不一定执行成功,TabletNum有时未减少至0,此功能慎用
命令:
ALTER SYSTEM DROP BACKEND "be_host:be_heartbeat_service_port";
3FE3BE缩容影响测试,DROPP命令删除节点
操作 | 副本数 | 副本是否自动迁移 | 数据是否丢失 | 集群是否可用 | 重新ADD是否恢复 |
---|---|---|---|---|---|
BE宕机1台 | 1 | 否 | 是 | 否 | 否 |
BE宕机1台 | 2 | 否 | 否 | 是 | 否 |
BE宕机1台 | 3 | 否 | 否 | 是 | 否 |
BE宕机2台 | 1 | 否 | 是 | 否 | 否 |
BE宕机2台 | 2 | 否 | 是 | 否 | 否 |
BE宕机2台 | 3 | 否 | 否 | 是 | 否 |
BE宕机3台 | 1 | 否 | 是 | 否 | 否 |
BE宕机3台 | 2 | 否 | 是 | 否 | 否 |
BE宕机3台 | 3 | 否 | 是 | 否 | 否 |
1.4、FE节点缩容宕机测试
命令:
ALTER SYSTEM DROPP FOLLOWER[OBSERVER] "fe_host:edit_log_port";
操作 | 宕机机器的Alive状态 | 宕机机器的Join状态 | 集群是否可用 | 重启是否恢复 |
---|---|---|---|---|
FE宕机1台(非master) | FALSE | TRUE | 是 | 是 |
FE宕机1台(master) | FALSE | TRUE | 是 | 是,恢复为从节点 |
FE宕机2台(不含master) | FALSE | TRUE | 否,30s后主节点会自动宕机 | 否 |
FE宕机2台(含master) | FALSE | TRUE | 否 | 否 |
FE宕机3台 | FALSE | TRUE | 否 | 否 |
现象:
宕机2台以上master报错SIMPLE_MAJORITY required 1 replica. But none were active with this master.
重启之后一直滚动 "wait catalog to be ready. FE type UNKNOWN"
解决方案:
集群启动之初FE节点增加配置:
replica_ack_policy="none" //默认SIMPLE_MAJORITY,一半节点都写入元数据才算成功,此配置不是热更新,需要重启集群