ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Apache Doris部署实战:从单机到集群高可用全指南

Apache Doris部署实战:从单机到集群高可用全指南 1. 部署前必须确认的几件事版本、形态与机器规划1.1 Doris到底解决什么问题Doris是Apache基金会下的MPP架构实时分析型数据库标准SQL、向量化执行引擎主要面向OLAP场景。简单说它是给数据量大、查询复杂、要实时出数的场景用的。和ClickHouse、StarRocks属于同一类工具但Doris在宽表聚合查询、多表Join、高并发点查上表现相对均衡而且权限体系、物化视图、异步物化视图这些能力也比较完整。这个定位决定了Doris的部署方式和MySQL这种OLTP数据库完全不一样。Doris是存储计算一体、FE/BE两层的架构FEFrontend负责SQL解析、规划、调度、元数据管理、事务对外提供MySQL协议。BEBackend负责数据存储和查询执行数据副本、compaction、列式存储都在这一层。部署一个能跑的Doris至少要有一个FE和一个BE生产上通常每类节点至少三个FE多活、BE多副本保证高可用和数据安全。1.2 版本选型别只盯着“最新版本”从官网下载的时候会看到好几个版本栏。根据我的实际经验长期稳定版本适合生产bug修复和兼容性最稳。最新release版本功能最新测试环境优先选这个。beta、rc版本尝鲜用别上生产。比如2.0.x、2.1.x都是常见的生产大版本。2.1之后有几个对部署影响很大的特性Variant类型、异步物化视图、Unique Key模型的部分列更新等。如果你的业务要用Variant来存半结构化JSON一定要选2.1以上版本。还有一点非常关键Doris不同版本的默认配置会有变化比如FE的一些内存参数、BE的线程数默认值。网上大量博客和教程是基于旧版本写的直接抄命令很容易踩坑。我见过有人拿1.2版本的命令去操作2.1版本集群结果注册BE、查看副本状态的语法都不对。部署前一定养成分支看官方文档的习惯特别是当前版本对应的安装手册。1.3 部署形态与机器规划单机怎么跑集群怎么分部署形态有三种单机模式FE和BE跑在同一台机器用于测试、功能验证、学习。集群模式多个FE和BE用于生产。多集群模式两套以上集群独立部署用于环境隔离。机器规格方面我的建议比较务实FE测试环境2核4G也能跑起来但生产至少8核16G起步FE主要消耗内存管理元数据和执行计划CPU也不能太弱。BECPU和内存是基本盘建议16核64G起步数据量大的往32核128G走。磁盘BE一定要用SSD机械盘跑OLAP查询很容易成为瓶颈。多块盘可以都配到storage_root_path里比如/data1/doris、/data2/doris。网络集群节点之间建议万兆网卡shuffle join和数据迁移都要走网络千兆网在小集群上可能感觉不明显但数据量上来之后区别很大。端口方面部署前先确认本机端口没有被占用FE8030Web UI/HTTP、9030MySQL协议、9010FE内部RPCBE8040BE HTTP、9060BRPC、9050心跳上报后面所有命令和排查都会围绕这些端口展开。2. 单机部署手把手实操从下载到首次建表查询2.1 环境准备JDK、文件句柄、关闭swap部署第一步不是解压而是先看操作系统环境。我一般检查三样东西。Java环境。FE需要JDK推荐JDK8或JDK11确保java -version能正常输出。这里有个容易忽略的点如果机器上装了多个JDK版本一定要把JAVA_HOME指向正确版本并确认path里的java命令也是同一个版本。FE启动脚本对JAVA_HOME很敏感指向错了会出现各种莫名其妙的报错。文件句柄。Doris文档建议把open files设置到65536以上否则BE在写入高峰期很可能报文件数不足。查看当前值用ulimit -n临时设置用ulimit -n 65536持久配置写到/etc/security/limits.conf。时钟同步。集群里各机器时间差太多事务和元数据会出问题生产环境建议配NTP同步。单机部署无所谓但需要养成这个意识。还有一条官方文档写得很实在的建议关闭swap。Linux用了swap之后数据库这种对延迟敏感的程序可能被换页拖死。我的做法是设置sysctl vm.swappiness0并写入/etc/sysctl.conf持久化。2.2 下载压缩包、配置FE并启动从Doris官网doris.apache.org下载对应发行版的二进制tar包。以2.0.x版本为例wget https://dlcdn.apache.org/doris/2.0.12/apache-doris-2.0.12-bin-x64.tar.gz tar -zxvf apache-doris-2.0.12-bin-x64.tar.gz cd apache-doris-2.0.12解压后目录里可以看到fe、be、broker等目录。先改FE配置cd fe vi conf/fe.conffe.conf里核心配置是meta_dir用来放元数据。没有特殊要求的话默认相对路径就行但我习惯改成绝对路径meta_dir /data/doris/fe_meta再确认一下http_port 8030这个端口是Doris Web UI和HTTP API的入口。如果机器上已经有其他服务占用需要改掉。启动FEbin/start_fe.sh --daemon看到FE进程起来之后用MySQL客户端连一下。Doris兼容MySQL协议所以任何mysql客户端都可以mysql -h127.0.0.1 -P9030 -uroot进去之后先看FE状态SHOW FRONTENDS;我遇到过一种常见情况FE状态里Join字段是dead。这种通常是机器hostname解析问题需要检查/etc/hosts确保机器名能解析到本机IP。不解决的话后面注册BE始终成功不了。2.3 配置BE、注册BE并完成读写验证接着启动BE。先改BE配置cd ../be vi conf/be.conf我一般会改两个参数storage_root_pathBE数据目录多目录用英文逗号分隔比如/data1/doris,/data2/doris。be_port默认9060一般不用改。启动BEbin/start_be.sh --daemon注意BE启动后并不会自动加入集群必须手动注册。在MySQL客户端里执行ALTER SYSTEM ADD BACKEND 127.0.0.1:9050;这里的9050是BE的心跳端口be_heartbeat_port不是BE的RPC端口9060。很多人第一次部署时在这里填错填成9060会导致注册不上。记住ADD BACKEND填的是心跳端口默认9050。再看一下SHOW BACKENDS;Alive字段为true证明BE已经正常注册和心跳了。部署完不能只靠进程活着就算成功一定要做一轮真实的数据读写验证。先设置root密码避免裸奔SET PASSWORD FOR root PASSWORD(你的密码);然后建一个测试库表CREATE DATABASE test_db; CREATE TABLE test_db.user_log ( user_id BIGINT, event_time DATETIME, event_type VARCHAR(20), cost DECIMAL(12,2) ) DUPLICATE KEY(user_id, event_time) DISTRIBUTED BY HASH(user_id) BUCKETS 10 PROPERTIES (replication_num 1);单机部署时副本数只能配1因为只有一个BE如果replication_num默认是3建表会报错显式改成1就行。写入测试INSERT INTO test_db.user_log VALUES (1, 2024-01-01 10:00:00, click, 12.50), (2, 2024-01-01 10:05:00, buy, 99.00); SELECT user_id, SUM(cost) FROM test_db.user_log GROUP BY user_id;能正确返回结果单机部署就算成功了。3. 集群模式与高可用FE多节点组网和BE扩容缩容3.1 三种FE角色怎么搭配单机部署只能用来验证功能上生产之前必须把FE从单点变成多节点。Doris的FE分三种角色Leader负责写元数据一个集群只有一个Leader由Follower选举产生。Follower参与元数据写入和选举至少3个才能组成高可用集群。Observer只同步元数据副本不参与选举可以横向扩容来增加查询能力。生产环境最稳妥的搭配是3个Follower再加N个Observer。Observer专为扩展查询能力设计可以应对更多并发连接但元数据写入还是Leader在管。BE的规划更直接数据量决定节点数副本数建议2或3。副本3才能允许坏一台BE而不丢数据建表时配置replication_num为3。3.2 集群FE组网的具体步骤假设有三台机器规划如下fe1、fe2、fe3三个FE都是Follower角色be1、be2、be3三个BE先在fe1上启动第一个FEbin/start_fe.sh --daemon连接fe1把fe2和fe3注册为FollowerALTER SYSTEM ADD FOLLOWER fe2:9010; ALTER SYSTEM ADD FOLLOWER fe3:9010;注意这里填的端口是FE的edit_log_port默认9010不是MySQL协议端口9030。然后在fe2、fe3节点上分别带上helper参数启动FEbin/start_fe.sh --helper fe1:9010 --daemon--helper指定的是Leader节点地址这个参数只在第一次启动时用后续正常启动不需要带。验证SHOW FRONTENDS;看到两个新FE的Join和Alive都是trueFE集群就组好了。BE的处理和单机一样三台机器分别启动BE然后在任意一个FE上执行ALTER SYSTEM ADD BACKEND be1:9050; ALTER SYSTEM ADD BACKEND be2:9050; ALTER SYSTEM ADD BACKEND be3:9050;这里有个细节值得注意Doris只有在建表时才会根据当前BE列表分配分桶副本。如果你在三台BE都注册成功后再建表副本才能均衡分布如果表已经建好后面再扩容BE需要等Doris后台自动做数据均衡这个过程比较慢数据量越大越慢。所以生产集群一般是先把BE节点规划到位再建核心表。3.3 BE扩容缩容的正确操作扩容时新BE节点加入集群后Doris会自动把部分tablet搬迁过去。通过以下命令观察迁移进度SHOW BACKENDS;重点看TabletNum和DataUsedCapacity的变化这两个指标会慢慢趋于均衡。如果一台BE要下线千万不要直接kill进程否则副本数会在短时间内降低有一定数据风险。正确方法是在集群里执行ALTER SYSTEM DECOMMISSION BACKEND be3:9050;这个命令会把该BE上的数据先迁移到其他节点迁移完成后自动把它摘除。这是Doris运维里最值得养成习惯的一个操作跟先备份再删库一个道理。4. 特殊环境部署Windows本地实测和Docker快速体验4.1 Windows上部署Doris能跑但有边界经常有人问Windows上能部署Doris吗我实测过测试环境下是能跑的但有一些坑要提前知道。首先是版本选择。官方没有提供Windows原生二进制包需要用Git Bash或WSLWindows Subsystem for Linux来跑官方Linux包。我的建议排序是WSL最省心Git Bash其次。用WSL的话本质上就是在一个Linux环境里部署按第2节的流程走就行几乎不会遇到Windows特殊性。用Git Bash则会遇到一些脚本兼容问题比如启动脚本里某些Linux命令在Windows环境下表现不一致常见的报错是printf: ILLEGAL OPTION。遇到这类错误不要慌多半是shell环境变量或脚本里的命令在Git Bash下不兼容不是Doris本身的问题。即使Windows部署成功了也只适合当开发库用别指望在生产Windows服务器上扛OLAP压力。Windows对文件句柄、磁盘IO、网络模型的限制在数据量上来之后会非常明显。如果你只是想在本地快速验证一个功能点我个人更推荐直接装Docker Desktop或者云上开一台Linux主机体验比Windows部署平滑得多。4.2 Docker Compose快速拉起Doris想快速体验Doris不想折腾环境变量可以用Docker。社区有apache/doris的官方镜像示例的compose配置大致长这样services: fe: image: apache/doris:2.0.12-fe ports: - 8030:8030 - 9030:9030 volumes: - ./fe.conf:/opt/apache-doris/fe/conf/fe.conf be: image: apache/doris:2.0.12-be depends_on: - fe volumes: - ./be.conf:/opt/apache-doris/be/conf/be.confDocker部署最大的价值是快速还原现场特别适合写Demo、做POC。但容器化在生产环境里对磁盘、网络、端口映射的绕行成本比较高我很少看到生产环境用容器方式跑Doris核心集群。如果真的要上生产物理机或云主机二进制部署更可控问题排查也更容易。5. 部署完的第一轮检查与业务接入高频问题5.1 部署后的健康巡检命令清单部署完成不等于万事大吉我给团队定了一个上线前巡检清单执行SHOW FRONTENDS;确认所有FE的Join/Alive都是true。执行SHOW BACKENDS;确认所有BE的Alive都是trueTabletNum没有持续异常增长。用mysql客户端执行一个简单聚合查询确保读写链路正常。访问FE的8030端口Web页面看监控概览。如果有Broker节点或扩展服务确认对应进程和配置正常。这里我特别建议巡检结果最好截图或存到文档里。部署完当天你可能记得很清楚过两个星期再排查问题这些基线数据会非常有用。5.2 SpringBoot连Doris超时怎么设置业务接入时SpringBoot项目用JDBC连Doris最常见的问题就是连接超时和查询超时。Doris走的是MySQL协议所以数据源配置跟MySQL很像但Doris上跑的通常是复杂的OLAP查询有时候确实会跑很久socketTimeout不能照搬MySQL那套短配置。一份可用的配置示例spring: datasource: url: jdbc:mysql://fe_host:9030/your_db?connectTimeout5000socketTimeout120000rewriteBatchedStatementstrueuseUnicodetruecharacterEncodingutf8 username: your_user password: your_password driver-class-name: com.mysql.cj.jdbc.DriverconnectTimeout控制建立连接的超时单位毫秒设3到5秒足够socketTimeout控制每条SQL读取的超时要按最慢的SQL来调设太短会导致慢查询动不动被掐断。rewriteBatchedStatementstrue对大批量写入很重要尤其用JDBC batch时性能差异非常大。还有一个容易踩的坑生产环境如果FE有多个节点JDBC连接要做HA。MySQL Connector/J支持在URL里配置多个FE地址jdbc:mysql://fe1:9030,fe2:9030,fe3:9030/your_db?loadBalanceAutoCommitStatementThreshold5连接器会把连接分散到多个FE上避免单点故障。只连一个FE当然也能跑但上生产别这么干。5.3 Variant类型Java侧写入半结构化JSONDoris 2.1.0版本引入了Variant类型。Variant可以动态推断JSON结构并存储不需要预先定义所有嵌套字段。对日志分析、行为数据这类非结构化场景特别实用。建表示例CREATE TABLE app_logs ( ts DATETIME, data VARIANT ) DUPLICATE KEY(ts) DISTRIBUTED BY HASH(ts) BUCKETS 10 PROPERTIES (replication_num 3);Java侧写入其实跟写普通字符串没区别把JSON字符串作为参数传进去就行。比如用JDBC PreparedStatementString json {\user_id\:123,\action\:\click\,\page\:\home\,\extra\:{\duration\:12.5}}; ps.setObject(2, json);Doris端会自动解析这个字符串并提取出子列。有几个坑要记住Variant里的嵌套字段查询时用点号路径访问比如data.extra.duration。同一字段在不同JSON里类型不一致比如有时候是空值有时候是字符串有时候是数字Doris在动态类型推断时可能出现类型冲突。建议写入前做一次格式清洗或者把易变字段设计成VARCHAR以换取兼容性。Variant字段不能作为分区分桶键。5.4 FlinkSQL写入Unique Key模型表FlinkSQL写入Doris unique key模型的表这个问题被问得很多。原因很直接Unique Key模型常见于实时数仓Flink又是最常用的实时计算引擎两者结合能实现实时写入按主键覆盖的效果。前提是引入Flink Doris Connector。在SQL作业里先创建Doris结果表核心配置如下CREATE TABLE doris_sink ( id INT, name STRING, update_time TIMESTAMP(3), PRIMARY KEY (id) NOT ENFORCED ) WITH ( connector doris, fenodes fe_host:8030, table.identifier db.user_config, username your_user, password your_password, sink.label-prefix flink_sink_, sink.properties.format json, sink.properties.read_json_by_line true, sink.enable.batch-mode true, sink.max-retries 3 );写入Unique Key模型表时Doris会根据key列执行replace合并。如果建的是明细模型Duplicate KeyFlink写入只是追加不会覆盖旧数据。这个区别必须和业务方确认清楚否则会出现明明Flink跑了数据却重复了的困惑。Flink侧还要注意一点尽量让相同key的数据落在同一个sink子任务否则两个子任务同时写同一个key可能出现乱序覆盖。现实中通常会在Flink SQL里按主键key做分组或者合理设置并行度。如果你用的Unique Key表开了部分列更新partial updateDoris Sink写入时对JSON格式的字段解析会有一些额外要求比如可能需要通过__op字段标识upsert或delete。这类高级配置建议直接看当前connector版本的官方文档老版本对部分列更新的支持不完整不要想当然。5.5 手动触发对表的合并compaction搜索doris 手动触发对表的合并的人多半是部署完数据高频写入后遇到了小文件多、查询变慢的情况。Doris内部对每个tablet的数据做分层存储后台会持续进行compaction把小文件合并成大文件。正常情况下不需要干预。但如果写入量大、写入频率高BE的compaction有时跟不上小文件堆积导致查询扫描路径变长、CPU开销变大。这时候可以做两件事。第一查看compaction状态。BE提供了HTTP接口比如curl http://be_host:8040/api/compaction/run_status?tablet_idxxx可以在BE节点上查看某个tablet的compaction运行情况。不同版本接口路径可能有差异以当前版本官方文档为准。第二确认需要干预时再手动触发一次性compaction。老版本提供的大致接口是curl http://be_host:8040/api/compaction/run?tablet_idxxxschema_hashxxx触发后会有一个后台任务在BE上执行合并。这里我要强调一点手动触发compaction在大多数生产场景不是常规操作。频繁手动触发反而会给BE造成额外压力得不偿失。更合理的做法是控制导入批次和文件大小比如增大Stream Load单批数据量减少小文件生成。合理设置表属性让Doris的compaction策略与写入节奏匹配。让Doris自行调度compaction除非明确看到某个tablet小文件数量异常再手动干预。换句话说这个需求多半是因为写入模式设计不当导致的。先调整写入方式再考虑手动merge。6. 从能跑到好用慢查询排查与后续建设6.1 一条SQL慢在哪里先看执行计划部署完Doris团队用得越深慢查询优化就越重要。第一个建议不要凭感觉优化SQL先看执行计划。在MySQL客户端里执行EXPLAIN SELECT user_id, COUNT(*) FROM user_log WHERE event_time 2024-01-01 GROUP BY user_id;Doris会输出查询计划树主要看三处Tablet扫描数量如果扫描了全部tablet说明分区裁剪或分桶裁剪没有生效。Join方式Doris会用BROADCAST广播小表或SHUFFLE重分区执行Join选错往往是慢的根源。聚合下推情况尽早做partial aggregate的SQL性能远好于全部数据拉到上层再聚合。对于线上已经发生的慢查询可以查审计日志。Doris的审计插件会把慢SQL写到日志或内表里按执行时间排序找耗时Top N比一个个问业务方有效得多。6.2 表结构与Join方式对查询的影响影响Doris查询性能最大的三个因素分区分桶键选没选对。分区裁剪可以让你只扫一个月的数据而不是扫全表。比如日志表按天分区查询条件带一天范围就能只扫描对应分区。分桶键和查询过滤条件的匹配度。如果where条件里的等值字段恰好是分桶键Doris可以直接定位少量分桶避免全表扫描。数据模型选择。明细Duplicate Key、聚合Aggregate Key、更新Unique Key三种模型的适用场景完全不同。部署后第一版表结构可以先粗一点但上线前一定要重新审视模型是否合理。比如高频更新的数据放进Duplicate模型会导致重复行很伤统计结果。关于广播Join和Shuffle Join说一个很典型的例子如果一个大表和一个小表Join小表只有几千行Doris默认会把它当作广播表分发给每个BE避免shuffle大表。但当小表实际上有几百万行时广播成本会很高这时候应该手动给Join加hint让它走shuffle join。配合EXPLAIN看执行计划能很直观地判断当前到底走了哪种方式。物化视图和BloomFilter索引是另外两个常用的调优手段。物化视图适合提前聚合高频查询BloomFilter索引适合高基数字段的过滤。这些功能部署完可以先不用等业务量上来之后按需添加。6.3 部署后的扩展方向监控、备份与跨集群最后快速说下部署完要做的三件事不然集群跑起来之后会越来越被动。监控方面Doris的FE自带Web页面和metrics接口可以接入Prometheus。建议把FE和BE的进程存活、查询QPS、导入TPS、tablet状态、compaction队列都做成告警。等到线上出问题再补监控通常已经晚了。备份方面Doris有Backup/Restore功能可以把库表备份到远端存储比如S3或HDFS。这是按表级别操作的部署早期就养成定期备份习惯后面运维会轻松很多。跨集群方面如果以后要做读写分离或者把数据同步给外部系统可以了解CCRCross Cluster Replication它能在两个Doris集群之间做表级同步。这块不是部署阶段的必修课但知道有这么个能力以后做架构扩展时会少很多不确定性。我记得第一次部署Doris的时候最大的感受是这个东西装起来不算难但用好的门道特别多。安装只是开始真正花时间的往往在部署完的那些天——业务方问连接超时怎么调、JSON怎么存、Flink怎么接、查询怎么变快。如果你按这篇文章的顺序把集群搭起来再逐条验证我列出的巡检项应该能少走不少弯路。最后留一个建议不管什么环境动手前一定先把当前版本官方文档的安装手册翻一遍版本差异带来的坑是最不值得踩的坑。
返回列表