背景:kafka存储数据时可以向多个slave节点去放数据,es刚开始也参考了这种做法,后来又没有采用这种方式,因为kafka默认存储是2周的,而es不行,采取的策略是利用这种冷热分离的办法.指定好数据分层的策略,包括
- 热数据快速访问
- 冷数据成本优化
- 自动生命周期管理
1.0 Kafka 的存储特点:
// Kafka 配置示例
Properties props = new Properties();
props.put("log.retention.hours", 336); // 2周数据保留
props.put("log.retention.bytes", 1073741824); // 1GB
props.put("replica.factor", 3); // 3个副本
主要特点:
- 数据默认保留时间短(2周)
- 数据按时间顺序追加写入
- 读取通常是最近的数据
- 数据过期自动删除
- 副本机制简单直接
2.0 Elasticsearch 的存储特点
// ES 冷热分离配置示例
PUT _ilm/policy/data_lifecycle_policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50GB",
"max_age": "1d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"forcemerge": {
"max_num_segments": 1
},
"shrink": {
"number_of_shards": 1
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"searchable_snapshot": {
"snapshot_repository": "cold_backup"
},
"allocate": {
"require": {
"data": "cold"
}
}
}
}
}
}
}
主要特点:
- 数据保留时间长
- 随机读写频繁
- 复杂的查询需求
- 数据量庞大
- 检索性能要求高
3.0为什么 ES 采用冷热分离更合适:
@Service
@Slf4j
public class DataStorageAnalysis {
/**
* Kafka 数据访问模式
*/
public void kafkaDataAccess() {
// 1. 顺序写入
producer.send(new ProducerRecord<>("topic", data));
// 2. 按照 offset 顺序读取
consumer.poll(Duration.ofMillis(100));
// 3. 数据自动过期
// log.retention.hours 控制
}
/**
* ES 数据访问模式
*/
public void esDataAccess() {
// 1. 复杂查询
SearchRequest searchRequest = new SearchRequest("index")
.source(new SearchSourceBuilder()
.query(QueryBuilders.boolQuery()
.must(QueryBuilders.rangeQuery("timestamp")
.from(startTime)
.to(endTime))
.must(QueryBuilders.termQuery("field", value))
)
.aggregation(AggregationBuilders.terms("agg").field("field"))
);
// 2. 数据分层存储
// hot: 最近数据,高性能存储
// warm: 较旧数据,普通存储
// cold: 历史数据,低成本存储
}
}
4.0 性能对比:
public class PerformanceComparison {
/**
* Kafka 性能特点
*/
public void kafkaPerformance() {
// 1. 顺序写入,性能高
// 2. 数据量有限,全内存操作
// 3. 简单的复制机制
// 4. 适合流式处理
}
/**
* ES 性能特点
*/
public void esPerformance() {
// 1. 随机读写,需要索引
// 2. 数据量大,需要分层
// 3. 复杂的分片复制机制
// 4. 适合复杂查询
}
}
5.0 存储成本对比:
public class StorageCostAnalysis {
/**
* Kafka 存储成本
*/
public void kafkaStorageCost() {
// 1. 短期存储,成本可控
// 2. 简单的副本机制
// 3. 存储空间自动回收
}
/**
* ES 存储成本
*/
public void esStorageCost() {
// 1. 长期存储,成本高
// 2. 需要分层存储策略
// 3. 冷热分离降低成本
// 4. 数据压缩和归档
}
}
主要区别:
- 使用场景:
- Kafka:消息队列,流式处理
- ES:数据检索,复杂查询
- 数据特点:
- Kafka:短期、顺序访问
- ES:长期、随机访问
- 存储策略:
- Kafka:简单副本
- ES:冷热分离
- 性能考虑:
- Kafka:写入性能优先
- ES:查询性能优先
- 成本控制:
- Kafka:自动过期控制成本
- ES:分层存储优化成本
ES这种存储设计充分考虑了 ES 的使用特点,通过冷热分离既保证了查询性能,又优化了存储成本,是一种更适合 ES 的存储策略。