ElasticSearch教程FG037-ElasticSearch分表分库实战
内容简介:本文档风哥主要介绍ElasticSearch分表分库的概念、实现方法以及最佳实践,包括时间序列索引、自定义分片策略、索引别名管理、数据迁移与同步等内容。通过学习本文,您将掌握如何使用ElasticSearch实现分表分库,提高集群性能和可扩展性。风哥教程参考ElasticSearch官方文档Index Management部分。
Part01-基础概念与理论知识
1.1 分表分库概述
分表分库是指将数据分散存储在多个表或数据库中的策略,以提高系统性能和可扩展性。在ElasticSearch中,分表分库主要通过以下方式实现:
- 时间序列索引:按时间创建索引,如按天、按月创建索引
- 自定义分片:根据业务逻辑将数据分散到不同的索引中
- 索引别名:使用别名管理多个索引,提供统一的访问接口
1.2 分表分库的优势
分表分库的优势包括:
- 提高性能:减少单个索引的大小,提高查询速度
- 提高可扩展性:可以通过添加索引来扩展存储容量
- 便于数据管理:可以针对不同时间或业务的数据进行单独管理
- 优化资源使用:可以根据数据的重要性分配不同的资源
- 提高可靠性:减少单个索引故障的影响范围
1.3 分表分库策略
常见的分表分库策略包括:
- 时间策略:按时间维度分表,如按天、按月、按年
- 业务策略:按业务维度分表,如按用户、按产品
- 哈希策略:使用哈希函数将数据分散到不同的索引中
- 范围策略:按数据范围分表,如按ID范围、按金额范围
Part02-生产环境规划与建议
2.1 分表分库设计
分表分库设计建议:
- 数据量评估:评估数据增长速度和总量,确定分表策略
- 查询模式分析:分析查询模式,选择合适的分表策略
- 索引大小控制:控制单个索引的大小,一般不超过30GB
- 分片数规划:根据节点数和数据量规划合理的分片数
2.2 分片策略选择
分片策略选择建议:
- 时间序列数据:使用时间策略,按天或按月创建索引
- 业务数据:使用业务策略,按业务维度分表
- 随机数据:使用哈希策略,均匀分散数据
- 范围数据:使用范围策略,按数据范围分表
2.3 索引命名规范
索引命名规范建议:
- 时间序列索引:使用格式如 fgedu-logs-2024.01.01
- 业务索引:使用格式如 fgedu-orders-user123
- 版本控制:使用格式如 fgedu-products-v1
- 一致性:保持索引命名的一致性,便于管理
Part03-生产环境项目实施方案
3.1 时间序列索引
时间序列索引:
curl -X PUT “http://192.168.1.10:9200/_index_template/fgedu-logs-template” -H “Content-Type: application/json” -d ‘{
“index_patterns”: [“fgedu-logs-*”],
“priority”: 100,
“template”: {
“settings”: {
“number_of_shards”: 3,
“number_of_replicas”: 2
},
“mappings”: {
“properties”: {
“timestamp”: {
“type”: “date”
},
“message”: {
“type”: “text”
},
“level”: {
“type”: “keyword”
}
}
}
}
}’
# 2. 创建当天索引
curl -X PUT “http://192.168.1.10:9200/fgedu-logs-$(date +%Y.%m.%d)”
# 3. 插入测试数据
curl -X POST “http://192.168.1.10:9200/fgedu-logs-$(date +%Y.%m.%d)/_bulk” -H “Content-Type: application/json” -d ‘{
“index”: {}
{“timestamp”: “2024-01-01T00:00:00Z”, “message”: “Test log 1”, “level”: “INFO”}
{“index”: {}
{“timestamp”: “2024-01-01T00:01:00Z”, “message”: “Test log 2”, “level”: “ERROR”}
}’
# 4. 查询时间范围数据
curl -X POST “http://192.168.1.10:9200/fgedu-logs-*/_search” -H “Content-Type: application/json” -d ‘{
“query”: {
“range”: {
“timestamp”: {
“gte”: “2024-01-01”,
“lte”: “2024-01-31”
}
}
}
}’
3.2 自定义分片策略
自定义分片策略:
curl -X PUT “http://192.168.1.10:9200/_index_template/fgedu-users-template” -H “Content-Type: application/json” -d ‘{
“index_patterns”: [“fgedu-users-*”],
“priority”: 100,
“template”: {
“settings”: {
“number_of_shards”: 2,
“number_of_replicas”: 1
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“email”: {
“type”: “keyword”
}
}
}
}
}’
# 2. 按用户ID范围创建索引
curl -X PUT “http://192.168.1.10:9200/fgedu-users-1-1000”
curl -X PUT “http://192.168.1.10:9200/fgedu-users-1001-2000”
curl -X PUT “http://192.168.1.10:9200/fgedu-users-2001-3000”
# 3. 插入测试数据
curl -X POST “http://192.168.1.10:9200/fgedu-users-1-1000/_doc/1” -H “Content-Type: application/json” -d ‘{
“id”: 1,
“name”: “张三”,
“email”: “zhangsan@example.com”
}’
curl -X POST “http://192.168.1.10:9200/fgedu-users-1001-2000/_doc/1001” -H “Content-Type: application/json” -d ‘{
“id”: 1001,
“name”: “李四”,
“email”: “lisi@example.com”
}’
3.3 索引别名管理
索引别名管理:
curl -X POST “http://192.168.1.10:9200/_aliases” -H “Content-Type: application/json” -d ‘{
“actions”: [
{
“add”: {
“index”: “fgedu-logs-2024.01.01”,
“alias”: “fgedu-logs-current”
}
}
]
}’
# 2. 切换索引别名
curl -X POST “http://192.168.1.10:9200/_aliases” -H “Content-Type: application/json” -d ‘{
“actions”: [
{
“remove”: {
“index”: “fgedu-logs-2024.01.01”,
“alias”: “fgedu-logs-current”
}
},
{
“add”: {
“index”: “fgedu-logs-2024.01.02”,
“alias”: “fgedu-logs-current”
}
}
]
}’
# 3. 查询别名
curl -X GET “http://192.168.1.10:9200/_alias/fgedu-logs-current”
# 4. 通过别名查询数据
curl -X POST “http://192.168.1.10:9200/fgedu-logs-current/_search” -H “Content-Type: application/json” -d ‘{
“query”: {
“match_all”: {}
}
}’
3.4 数据迁移与同步
数据迁移与同步:
curl -X POST “http://192.168.1.10:9200/_reindex” -H “Content-Type: application/json” -d ‘{
“source”: {
“index”: “fgedu-old-index”
},
“dest”: {
“index”: “fgedu-new-index”
}
}’
# 2. 使用scroll API批量迁移数据
# 初始化scroll
curl -X POST “http://192.168.1.10:9200/fgedu-old-index/_search?scroll=1m” -H “Content-Type: application/json” -d ‘{
“size”: 1000,
“query”: {
“match_all”: {}
}
}’
# 处理scroll结果并批量导入
# 示例脚本
#!/bin/bash
# migrate.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
SCROLL_ID=$(curl -s -X POST “http://192.168.1.10:9200/fgedu-old-index/_search?scroll=1m” -H “Content-Type: application/json” -d ‘{“size”: 1000, “query”: {“match_all”: {}}}’ | jq -r ‘./_scroll_id’)
while true; do
RESPONSE=$(curl -s -X POST “http://192.168.1.10:9200/_search/scroll” -H “Content-Type: application/json” -d ‘{“scroll”: “1m”, “scroll_id”: “‘$SCROLL_ID'”}’)
HITS=$(echo $RESPONSE | jq -r ‘.hits.hits | length’)
if [ $HITS -eq 0 ]; then
break
fi
# 处理数据并导入到新索引
echo $RESPONSE | jq -c ‘.hits.hits[] | {“index”: {“_id”: ._id}, “_source”: ._source}’ > bulk_data.json
curl -X POST “http://192.168.1.10:9200/fgedu-new-index/_bulk” -H “Content-Type: application/json” –data-binary @bulk_data.json
done
Part04-生产案例与实战讲解
4.1 时间序列索引实战
时间序列索引实战:
curl -X PUT “http://192.168.1.10:9200/_index_template/fgedu-logs-template” -H “Content-Type: application/json” -d ‘{
“index_patterns”: [“fgedu-logs-*”],
“priority”: 100,
“template”: {
“settings”: {
“number_of_shards”: 3,
“number_of_replicas”: 2
},
“mappings”: {
“properties”: {
“timestamp”: {
“type”: “date”
},
“message”: {
“type”: “text”
},
“level”: {
“type”: “keyword”
},
“service”: {
“type”: “keyword”
}
}
}
}
}’
# 2. 创建索引管理脚本
vi /es/app/scripts/create-index.sh
#!/bin/bash
# create-index.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# 创建当天索引
INDEX_NAME=”fgedu-logs-$(date +%Y.%m.%d)”
# 检查索引是否存在
EXIST=$(curl -s -X HEAD “http://192.168.1.10:9200/$INDEX_NAME” | grep -E “200|302”)
if [ -z “$EXIST” ]; then
echo “Creating index: $INDEX_NAME”
curl -X PUT “http://192.168.1.10:9200/$INDEX_NAME”
else
echo “Index $INDEX_NAME already exists”
fi
# 设置执行权限
chmod +x /es/app/scripts/create-index.sh
# 3. 添加到crontab,每天凌晨创建新索引
crontab -e
# 添加以下内容
0 0 * * * /es/app/scripts/create-index.sh
# 4. 测试索引创建
/es/app/scripts/create-index.sh
# 5. 验证索引创建
curl -X GET “http://192.168.1.10:9200/_cat/indices/fgedu-logs-*?v”
4.2 自定义分片策略实战
自定义分片策略实战:
curl -X PUT “http://192.168.1.10:9200/_index_template/fgedu-products-template” -H “Content-Type: application/json” -d ‘{
“index_patterns”: [“fgedu-products-*”],
“priority”: 100,
“template”: {
“settings”: {
“number_of_shards”: 2,
“number_of_replicas”: 1
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“price”: {
“type”: “float”
},
“category”: {
“type”: “keyword”
}
}
}
}
}’
# 2. 按类别创建索引
curl -X PUT “http://192.168.1.10:9200/fgedu-products-electronics”
curl -X PUT “http://192.168.1.10:9200/fgedu-products-clothing”
curl -X PUT “http://192.168.1.10:9200/fgedu-products-home”
# 3. 插入测试数据
curl -X POST “http://192.168.1.10:9200/fgedu-products-electronics/_doc/1” -H “Content-Type: application/json” -d ‘{
“id”: 1,
“name”: “iPhone 14”,
“price”: 5999,
“category”: “electronics”
}’
curl -X POST “http://192.168.1.10:9200/fgedu-products-clothing/_doc/1” -H “Content-Type: application/json” -d ‘{
“id”: 1,
“name”: “T-Shirt”,
“price”: 99,
“category”: “clothing”
}’
# 4. 查询特定类别的产品
curl -X POST “http://192.168.1.10:9200/fgedu-products-electronics/_search” -H “Content-Type: application/json” -d ‘{
“query”: {
“match_all”: {}
}
}’
4.3 索引别名管理实战
索引别名管理实战:
curl -X POST “http://192.168.1.10:9200/_aliases” -H “Content-Type: application/json” -d ‘{
“actions”: [
{
“add”: {
“index”: “fgedu-products-electronics”,
“alias”: “fgedu-products”
}
},
{
“add”: {
“index”: “fgedu-products-clothing”,
“alias”: “fgedu-products”
}
},
{
“add”: {
“index”: “fgedu-products-home”,
“alias”: “fgedu-products”
}
}
]
}’
# 2. 查询别名
curl -X GET “http://192.168.1.10:9200/_alias/fgedu-products”
# 3. 通过别名查询所有产品
curl -X POST “http://192.168.1.10:9200/fgedu-products/_search” -H “Content-Type: application/json” -d ‘{
“query”: {
“match_all”: {}
}
}’
# 4. 添加新索引到别名
curl -X PUT “http://192.168.1.10:9200/fgedu-products-sports”
curl -X POST “http://192.168.1.10:9200/_aliases” -H “Content-Type: application/json” -d ‘{
“actions”: [
{
“add”: {
“index”: “fgedu-products-sports”,
“alias”: “fgedu-products”
}
}
]
}’
4.4 数据迁移与同步实战
数据迁移与同步实战:
curl -X PUT “http://192.168.1.10:9200/fgedu-old-products” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 1,
“number_of_replicas”: 0
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“price”: {
“type”: “float”
}
}
}
}’
# 2. 插入测试数据
curl -X POST “http://192.168.1.10:9200/fgedu-old-products/_bulk” -H “Content-Type: application/json” -d ‘{
“index”: {}
{“id”: 1, “name”: “Product 1”, “price”: 100}
{“index”: {}
{“id”: 2, “name”: “Product 2”, “price”: 200}
{“index”: {}
{“id”: 3, “name”: “Product 3”, “price”: 300}
}’
# 3. 创建新索引
curl -X PUT “http://192.168.1.10:9200/fgedu-new-products” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 3,
“number_of_replicas”: 2
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“price”: {
“type”: “float”
},
“category”: {
“type”: “keyword”
}
}
}
}’
# 4. 使用reindex API迁移数据
curl -X POST “http://192.168.1.10:9200/_reindex” -H “Content-Type: application/json” -d ‘{
“source”: {
“index”: “fgedu-old-products”
},
“dest”: {
“index”: “fgedu-new-products”
},
“script”: {
“source”: “ctx._source.category = \”general\””
}
}’
# 5. 验证数据迁移
curl -X GET “http://192.168.1.10:9200/fgedu-new-products/_search?pretty”
Part05-风哥经验总结与分享
5.1 分表分库最佳实践
- 合理选择分表策略:根据数据特点和查询模式选择合适的分表策略
- 控制索引大小:单个索引大小一般不超过30GB,避免影响性能
- 使用索引别名:通过索引别名提供统一的访问接口,简化应用开发
- 自动化管理:使用脚本自动化索引的创建、管理和清理
- 监控与告警:监控索引大小和性能,及时发现和解决问题
- 定期维护:定期清理过期数据,优化索引结构
5.2 常见问题与解决方案
- 索引过多:合理规划索引创建策略,避免创建过多索引
- 查询性能下降:优化查询语句,使用合适的索引别名
- 数据迁移失败:使用reindex API时注意分批处理,避免超时
- 索引管理复杂:使用脚本自动化索引管理,减少人工操作
- 存储空间不足:配置索引生命周期,定期清理过期数据
5.3 性能优化建议
- 分片数优化:根据节点数和数据量设置合理的分片数
- 查询优化:使用合适的查询语句,避免跨过多索引查询
- 缓存优化:合理配置缓存,提高查询性能
- 存储优化:使用SSD存储,提高I/O性能
- 网络优化:确保节点间网络连接稳定,延迟低
- 监控优化:建立完善的监控体系,及时发现性能问题
更多视频教程www.fgedu.net.cn
学习交流加群风哥微信: itpux-com
学习交流加群风哥QQ113257174
风哥提示:分表分库是ElasticSearch处理海量数据的重要策略,需要合理设计和管理
更多学习教程公众号风哥教程itpux_com
from ElasticSearch视频:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
