背景
提到日志实时分析, 大部分人第一想到是社区很火 ELK Stack(Elastic/Logstash/Kibana).ELK 方案上手难度小, 开源材料众多, 在社区中有大量的使用案例.
阿里云日志服务 (SLS/Log) 是阿里巴巴集团对日志场景的解决方案产品, 前身是 2012 年初阿里云在研发飞天操作系统过程中用来监控 + 问题诊断的产物, 但随着用户增长与产品发展, 慢慢开始向面向 Ops(DevOps,Market Ops,SecOps) 日志分析领域发展(见下图), 期间经历双十一, 蚂蚁双十二, 新春红包, 国际业务等场景挑战, 成为同时服务内外的产品.
面向日志分析场景
搞搜索都知道 Apache Lucene(Lucene 是 Doug Cutting 2001 年贡献, Doug 也是 Hadoop 创始人).2012 年 Elastic 把 Lucene 基础库包成了一个更好用的软件, 并且在 2015 年推出 ELK Stack(Elastic Logstash Kibana)解决集中式日志采集, 存储和查询问题. Lucene 设计场景是 Information Retrial, 面对是 Document 类型, 因此对于 Log 这种数据有一定限制, 例如规模, 查询能力, 以及一些定制化功能 (例如智能聚类 LogReduce) 等.
SLS 提供日志存储引擎是阿里内部自研究技术, 经过 3 年 W 级应用锤炼, 每日索引数据量达 PB 级, 服务万级开发者每天亿次查询分析. 在阿里集团内阿里云全站, SQL 审计, 鹰眼, 蚂蚁云图, 飞猪 Tracing, 阿里云谛听等都选择 SLS 作为日志分析引擎.
- <div id="xe41iq" data-type="image" data-display="block" data-align="center" data-src="https://cdn.nlark.com/lark/0/2018/png/26154/1545743982489-63f095dc-da3c-4fd4-ab2a-52a055b15e10.png" data-width="747">
- <img src="https://cdn.nlark.com/lark/0/2018/png/26154/1545743982489-63f095dc-da3c-4fd4-ab2a-52a055b15e10.png" width="747" />
- </div>
而日志查询是 DevOps 最基础需求, 从业界的调研《50 Most Frequently Used Unix Command》也验证了这一点, 排名第一的是 tar, 第二的就 Grep 这个命令了, 由此可见他对程序员的重要性.
我们在日志查询分析场景上以如下点对 ELK 与 SLS 做一个全方位比较:
易用: 上手及使用过程中的代价
功能(重点): 主要针对查询分析两个场景
性能(重点): 对于单位大小数据量查询与分析需求, 延时如何
规模(重点): 能够承担的数据量, 扩展性等
成本: 同样功能和性能, 使用分别花多少钱
利益关系: 本人 SLS 研发可能带一些主观色彩, 但一切都以技术指标来对比, 如有偏颇请不吝指正
易用性
对日志分析系统而言, 有如下使用过程:
采集: 将数据稳定写入
配置: 如何配置数据源
扩容: 接入更多数据源, 更多机器, 对存储空间, 机器进行扩容
导出: 数据能否方便导出到其他系统, 例如做流计算, 放到对象存储中进行备份
多租户: 如何将数据能否分享给他人使用, 使用是否安全等
以下是比较结果:
采集
|
协议
|
|
|
|
客户端
|
|
|
配置
|
单元
|
|
|
|
属性
|
|
|
扩容
|
存储
|
|
|
|
计算
|
|
|
|
配置
|
|
|
|
采集点
|
|
|
|
容量
|
|
|
导出
|
方式
|
|
|
多租户
|
安全
|
|
|
|
流控
|
|
|
|
多租户
|
|
|
整体而言:
ELK 有非常多生态和写入工具, 使用中的安装, 配置等都有较多工具可以参考
SLS 是托管服务, 从接入, 配置, 使用上集成度非常高, 普通用户 5 分钟就可以接入, 但在生态与丰富度和 ELK 相比有较大差距
SLS 是 SaaS 化服务, 在过程中不需要担心容量, 并发等问题, 弹性伸缩, 免运维
功能(查询 + 分析)
查询主要将符合条件的日志快速命中, 分析功能是对数据进行统计与计算. 例如我们有如下需求: 所有大于 200 读请求, 根据 Ip 统计次数和流量, 这样的分析请求就可以转化为两个操作: 查询到指定结果, 对结果进行统计分析. 在一些情况下我们也可以不进行查询, 直接对所有日志进行分析.
- Query1:
- Status in (200,500] and Method:Get*
- Query2:
- select count(1) as c, sum(inflow) as sum_inflow, ip group by Ip
查询基础对比
参考: Elastic 6.5 Indices
类型 | 小项 | ELK | SLS |
---|---|---|---|
文本 | 索引查询 | 支持 | 支持 |
分词 | 支持 | 支持 | |
中文分词 | 支持 | 支持 | |
前缀 | 支持 | 支持 | |
后缀 | 支持 | ||
模糊 | 支持 | 可通过 SQL 支持 | |
Wildcast | 支持 | 可通过 SQL 支持 | |
数值 | long | 支持 | 支持 |
double | 支持 | 支持 | |
Nested | Json | 支持 | |
Geo | Geo | 支持 | 可通过 SQL 支持 |
Ip | Ip 查询 | 支持 | 可通过 SQL 支持 |
对比结论
ES 支持数据类型丰富度, 原生查询能力比 SLS 更完整
SLS 能够通过 SQL 方式 (如下) 来代替字符串模糊查询, Geo 等比较函数, 但性能会比原生查询稍差
子串命中
* | select content where content like '%substring%' limit 100
正则表达式匹配
* | select content where regexp_like(content, '\d+m')limit 100
JSON 内容解析与匹配
* | select content where json_extract(content, '$.store.book')='mybook' limit 100
如果设置 JSON 类型索引也可以使用:
field.store.book='mybook'
查询扩展能力
在日志分析场景中, 光有检索可能还不够, 需要能够围绕查询做进一步的工作:
定位到错误日志后, 想看看上下文是什么参数引起了错误
定位到错误后, 想看看之后有没有类似错误, 类似 tail -f 原始日志文件, 并进行 grep
通过关键词搜索到一大堆日志(例如百万条), 其中 90% 都是已知问题刚干扰调查线索
SLS 针对以上问题提供闭环解决方案:
上下文查询(Context Lookup): 原始上下文翻页, 免登服务器
LiveTail 功能(Tail-f): 原始上下文 tail-f, 更新实时情况
智能聚类(LogReduce): 根据日志 Pattern 动态归类, 合并重复模式, 洞察异常
查询扩展能力(1):LiveTail(云端 tail -f)
在传统的运维方式中, 如果需要对日志文件进行实时监控, 需要到服务器上对日志文件执行命令 tail -f, 如果实时监控的日志信息不够直观, 可以加上 grep 或者 grep -v 进行关键词过滤. SLS 在控制台提供了日志数据实时监控的交互功能 LiveTail, 针对线上日志进行实时监控分析, 减轻运维压力.
Livetail 特点如下:
智能支持 Docker,K8S, 服务器, Log4J Appender 等来源数据
监控日志的实时信息, 标记并过滤关键词
日志字段做分词处理, 以便查询包含分词的上下文日志
具体使用场景参见文档: https://help.aliyun.com/document_detail/93633.html
查询扩展能力(2): 智能聚类(LogReduce)
业务的高速发展, 对系统稳定性提出了更高的要求, 各个系统每天产生大量的日志, 你是否曾担心过:
系统有潜在异常, 但被淹没在海量日志中
机器被入侵, 有异常登录, 却后知后觉
新版本上线, 系统行为有变化, 却无法感知
这些问题, 归根到底, 是信息太多, 太杂, 不能良好归类, 同时记录信息的日志, 往往还都是无 Schema, 格式多样, 归类难道更大. SLS 提供实时日志智能聚类 (LogReduce) 功能根据日志的相似性进行归类, 快速掌握日志全貌:
支持任意格式日志: Log4J,JSON, 单行(syslog)
日志经任意条件过滤后再 Reduce; 对 Reduce 后 Pattern, 根据 signature 反查原始数据
不同时间段 Pattern 比较
动态调整 Reduce 精度
亿级数据, 秒级出结果
文档:
说明: https://yq.aliyun.com/articles/679078
文档: https://help.aliyun.com/document_detail/100039.html
分析能力对比
ES 在 docvalue 之上提供一层聚合 (Aggregation) 语法, 并且在 6.x 版本中提供 SQL 语法能够对数据进行分组聚合运算.
SLS 支持完整 SQL92 标准(提供 restful 和 jdbc 两种协议), 除基本聚合功能外, 支持完整的 SQL 计算, 并支持外部数据源联合查询(Join), 机器学习, 模式分析等函数.
参考: ES 6.5 Aggregation,SLS 分析语法
除 SQL92 标准语法外, 我们根据实际日志分析需求, 研发一系列实用的功能:
分析功能演示(1): 同比, 环比函数
同比环比函数能够通过 SQL 嵌套对任意计算 (单值, 多值, 曲线) 计算同环比(任意时段), 以便洞察增长趋势.
- * | select compare( pv , 86400) from (select count(1) as pv from log)
- *|select t, diff[1] as current, diff[2] as yestoday, diff[3] as percentage from(select t, compare( pv , 86400) as diff from (select count(1) as pv, date_format(from_unixtime(__time__), '%H:%i') as t from log group by t) group by t order by t) s
文档: https://help.aliyun.com/document_detail/86661.html
分析功能演示(2): 外部数据源联合查询(Join)
可以在查询分析中关联外部数
支持 logstore,MySQL,OSS(CSV)等数据源
支持 left,right,out,innerjoin
SQL 查询外表, SQLJoin 外表
Join 外表的样例:
sql
创建外表:
* | create table user_meta ( userid bigint, nick varchar, gender varchar, province varchar, gender varchar,age bigint) with ( endpoint='oss-cn-hangzhou.aliyuncs.com',accessid='LTA288',accesskey ='EjsowA',bucket='testossconnector',objects=ARRAY['user.csv'],type='oss')
使用外表
* | select u.gender, count(1) from chiji_accesslog l join user_meta1 u on l.userid = u.userid group by u.gender
云栖: https://yq.aliyun.com/articles/613365
文档: https://help.aliyun.com/document_detail/70479.html
分析功能演示(3): 地理位置函数
针对 IP 地址, 手机等内容, 内置地理位置函数方便分析用户来源, 包括:
IP: 国家, 省市, 城市, 经纬度, 运营商
Mobile: 运营商, 省市
GeoHash:Geo 位置与坐标转换
查询结果分析样例:
- sql
- * | SELECT count(1) as pv, ip_to_province(ip) as province WHERE ip_to_domain(ip) != 'intranet' GROUP BY province ORDER BY pv desc limit 10
- * | SELECT mobile_city(try_cast("mobile" as bigint)) as "城市", mobile_province(try_cast("mobile" as bigint)) as "省份", count(1) as "请求次数" group by "省份", "城市" order by "请求次数" desc limit 100
查询结果:
GeoHash:https://help.aliyun.com/document_detail/84374.html
IP 函数: https://help.aliyun.com/document_detail/63458.html
电话号码: https://help.aliyun.com/document_detail/98580.html
分析功能演示(4): 安全分析函数
依托全球白帽子共享安全资产库, 提供安全检测函数, 您只需要将日志中任意的 IP, 域名或者 URL 传给安全检测函数, 即可检测是否安全.
- security_check_ip
- security_check_domain
- security_check_url
文档: https://help.aliyun.com/document_detail/87093.html
分析功能演示(5): 机器学习与时序检测函数
新增机器学习与智能诊断系列函数:
1)根据历史自动学习其中规律, 并对未来的走势做出预测;
2)实时发现不易察觉的异常变化, 并通过分析函数组合推理导致异常的特征;
3)结合环比, 告警功能智能发现 / 巡检. 该功能适用在智能运维, 安全, 运营等领域, 帮助更快, 更有效, 更智能洞察数据.
提供的功能有:
预测: 根据历史数据拟合基线
异常检测, 变点检测, 折点检测: 找到异常点
多周期检测: 发现数据访问中的周期规律
时序聚类: 找到形态不一样的时序
文档: https://help.aliyun.com/document_detail/93024.html
云栖: https://yq.aliyun.com/articles/670718
分析功能演示(6): 模式分析函数
模式分析函数能够洞察数据中的特征与规律, 帮助快速, 准确推断问题:
定位频繁集
例如: 错误请求中 90% 由某个用户 ID 构成
定位两个集合中最大支持因素, 例如:
延时 > 10S 请求中某个 ID 构成比例远远大于其他维度组合
并且该 ID 在对比集合 (B) 中的比例较低
A 和 B 中差异明显
性能
接下来我们测试针对相同数据集, 分别对比写入数据及查询, 和聚合计算能力.
实验环境
测试配置
自建 ELK | LogSearch/LogAnalytics | |
---|---|---|
环境 | ECS 4 核 16GB * 4 台 + 高效云盘 SSD | |
Shard | 10 | 10 |
拷贝数 | 2 | 3 (默认配置,对用户不可见) |
测试数据
5 列 double,5 列 long,5 列 text, 字典大小分别是 256,512,768,1024,1280
以上字段完全随机(测试日志样例如下)
原始数据大小: 50 GB
日志行数: 162,640,232 (约为 1.6 亿条)
- timestamp:August 27th 2017, 21:50:19.000
- long_1:756,444 double_1:0 text_1:value_136
- long_2:-3,839,872,295 double_2:-11.13 text_2:value_475
- long_3:-73,775,372,011,896 double_3:-70,220.163 text_3:value_3
- long_4:173,468,492,344,196 double_4:35,123.978 text_4:value_124
- long_5:389,467,512,234,496 double_5:-20,10.312 text_5:value_1125
写入测试结果
ES 采用 bulk API 批量写入, SLS(LogSearch/Analytics)用 PostLogstoreLogs API 批量写入, 结果如下:
类型 | 项目 | 自建 ELK | LogSearch/Analytics |
---|---|---|---|
延时 | 平均写入延时 | 40 ms | 14 ms |
存储 | 单拷贝数据量 | 86G | 58G |
膨胀率:数据量 / 原始数据大小 | 172% | 121% |
备注: SLS 产生计费的存储量包括压缩的原始数据写入量(23G)+ 索引流量(27G), 共 50G 存储费用.
从测试结果来看
SLS 写入延时好于 ES,40ms vs 14 ms
空间: 原始数据 50G, 因测试数据比较随机所以存储空间会有膨胀(大部分真实场景下, 存储会因压缩后会比原始数据小).ES 胀到 86G, 膨胀率为 172%, 在存储空间超出 SLS 58%. 这个数据与 ES 推荐的存储大小为原始大小 2.2 倍比较接近.
读取 (查询 + 分析) 测试
测试场景
选取两种比较常见的场景: 日志查询和聚合计算. 分别统计并发度为 1,5,10 时, 两种 case 的平均延时.
针对全量数据, 对任意 text 列计算 group by, 计算 5 列数值的 avg/min/max/sum/count, 并按照 count 排序, 取前 1000 个结果, 例如:
- select count(long_1) as pv,sum(long_2),min(long_3),max(long_4),sum(long_5)
- group by text_1 order by pv desc limit 1000
针对全量数据, 随机查询日志中的关键词, 例如查询 "value_126", 获取命中的日志数目与前 100 行, 例如:
value_126
测试结果
类型 | 并发数 | ES 延时 (单位 s) | LogSearch/Analytics 延时 (单位 s) |
---|---|---|---|
case1:分析类 | 1 | 3.76 | 3.4 |
5 | 3.9 | 4.7 | |
10 | 6.6 | 7.2 | |
case2:查询类 | 1 | 0.097 | 0.086 |
5 | 0.171 | 0.083 | |
10 | 0.2 | 0.082 |
结果分析
从结果看, 对于 1.5 亿数据量这个规模, 两者都达到了秒级查询与分析能力
针对统计类场景(case 1), ES 和日志服务延时处同一量级. ES 采用 SSD 硬盘, 在读取大量数据时 IO 优势比较高
针对查询类场景(case 2), LogAnalytics 在延时明显优于 ES. 随着并发的增加, ELK 延时对应增加, 而 LogAnalytics 延时保持稳定甚至略有下降
规模与成本
1. 规模能力
SLS 可以处理 PB/Day 级数据, 一次查询可以在秒级过 TB 规模数据, 在数据规模上可以做到弹性伸缩与水平扩展
ES 比较适合服务场景为: 写入 GB-TB/Day, 存储在 TB 级. 主要受限于 2 个原因:
单集群规模: 比较理想为 20 台左右, 据我了解业界比较大为 100 节点一个集群, 为了应对业务往往拆成多个集群
写入扩容: shard 创建后便不可再修改, 当吞吐率增加时, 需要动态扩容节点, 最多可使用的节点数便是 shard 的个数
存储扩容: 主 shard 达到磁盘的上线时, 要么迁移到更大的一块磁盘上, 要么只能分配更多的 shard. 一般做法是创建一个新的索引, 指定更多 shard, 并且 rebuild 旧的数据
1.1 用户案例(规模带来的问题)
客户 A 是国内最大资讯类网站之一, 有数千台机器与百号开发人员. 运维团队原先负责一套 ELK 集群用来处理 Nginx 日志, 但始终处于无法大规模使用状态:
一个大 Query 容易把集群打爆, 导致其他用户无法使用
在业务高峰期间, 采集与处理能力打满集群, 造成数据丢失, 查询结果不准确
业务增长到一定规模, 因内存设置, 心跳同步等节点经常内存失控导致 OOM
不能保证可用性与准确性, 开发最终没有使用起来, 成为一个摆设.
在 2018 年 6 月份, 运维团队开始运行 SLS 方案:
使用 Logtail 来采集线上日志, 将采集配置, 机器管理等通过 API 集成进客户自己运维与管控系统
将 SLS 查询页面嵌入统一登录与运维平台, 进行业务与账户权限隔离
通过控制台内嵌方案满足开发查询日志需求, 通过 Grafana 插件调用 SLS 统一业务监控, 通过 DataV 连接 SLS 进行大盘搭建
控制台嵌入方案: https://help.aliyun.com/document_detail/74971.html
接入 Grafana:https://help.aliyun.com/document_detail/60952.html
接入 DataV:https://help.aliyun.com/document_detail/62961.html
对接 Jaeger:https://help.aliyun.com/document_detail/68035.html
整体架构如下图:
平台上线 2 个月后:
每天查询的调用量大幅上升, 开发逐步开始习惯在运维平台进行日志查询与分析, 提升了研发的效率, 运维部门也回收了线上登录的权限
除 Nginx 日志外, 把 App 日志, 移动端日志, 容器日志也进行接入, 规模是之前 10 倍
除查询日志外, 也衍生出很多新的玩法, 例如通过 Jaeger 插件与控制台基于日志搭建了 Trace 系统, 将线上错误配置成每天的告警与报表进行巡检
通过统一日志接入管理, 规范了各平台对接总线, 不再有一份数据同时被采集多次的情况, 大数据部门 Spark,Flink 等平台可以直接去订阅实时日志数据进行处理
2. 成本估计
以上述测试数据为例, 一天写入 50GB 数据(其中 27GB 为实际的内容), 保存 90 天, 平均一个月的耗费.
日志服务 (LogSearch/LogAnalytics) 计费规则参考, 包括读写流量, 索引流量, 存储空间等计费项, 查询功能免费.
计费项目 | 值 | 单价 | 费用 (元) |
---|---|---|---|
读写流量 | 23G * 30 | 0.2 元 / GB | 138 |
存储空间(保存 90 天) | 50G * 90 | 0.3 元 / GB*Month | 1350 |
索引流量 | 27G * 30 | 0.35 元 / GB | 283 |
总计 | 1771 |
ES 费用包括机器费用, 及存储数据 SSD 云盘费用
云盘一般可以提供高可靠性, 因此我们这里不计费副本存储量
存储盘一般需要预留 15% 剩余空间, 以防空间写满, 因此乘以一个 1.15 系数
计费项目 | 值 | 单价 | 费用 (元) |
---|---|---|---|
服务器 | 4 台 4 核 16G(三个月)(ecs.mn4.xlarge) | 包年包月费用:675 元 / Month | 2021 |
存储 | 86 * 1.15 * 90 (这里只计算一个副本) | SSD:1 元 / GB*M | 8901 |
SATA:0.35 元 / GB*M | 3115 | ||
总计 | 12943 (SSD) | ||
5135 (SATA) |
同样性能, 使用 SLS(SSD)费用比为 13.6%. 在测试过程中, 我们也尝试把 SSD 换成 SATA 以节省费用(SLS 与 SATA 版费用比为 34%), 但测试发现延时会从 40ms 上升至 150ms, 在长时间读写下, 查询和读写延时变得很高, 无法正常工作了.
3. 时间成本(Time to Value)
除硬件成本外, SLS 在新数据接入, 搭建新业务, 维护与资源扩容成本基本为 0:
支持各种日志处理生态, 可以和 Spark,Hadoop,Flink,Grafana 等系统无缝对接
在全球化部署(有 20+ Region), 方便拓展全球化业务
提供 30 + 日志接入 SDK, 与阿里云产品无缝打通集成
SLS 采集和可视化可以参见如下文章, 非核心功能不展开做比较
采集: https://yq.aliyun.com/articles/672576
可视化: https://yq.aliyun.com/articles/670942
写在最后
ES 是一把锋利的军刀, 支撑更新, 查询, 删除等更通用场景, 在搜索, 数据分析, 应用开发等领域有广泛使用, ELK 组合在日志分析场景上把 ES 灵活性与性能发挥到极致; SLS 是纯定位在日志类数据分析场景的服务, 在该领域内做了很多定制化开发. 一个服务更广, 一个场景更专. 当然离开了场景纯数字的比较没有意义, 找到适合自己场景的才重要.
日志服务(SLS):https://www.aliyun.com/product/sls
用户手册: https://promotion.aliyun.com/ntms/act/logdoclist.html
来源: https://yq.aliyun.com/articles/684009