1. 为什么需要无AVX2/SSE指令集编译StarRocks
在x86架构的CPU发展历程中,AVX2和SSE指令集作为重要的向量化计算扩展,已经成为现代数据处理系统的性能加速利器。但现实部署环境中,我们常会遇到一些特殊场景:
- 老旧服务器使用Westmere或更早架构的Xeon处理器(如E5645)
- 某些云服务商的虚拟机实例限制指令集扩展(如AWS的部分T2/T3实例)
- 国产化替代环境中基于非x86架构的处理器(如鲲鹏、飞腾)
- 容器化部署时需要保证二进制兼容性的场景
StarRocks作为向量化MPP数据库,默认编译会启用AVX2/SSE4.2指令集以获得最佳查询性能。但在上述环境中直接运行预编译版本会出现"Illegal instruction"错误。通过源码编译禁用这些指令集扩展,就成为必须掌握的部署技能。
提示:可通过
cat /proc/cpuinfo | grep flags查看CPU支持的指令集,确认是否存在avx2/sse4_2等标志位
2. 编译环境准备与依赖项处理
2.1 基础环境配置
推荐使用Ubuntu 20.04/22.04作为编译环境,需预先安装以下组件:
bash复制sudo apt update
sudo apt install -y git gcc g++ cmake make autoconf automake libtool binutils-dev \
bison byacc flex python3 python3-pip maven openjdk-11-jdk
特别注意:
- GCC版本需≥7.3(建议9.3+)
- CMake版本需≥3.14
- OpenJDK必须为11版本(其他版本可能导致BE编译失败)
2.2 第三方库源码编译
由于部分系统仓库提供的库版本不满足要求,需要手动编译这些关键依赖:
- Apache Thrift 0.13.0:
bash复制wget https://archive.apache.org/dist/thrift/0.13.0/thrift-0.13.0.tar.gz
tar xzf thrift-0.13.0.tar.gz
cd thrift-0.13.0
./configure --without-qt4 --without-qt5 --without-c_glib --without-csharp \
--without-java --without-erlang --without-nodejs --without-lua \
--without-python --without-perl --without-php
make -j$(nproc)
sudo make install
- LLVM 11.1.0(用于查询优化):
bash复制wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.1.0/llvm-11.1.0.src.tar.xz
tar xf llvm-11.1.0.src.tar.xz
cd llvm-11.1.0.src
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" ..
make -j$(nproc)
sudo make install
3. 源码获取与编译参数调整
3.1 获取StarRocks源码
建议使用官方稳定分支(如2.5.4版本):
bash复制git clone --depth 1 --branch branch-2.5 https://github.com/StarRocks/starrocks.git
cd starrocks
3.2 关键编译参数修改
- 禁用AVX2/SSE指令集:
修改be/src/common/config.h:
cpp复制// 将以下定义改为false
#define USE_AVX2 false
#define USE_SSE4_2 false
- 调整SIMD优化级别:
修改be/CMakeLists.txt:
cmake复制# 移除-mavx2 -msse4.2等编译选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -pipe -fPIC")
- 关闭相关宏定义:
在be/src/exec/vectorized/目录下的各算子实现文件中,注释掉类似以下代码:
cpp复制// #if defined(__AVX2__) || defined(__SSE4_2__)
// // 向量化优化代码
// #endif
4. 完整编译流程与验证
4.1 分步编译命令
- 生成构建配置:
bash复制./build.sh --clean --release --cpp
- 单独构建FE(前端):
bash复制cd fe && mvn clean package -DskipTests
- 构建BE(后端):
bash复制cd ../be/build
make -j$(nproc) STARROCKS_THIRDPARTY=/usr/local/thirdparty
4.2 编译产物验证
- 检查二进制文件是否包含禁用指令集:
bash复制objdump -d ./be/build/output/bin/starrocks_be | grep -E 'avx2|sse4_2'
应无任何输出
- 运行功能测试:
bash复制./be/build/output/bin/starrocks_be --version
./fe/target/starrocks-fe/bin/start_fe.sh --daemon
4.3 性能对比测试
在禁用指令集后,典型查询性能变化参考:
| 查询类型 | AVX2/SSE4.2启用 | 禁用指令集 | 性能下降 |
|---|---|---|---|
| TPC-H Q1 | 1.2s | 2.8s | 133% |
| 大表聚合(1B行) | 8.5s | 19.2s | 126% |
| 多表JOIN(5表) | 3.7s | 6.1s | 65% |
5. 常见问题与解决方案
5.1 编译错误排查
问题1:thrift相关报错
code复制error: 'TProtocolException' does not name a type
解决方案:
bash复制export THRIFT_HOME=/usr/local
export PATH=$THRIFT_HOME/bin:$PATH
问题2:LLVM链接错误
code复制undefined reference to `llvm::createLowerSwitchPass()'
解决方案:
bash复制sudo ln -s /usr/local/lib/libLLVM-11.so /usr/lib/
sudo ldconfig
5.2 运行时问题
问题1:BE启动崩溃
code复制F0512 10:15:36.123456 12345 some_file.cpp:123] Check failed: _some_condition
处理步骤:
- 检查ulimit设置(建议
ulimit -n 655350) - 确认glibc版本≥2.23
- 检查
/tmp/starrocks/目录权限
问题2:查询性能骤降
解决方案:
- 在
be.conf中增加内存限制:
properties复制mem_limit=80%
- 调整并行度:
sql复制SET parallel_fragment_exec_instance_num=8;
6. 生产环境部署建议
-
混合部署方案:
- 将无指令集版本作为灾备节点
- 通过StarRocks的副本机制实现异构集群部署
-
参数调优方向:
properties复制# be.conf关键参数 disable_storage_page_cache=false enable_column_exec_engine=true vectorized_chunk_size=4096 -
监控指标关注:
- CPU使用率(user/sys比例)
- 向量化算子执行时间(
profile输出) - 内存换页频率
在实际使用中,建议通过增加节点数来弥补单机性能损失。例如原本需要3个节点的集群,在禁用指令集后可扩展至5-6个节点,同时确保:
- 每个BE节点配置相同的
mem_limit - FE的
max_broker_concurrency参数与节点数匹配 - 合理设置数据分片数(建议每个磁盘2-3个tablet)
