3、日志存储与索引:Elasticsearch集群搭建、索引生命周期管理(ILM)、分片与副本策略、冷热数据分层
金融Agent跑起来之后,日志就像潮水一样涌来。我见过不少团队,日志系统跑着跑着就崩了,查询越来越慢,磁盘空间报警。说白了,日志存储不是简单的“写进去、查出来”,你得从一开始就规划好。
这一章,我们聊聊Elasticsearch。它是金融日志的标配存储引擎。怎么搭集群?怎么管理索引的生命周期?分片和副本怎么配?冷热数据怎么分层?嗯,这些都是实战中绕不开的坑。
3.1 Elasticsearch集群搭建:别让单点成为瓶颈
金融场景下,ES集群最少三节点起步。我个人习惯是奇数节点,方便选举。你想想看,如果只有两个节点,脑裂了怎么办?
搭建时,有几个关键参数必须调:
- discovery.seed_hosts:种子节点列表,别漏了
- cluster.initial_master_nodes:初始主节点,第一次启动时指定
- network.host:绑定IP,别用0.0.0.0裸奔
- path.data 和 path.logs:数据目录和日志目录分开,别挤在一起
我在项目中遇到过,有人把path.data和path.logs都放在系统盘,结果日志把根分区写满了,整个集群挂了。嗯,血的教训。
一个典型的docker-compose配置长这样:
version: '3.7'
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
container_name: es01
environment:
- node.name=es01
- cluster.name=fin-log-cluster
- discovery.seed_hosts=es02,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms4g -Xmx4g"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data01:/usr/share/elasticsearch/data
- logs01:/usr/share/elasticsearch/logs
ports:
- 9200:9200
es02:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
container_name: es02
environment:
- node.name=es02
- cluster.name=fin-log-cluster
- discovery.seed_hosts=es01,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms4g -Xmx4g"
volumes:
- data02:/usr/share/elasticsearch/data
- logs02:/usr/share/elasticsearch/logs
es03:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
container_name: es03
environment:
- node.name=es03
- cluster.name=fin-log-cluster
- discovery.seed_hosts=es01,es02
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms4g -Xmx4g"
volumes:
- data03:/usr/share/elasticsearch/data
- logs03:/usr/share/elasticsearch/logs
volumes:
data01:
data02:
data03:
logs01:
logs02:
logs03:
3.2 索引生命周期管理(ILM):让日志自动“退休”
金融Agent的日志量有多大?一天几十GB很正常。如果不做管理,索引会越来越多,查询越来越慢,磁盘迟早爆掉。
ILM就是干这个的。它定义了索引从创建到删除的完整生命周期。一般分四个阶段:
- Hot(热阶段):正在写入,频繁查询。用SSD,副本数可以少一点
- Warm(温阶段):不再写入,偶尔查询。用HDD,可以压缩
- Cold(冷阶段):很少查询,但需要保留。可以只保留一份数据
- Delete(删除阶段):过期数据,直接删掉
我建议你按天创建索引,比如fin-agent-logs-2025.01.15。然后配置一个ILM策略,让索引在7天后进入温阶段,30天后进入冷阶段,90天后删除。
一个典型的ILM策略配置:
PUT _ilm/policy/fin_agent_logs_policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50GB",
"max_age": "1d"
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": {
"number_of_shards": 1
},
"forcemerge": {
"max_num_segments": 1
},
"set_priority": {
"priority": 50
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"freeze": {},
"set_priority": {
"priority": 0
}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}
3.3 分片与副本策略:平衡的艺术
分片(shard)是ES分布式的基础。每个索引被分成多个分片,分布在不同的节点上。副本(replica)是分片的拷贝,用于高可用和读负载均衡。
分片数怎么定?我有个经验公式:
- 每个分片的大小控制在20GB到50GB之间
- 分片总数不要超过节点数乘以20
- 副本数一般设为1(即一份数据,一份备份)
举个例子:如果每天产生100GB日志,按50GB一个分片,就是2个分片。保留7天,总共14个分片。3个节点,每个节点约5个分片,很合理。
副本数不是越多越好。副本多了,写入性能会下降,因为每个分片都要复制。我建议:
- 热数据:副本数=1,保证高可用
- 温数据:副本数=0,节省空间
- 冷数据:副本数=0,只保留一份
配置示例:
PUT fin-agent-logs-2025.01.15
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 1
}
}
3.4 冷热数据分层:把钱花在刀刃上
金融日志有个特点:最近几天的数据查询最频繁,越老的数据越少人看。如果所有数据都放在SSD上,成本太高了。
冷热数据分层就是解决这个问题的。热节点用SSD,温节点用HDD,冷节点甚至可以上对象存储(比如S3)。
在ES里,通过节点角色来实现:
- hot节点:设置
node.roles: [ data_hot ] - warm节点:设置
node.roles: [ data_warm ] - cold节点:设置
node.roles: [ data_cold ]
然后,在ILM策略里指定每个阶段的数据迁移目标:
PUT _ilm/policy/fin_agent_logs_policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"allocate": {
"require": {
"data": "hot"
}
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"allocate": {
"require": {
"data": "warm"
}
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"allocate": {
"require": {
"data": "cold"
}
}
}
}
}
}
}
这样,数据会自动从热节点迁移到温节点,再到冷节点。你什么都不用管,ES自己搞定。
3.5 知识体系总览
下面这张图,把本章的核心逻辑串起来了。从集群搭建,到索引管理,再到分片策略和冷热分层,每一步都环环相扣。
好了,这一章的内容就这些。集群搭建、ILM、分片副本、冷热分层,每个点都是实战中必须掌握的。你把这些搞定了,金融Agent的日志存储基本不会出大问题。
公众号:蓝海资料掘金营,微信deep3321