logsystem

logsystem是一道最近在facebook面试中经常遇到的问题,本文抛砖引玉,介绍我关于该问题的思考。

需求

是用来收集什么日志? => 收集手机app的crush记录
收集日志的目的? => 分析crush的原因 => 最好需要上层的查询分析接口
日志的存储时间?永久还是有期限? => 两年 or 永久?为了估算空间

数据特点

  1. Crush收集的记录可能经常会发生变化
    时间 模块 错误信息 栈信息等
  2. 写明显大于读

潜在的需求

  1. 数据安全性
  2. 日志的汇总
  3. 查询接口
  4. 严重bug通知

估计

并发量

考虑Facebook全球十亿台设备,万分之一的机会一台设备发生bug,那么每秒的平均请求量:

1000,000,000 / 100 = 1000w
1000w / 24 60 60 = 1000w / 8w = 250 qps
考虑巅峰是平均请求量的20倍,qps = 5000,仍然很小,并发压力不存在

容量

考虑一条crush记录,1kb。暂且考虑存2年,那么容量为:

1kb 1000w 365 * 2 = 8TB
开始时可考虑2块2TB磁盘

系统原型

mobile -> service -> queue
/ | \
storage aggregater alert

用户协议:可考虑http或者udp

从简单实现角度入手,采用http请求,发送json数据
考虑性能可采用udp,丢数据是可以接受的

Mobile

考虑实现:每次崩溃后,写入记录到本地,下次启动时发送。
优化: 发送时,对同类错误进行去重和汇总后发送,避免同一请求发送多次。

Service

功能:请求的路由,安全,流量控制。
最简单的办法采用Nginx,利用upstream模块,反向代理到消息队列中

Storage

非关系型数据存储,可考虑HBase, MongoDB。

Aggreagator

对数据按照时间、类型维度进行汇总,存入统一数据库,用于查询

设计可能存在的问题

数据跨地域存储,造成分析时难度。每次分析可能只能分析一个地域的数据。跨地域,跨表的Join的速度可能存在问题。

解法:考虑引入一个中间节点,定时汇总多个地域的数据。

nginx访问hbase可能因为网络问题等原因,造成短时间吞吐较低,形成瓶颈。

解法: 考虑nginx每次接收到Crush记录后,写入磁盘。由后台收集日志程序,发送请求到hbase端。

总结

在系统初期,在每个地域部署一台服务器,需要最少三台数据服务器,每个服务器需要至少2T硬盘,可坚持半年,并且每半年增加2T。
系统上线之后,可考虑加入日志收集模块,减少nginx与数据服务器的交互。并且引入数据汇聚节点,定期同步在各个地域的服务器。