技术探索从来不是一条直线,而是一条不断修正方向的路径
引言:技术选型背后的故事

我是一名从事后端系统架构设计多年的技术老兵。从业这么多年,最深的感受就是——技术本身并不是最难的部分,难的是如何在复杂、快速变化的业务场景中,找到一个既不过度设计又能支撑未来发展的平衡点。
这篇文章我想结合一个我们团队去年经历的实际项目案例来讲讲“深入理解技术探索与实践”的体会。这个项目不算大,但过程跌宕起伏,在技术选型、落地执行过程中踩了不少坑,也收获了很多经验。
希望这些经历能给你带来一些启发和参考价值。
项目背景:从0到1搭建企业级日志平台

我们服务的是一个中型互联网公司,内部有多个业务线,数据源繁杂,涉及Web、APP、IoT、第三方系统的日志收集和分析需求日益增长。原有的日志方案是基于ELK(Elasticsearch + Logstash + Kibana)的一套简单结构,仅用于日常排查问题,已经明显无法满足:
- 日志量快速增长带来的查询响应延迟
- 多租户支持缺失,不同业务的日志没有隔离机制
- 原始ELK方案缺乏自动化运维能力,升级扩容困难
- 没有统一的日志生命周期管理策略
- 缺乏可视化告警和集成看板能力
老板一声令下,我们开始从头规划一套全新的企业级日志平台,要求半年内上线,并且目标是为将来10倍增长做准备。
遇到的挑战:不是每个方案都“看起来好用”

