以下是一个从 Elasticsearch 读取数据并写入 MySQL 的 Shell 脚本示例,包含关键步骤和注意事项:
完整脚本示例
bash
#!/bin/bash
# 配置 Elasticsearch 和 MySQL 连接信息
ES_HOST="http://localhost:9200"
ES_INDEX="your_index"
ES_QUERY='{ "query": { "match_all": {} }, "size": 1000 }' # 每次查询1000条
MYSQL_HOST="localhost"
MYSQL_USER="root"
MYSQL_PASS="your_password"
MYSQL_DB="your_database"
MYSQL_TABLE="your_table"
# 从 Elasticsearch 读取数据
read_es_data() {
curl -s -XGET "$ES_HOST/$ES_INDEX/_search" \
-H 'Content-Type: application/json' \
-d "$ES_QUERY" | jq -c '.hits.hits[]._source'
}
# 写入 MySQL
write_to_mysql() {
local json_data="$1"
# 提取字段(根据实际JSON结构调整)
id=$(echo "$json_data" | jq -r '.id')
name=$(echo "$json_data" | jq -r '.name')
timestamp=$(echo "$json_data" | jq -r '.timestamp // "NULL"') # 处理空值
# 构建 SQL 语句
mysql -h "$MYSQL_HOST" -u "$MYSQL_USER" -p"$MYSQL_PASS" "$MYSQL_DB" <<EOF
INSERT INTO $MYSQL_TABLE (id, name, timestamp)
VALUES ($id, '$name', FROM_UNIXTIME($timestamp));
EOF
}
# 主流程
main() {
# 读取 ES 数据
data=$(read_es_data)
total=$(echo "$data" | wc -l)
current=0
# 逐条处理
echo "$data" | while read -r line; do
write_to_mysql "$line"
((current++))
# 显示进度条
echo -ne "进度: [$((current * 100 / total))%]\r"
done
echo -e "\n导入完成!共导入 $total 条数据"
}
main
关键步骤解析
1. Elasticsearch 数据读取
-
使用
curl
调用 ES 的_search
API -
通过
jq
工具提取数据核心内容:bashjq -c '.hits.hits[]._source' # -c 输出紧凑格式
-
建议分页查询(示例中
size=1000
),大数据量时需实现滚动查询
2. 数据转换与清洗
-
空值处理 :使用
jq
的//
运算符提供默认值bashtimestamp=$(echo "$json_data" | jq -r '.timestamp // "NULL"')
-
类型转换 :例如将 UNIX 时间戳转为 MySQL 的
DATETIME
sqlFROM_UNIXTIME($timestamp)
3. MySQL 写入优化
-
批量插入 (高效方式):将数据写入临时文件后使用
LOAD DATA
bash# 生成 SQL 文件 echo "$data" | jq -r '@sql "INSERT INTO table VALUES (...)"' > temp.sql # 批量执行 mysql -u user -p db_name < temp.sql
-
事务控制 :在循环外包裹事务提升性能
sqlSTART TRANSACTION; -- 插入语句... COMMIT;
4. 错误处理增强
-
添加错误重试机制:
bashwrite_to_mysql() { # 重试最多3次 for i in {1..3}; do if insert_operation; then return 0 fi sleep 1 done echo "插入失败: $json_data" >> error.log }
-
记录失败数据到日志文件
环境准备
1. 安装依赖工具
bash
# 安装 jq(JSON 处理工具)
sudo apt-get install jq # Debian/Ubuntu
sudo yum install jq # CentOS/RHEL
# 安装 MySQL 客户端
sudo apt-get install mysql-client
2. 创建 MySQL 表结构
sql
CREATE TABLE your_table (
id INT PRIMARY KEY,
name VARCHAR(255),
timestamp DATETIME
);
注意事项
-
数据一致性
- 处理 ES 和 MySQL 的字段类型映射(如
keyword
→VARCHAR
) - 处理时区问题(建议统一使用 UTC)
- 处理 ES 和 MySQL 的字段类型映射(如
-
性能优化
- 大数据量时使用
scroll
API 分批次读取
json{ "size": 1000, "sort": ["_doc"] # 优化滚动性能 }
- 使用
parallel
命令并行处理(需调整脚本)
- 大数据量时使用
-
安全建议
-
不要在脚本中硬编码密码,改用配置文件:
bash# ~/.my.cnf [client] user = root password = your_password
-
使用 HTTPS 连接 Elasticsearch(生产环境)
-
扩展:结合进度条优化
使用之前的进度条代码改进显示效果:
bash
# 在显示进度部分替换为更直观的图形化进度条
progress=$((current * 50 / total))
echo -ne "[$(printf '%0.s#' $(seq 1 $progress))$(printf '%0.s ' $(seq 1 $((50 - progress))))] $current/$total\r"
通过这个脚本,你可以实现基础的 ES 到 MySQL 数据迁移。实际生产环境中建议:
- 使用专业工具(如 Logstash、DataX)
- 增加数据校验步骤
- 添加监控告警机制