我们的目标很明确:建设一个高可用、可扩展、易运维、低成本的企业日志平台。这听起来像是个老生常谈的话题,但真动手的时候才发现现实有多骨感。
第一阶段尝试(失败)
初期我们延续了ELK的老思路,采用Logstash+Filebeat+Elasticsearch+Grafana的组合进行构建。但很快暴露出了几个关键问题:
- Logstash资源消耗太高,性能瓶颈明显
- 单台服务器每秒只能处理5万~8万个事件(Event),CPU基本被打满。
- Elasticsearch写入压力大,频繁Full GC
- Filebeat在多节点部署时配置复杂,缺乏集中管理
更头疼的是,当时我们还没有成熟的运维平台,整套系统需要手动监控和巡检,故障恢复效率极低。
这时候我们就意识到,如果继续用ELK原始架构,根本扛不住未来的规模。
解决方案:技术选型的权衡与思考
在经过一次内部会议讨论之后,我们决定对技术栈进行重构。这次我们不再“盲目跟风”,而是回归本质,拆解了以下几点:
| 关键指标 | 目标 |
|---|---|
| 收集层稳定性 | 需要轻量化、低资源占用 |
| 数据清洗灵活性 | 支持规则配置化、多语言适配 |
| 存储扩展性 | 易于水平扩展、支持冷热分离 |
| 查询性能 | 降低高频查询的延迟 |
| 成本控制 | 尽量利用开源生态,减少商业组件依赖 |
带着这些诉求,我们做了几轮选型评估对比:
| 组件类型 | 可选项 | 我们的选择 |
|---|---|---|
| 收集器 | Filebeat, Fluent Bit, Loki | Fluent Bit + 自研采集Agent |
| 清洗/转换 | Logstash, Vector, Fluentd | Vector |
| 存储引擎 | Elasticsearch, OpenSearch, ClickHouse | ClickHouse + Elasticsearch |
| 查询展示 | Grafana, Superset, Redash | Grafana + 自定义看板 |
| 分布式协调 | ZooKeeper, ETCD, Consul | ETCD(与现有环境兼容) |
这套新架构最终帮助我们在性能、成本和运维方面取得了更好的平衡。
架构演进:新旧方案对比
旧版ELK架构图(简化)
Filebeat → Logstash → Elasticsearch → Kibana
优点:成熟、社区活跃
缺点:性能瓶颈显著,运维复杂度高
新版架构图(简化)
Agent/Fluent Bit → Vector → ClickHouse/Elasticsearch → Grafana
新版本架构的特点在于:
- 使用 Vector 替代Logstash,轻量、高效、内存安全;
- 使用 ClickHouse 替代部分Elasticsearch的存储和查询压力(特别是统计类日志场景);
- 对接Grafana实现灵活仪表盘展示;
- Agent自研,适配容器、宿主机等混合部署场景;
- 结合ETCD做元数据管理、服务发现等基础设施支持。
代码实践:几个核心模块的关键实现片段
1. Vector的数据管道配置示例(toml格式)
[source.stdin]
type = "stdin"
[transform.rename_fields]
type = "remap"
inputs = ["stdin"]
source = '''
.log_level = string!(.level)
del(.level)
'''
[sink.ch_log]
type = "clickhouse"
inputs = ["rename_fields"]
endpoint = "http://ch-node1:8123"
database = "logs"
table = "app_logs"
这段配置实现了从标准输入读取日志,重命名字段后写入ClickHouse数据库的功能。实际应用中我们会根据不同的业务日志类型编写多个Pipeline。
2. 自研Agent启动脚本逻辑(Python伪代码)
class LogCollector:
def __init__(self):
self.conf = self.load_config()
self.sources = []
def load_sources(self):
# 根据本地或远程配置加载日志采集源(文件、socket、journal等)
for src in self.conf['sources']:
if src.type == 'file':
self.sources.append(FileSource(src.path))
elif src.type == 'docker':
self.sources.append(ContainerSource())
def run(self):
while True:
for source in self.sources:
log_events = source.collect()
forward_to_vector(log_events) # 通过TCP转发给Vector实例
time.sleep(1)
if __name__ == "__main__":
collector = LogCollector()
collector.run()
这段代码展示了我们采集端的基本运行逻辑,它会自动识别多种日志源并推送到Vector节点上进行后续处理。
3. Grafana数据源配置(使用ClickHouse插件)
在Grafana中添加ClickHouse插件后,可以非常方便地通过SQL直接绘图。
SELECT
toStartOfHour(timestamp) AS hour,
count(*) AS total_logs
FROM app_logs
WHERE log_level = 'error'
GROUP BY hour
ORDER BY hour
这样就可以轻松生成按小时划分的错误日志数量曲线图。
踩坑经验:从实践中汲取教训
虽然整体架构跑起来了,但在推进过程中我们也踩了一些典型的坑,值得记录一下:
坑1:低估了ClickHouse的Schema变更代价
ClickHouse的列式结构在大数据量下查询性能优越,但它不支持原生的在线Alter Schema操作。
我们初期为了测试方便,直接在表里加了一个user_id字段,结果线上表几十亿条数据,导致ALTER TABLE ADD COLUMN几乎卡死了整个集群,甚至影响了其他查询任务。
教训总结:
- 在ClickHouse中做Schema变更前,一定要评估表数据量和变更耗时
- 长期来看建议引入Iceberg或者Delta Lake这类可变schema结构
坑2:Vector并发模型配置不当引发丢包
Vector默认是以单线程方式运行的,但我们初期没注意这一点,导致在高流量场景下出现丢包。
解决方式:
- 启用了multi-threaded模式:
[global]
max_cpu_cores = 4
- 同时优化了网络传输buffer大小
坑3:误删索引导致Elasticsearch重建耗时长
由于一开始对Elasticsearch的索引生命周期不够熟悉,曾误删过一个生产索引,导致第二天早上被报警吵醒——大量日志丢失。
解决方案:
- 加强权限管控,限制生产环境DELETE操作
- 建立每日快照策略
- 设置索引锁定策略(Index Read-Only Lock)
实施效果:不仅仅是性能提升
在新方案上线半年后,我们做了全面复盘,主要成果如下:
| 指标 | 上线前 | 上线后 | 提升幅度 |
|---|---|---|---|
| 写入吞吐 | 8w EPS | 50w EPS | 6.25倍 |
| 查询延迟(P99) | >5s | <300ms | 减少94% |
| 系统维护时间 | 每周约3小时 | 每月<1小时 | 大幅下降 |
| 日志保留周期 | 7天 | 90天(热数据) + 360天(冷归档) | 提升5倍以上 |
| 整体运维成本 | 高 | 中等 | 节省30%以上 |
更重要的是,随着系统的稳定运行,我们开始接入更多业务部门的需求:
- 金融风控部用来分析用户行为日志
- 运维团队建立了完整的异常检测体系
- 支撑了BI部门的实时报表系统
整个系统成为了公司基础设施的一部分,真正体现了“平台”的价值。
经验分享:关于技术探索的几点建议
如果你也在面对类似的日志平台搭建或其他技术难题,这里是我总结的一些实战建议:
1. 别盲从流行架构,先问自己“真实需要什么”
我见过很多团队上来就选Kubernetes+Istio+Envoy的全栈微服务架构,结果连CI/CD流程都没跑通。技术和架构应该服务于业务,而不是相反。
2. 技术选型是一个权衡的过程,没有银弹
每种技术都有其适用边界,比如:
- ELK适合全文检索场景,不适合大规模统计
- ClickHouse适合聚合分析,不适合文档搜索
- Vector适合轻量级管道处理,但不适合复杂的多阶段计算
了解你所选技术的“擅长领域”,才能发挥出最大效益。
3. 不要忽视团队的能力和知识储备
再牛的架构,如果没有人能维护也是灾难。比如我们在后期考虑引入Apache Iceberg的时候就停了下来——因为团队还没完全掌握Spark的调优技巧。
合适比先进更重要。
4. 做好长期演进的设计,避免过度重构
一个优秀的系统往往是在迭代中慢慢打磨出来的。不要一开始就想搞个“全能平台”,而是从解决当前痛点出发,逐步扩展。
我们在建设日志平台的时候也是这样,第一步先解决了稳定性和容量问题,第二步才引入多租户、告警等功能。
让技术随着业务一起成长,才是最好的节奏。
写在最后:技术探索,本质上是认知的进化
回顾整个项目的历程,其实并不都是顺利的。中间有很多深夜加班、也有争执和怀疑,甚至一度想放弃换回旧架构。
但回头来看,正是那些困难让我们一步步走到了今天,也让团队在技术认知、架构能力和协作方式上完成了一次质的飞跃。
我也越来越相信一句话:“优秀的架构是磨出来的,不是画出来的。”
希望通过这篇来自实战经验的分享,能给你一点启发。也希望你在自己的技术探索之路上,少走弯路,多些成就感。
愿你我都能在技术这条路上,走得坚定又从容。
📌 如果你觉得这篇文章对你有帮助,欢迎点赞收藏;若有问题或观点想交流,也可以留言告诉我。

评论 0