日志分析

本用户指南部分介绍了 Solr 日志分析。

这是流表达式和数学表达式的可视化指南的附录。以下描述的所有函数都在指南中进行了详细介绍。请参阅入门章节,了解如何开始使用可视化和 Apache Zeppelin。

加载

可以使用位于 Solr 发行版 bin/ 目录中的 bin/solr postlogs 命令行工具将开箱即用的 Solr 日志格式加载到 Solr 索引中。

Postlogs

postlogs 命令读取 Solr 的日志格式并将其编入 Solr 集合中。

bin/solr postlogs [选项]

bin/solr postlogs -help

运行状况检查参数

-url <ADDRESS>

必需

默认值:无

集合的地址,例如 http://localhost:8983/solr/collection1/

-rootdir <DIRECTORY>

必需

默认值:无

日志目录根目录的文件路径:将对该目录(包括子目录)下找到的所有文件进行编制索引。如果路径指向单个日志文件,则只加载该日志文件。

示例bin/solr postlogs --url http://localhost:8983/solr/logs --rootdir /var/logs/solrlogs

上面的示例将 /var/logs/solrlogs 下的所有日志文件编入索引到基本 URL http://localhost:8983/solr 处的 logs 集合中。

探索

日志探索通常是日志分析和可视化的第一步。

在使用不熟悉的安装时,可以使用探索来了解日志中涵盖了哪些集合、这些集合中有哪些分片和核心,以及对这些集合执行了哪些类型的操作。

即使是熟悉的 Solr 安装,在进行故障排除时,探索仍然非常重要,因为它通常会发现一些意外情况,例如未知错误或意外的管理或索引操作。

抽样

探索的第一步是使用 random 函数从 logs 集合中获取随机样本。

在下面的示例中,random 函数运行一个参数,即要抽样的集合的名称。

logs sample

该样本包含 500 条随机记录及其完整字段列表。通过查看此样本,我们可以快速了解 logs 集合中可用的字段

时间段

每个日志记录都包含 date_dt 字段中的时间戳。了解日志涵盖的时间段以及已编制索引的日志记录数量通常很有用。

可以运行 stats 函数来显示此信息。

logs dates

记录类型

索引中的一个关键字段是 type_s 字段,它是日志记录的类型。

可以使用 facet 表达式来可视化不同类型的日志记录以及索引中每种类型的记录数量。

logs type

集合

另一个重要字段是 collection_s 字段,它是生成日志记录的集合。

可以使用 facet 表达式来可视化不同的集合以及它们生成多少日志记录。

logs collection

按集合划分的记录类型

可以运行二维 facet 来按集合可视化记录类型。

logs type collection

时间序列

可以使用 timeseries 函数来可视化日志特定时间范围内的时序。

在下面的示例中,时序用于以 15 秒的间隔可视化日志记录计数。

logs time series

请注意,在 21 小时 27 分钟之前,日志活动水平非常低。然后,从第 27 分钟到第 52 分钟出现了日志活动高峰。

随后出现了一大波日志活动。

下面的示例通过在 type_s 字段上添加查询来进一步细分,以便仅在日志中可视化查询活动。

logs time series2

请注意,查询活动占 21:27 至 21:52 之间日志记录突增的一半以上。但查询活动并不能解释随后出现的日志活动大幅激增。

我们可以通过更改搜索来解释该激增,仅包括日志中的更新提交deleteByQuery 记录。我们还可以按集合缩小范围,以便了解这些活动发生在何处。

logs time series3

通过各种探索性查询和可视化,我们现在对日志中包含的内容有了更好的了解。

查询计数

分布式搜索为每个查询生成多个日志记录。将有一个顶级日志记录用于顶级分布式查询,以及来自每个分片的某个副本上的分片级日志记录。还可能有一组ids 查询,用于从分片中按 ID 检索字段以完成结果页面。

日志索引中有一些字段可用于区分这三种类型的查询记录。

以下示例使用 stats 函数来统计日志中不同类型的查询记录。相同的查询可与 searchrandomtimeseries 函数一起使用,以返回特定类型查询记录的结果。

顶级查询

若要查找日志中的所有顶级查询,请添加查询以将结果限制为具有 distrib_s:true 的日志记录,如下所示

query top level

分片级查询

若要查找所有不是 ID 查询的分片级查询,请调整查询以将结果限制为具有 distrib_s:false AND ids_s:false 的日志,如下所示

query shard level

ID 查询

若要查找所有ids 查询,请调整查询以将结果限制为具有 distrib_s:false AND ids_s:true 的日志,如下所示

query ids

查询性能

Solr 日志分析的一项重要任务是了解 Solr 集群的执行情况。

qtime_i 字段包含日志记录中的查询时间 (QTime),以毫秒为单位。有许多强大的可视化和统计方法可用于分析查询性能。

QTime 散点图

散点图可用于可视化qtime_i字段的随机样本。以下示例演示了从日志记录的ptest1集合中随机抽取的 500 个样本的散点图。

在此示例中,qtime_i绘制在 y 轴上,而 x 轴只是一个序列,用于将查询时间分布在整个绘图中。

x字段包含在字段列表中。当x包含在字段列表中时,random函数会自动为 x 轴生成一个序列。
qtime scatter

从这个散点图中,我们可以了解有关查询时间的一些重要信息

  • 样本查询时间范围从 122 到 643。

  • 平均值似乎略高于 400 毫秒。

  • 查询时间往往更接近平均值,并且随着它们远离平均值而变得不那么频繁。

最高 QTime 散点图

通常能够可视化日志数据中记录的最高查询时间非常有用。这可以通过使用search函数并按qtime_i desc排序来完成。

在下面的示例中,search函数返回ptest1集合中最高的 500 个查询时间,并将结果设置为变量a。然后使用col函数从结果集中提取qtime_i列到一个向量中,该向量设置为变量y

然后使用zplot函数在散点图的 y 轴上绘制查询时间。

rev函数用于反转查询时间向量,以便可视化从最低到最高的查询时间。
qtime highest scatter

从这个绘图中,我们可以看到最高的 500 个查询时间从 510 毫秒开始,然后缓慢上升,直到最后 10 个急剧上升,最终达到 2529 毫秒的最高查询时间。

QTime 分布

在此示例中,创建了一个可视化,显示了四舍五入到最近一秒的查询时间的分布。

以下示例首先随机抽取 10000 条日志记录,其type_s* 为queryrandom函数的结果分配给变量a

然后使用col函数从结果中提取qtime_i字段。查询时间的向量设置为变量b

然后使用scalarDivide函数将查询时间向量的所有元素除以 1000。这将查询时间从毫秒转换为秒。结果设置为变量c

然后,round函数将查询时间向量的所有元素四舍五入到最近一秒。这意味着所有小于 500 毫秒的查询时间都将四舍五入为 0。

然后将 freqTable 函数应用于四舍五入到最近一秒的查询时间向量。

结果频率表显示在下面的可视化中。x 轴是秒数。y 轴是四舍五入到每秒的查询时间数。

qtime dist

请注意,大约 93% 的查询时间四舍五入到 0,这意味着它们低于 500 毫秒。大约 6% 四舍五入到 1,其余四舍五入到 2 或 3 秒。

QTime 百分位数图

百分位数图是用于了解日志中查询时间分布的另一个强大工具。以下示例演示如何创建和解释百分位数图。

在此示例中,创建了一个百分位数 array 并将其设置为变量 p

然后绘制 10000 个日志记录的随机样本并将其设置为变量 a。然后使用 col 函数从样本结果中提取 qtime_i 字段,并将此向量设置为变量 b

然后使用 percentile 函数计算查询时间向量的每个百分位数的值。设置为变量 p 的百分位数 array 告诉 percentile 函数计算哪些百分位数。

然后使用 zplot 函数在 x 轴上绘制百分位数,在 y 轴上绘制每个百分位数的查询时间

query qq

从该图中,我们可以看到第 80 个百分位数的查询时间为 464 毫秒。这意味着 80% 的查询低于 464 毫秒。

QTime 时间序列

还可以运行时间序列聚合以可视化 QTime 如何随时间变化。

以下示例显示了一个时间序列,面积图,它以 15 秒的间隔可视化日志的 3 分钟部分的平均查询时间

qtime series

性能故障排除

如果查询分析确定查询未按预期执行,则还可以使用日志分析来对慢速原因进行故障排除。以下部分演示了几个用于查找查询慢速源的方法。

慢速节点

在分布式搜索中,最终搜索性能仅与群集中响应最慢的分片一样快。因此,一个慢速节点可能是整体搜索时间慢的原因。

日志记录中提供了字段 core_sreplica_sshard_s。这些字段允许按 核心副本分片 计算平均查询时间。

core_s 字段特别有用,因为它是粒度最细的元素,并且命名约定通常包括集合、分片和副本信息。

以下示例使用 facet 函数按核心计算 avg(qtime_i)

slow nodes

请注意,在结果中,core_s 字段包含有关 集合分片副本 的信息。该示例还显示,同一集合中某些核心的 qtime 似乎明显较高。这应触发更深入的调查,以了解为什么这些核心可能执行得更慢。

慢速查询

如果查询分析显示大多数查询执行良好,但有一些异常查询很慢,则原因之一可能是特定查询很慢。

q_sq_t 字段都保存了 Solr 请求中 q 参数的值。q_s 字段是字符串字段,q_t 字段已标记化。

search 函数可用于按 qtime_i desc 对结果进行排序,从而返回日志中前 N 个最慢查询。以下示例演示了这一点

slow queries

检索查询后,可以检查它们并单独尝试,以确定查询是否一直很慢。如果查询显示很慢,则可以制定一个改进查询性能的计划。

提交

提交和导致提交的活动(例如完全索引复制)可能会导致查询性能下降。时间序列可视化有助于确定提交是否与性能下降相关。

第一步是可视化查询性能问题。下面的时间序列将日志结果限制为类型为 query 的记录,并以十分钟的间隔计算 max(qtime_i)。该图显示了 x 轴上的日期、小时和分钟以及 y 轴上以毫秒为单位的 max(qtime_i)。请注意,max qtime_i 中有一些极端峰值需要理解。

query spike

下一步是生成一个时间序列,在相同的时间间隔内统计提交次数。下面的时间序列使用与初始时间序列相同的 startendgap。但这次的时间序列是针对类型为 commit 的记录计算的。提交的计数被计算并绘制在 y 轴上。

请注意,在 max qtime_i 的峰值附近会出现提交活动峰值。

commit series

最后一步是在同一张图中叠加两个时间序列。

这可以通过执行两个时间序列并将结果设置为变量来完成,在本例中为 ab

然后从第一个时间序列中提取 date_dtmax(qtime_i) 字段作为向量,并使用 col 函数将其设置为变量。并且从第二个时间序列中提取 count(*) 字段。

然后使用 zplot 函数在 x 轴上绘制时间戳向量,在 y 轴上绘制最大 qtime 和提交计数向量。

minMaxScale 函数用于将两个向量缩放至 0 和 1 之间,以便可以在同一张图上进行视觉比较。
overlay series

请注意,在此图中,提交计数似乎与 max qtime_i 的峰值密切相关。

错误

日志索引将包含日志中发现的任何错误记录。错误记录的 type_s 字段值将为 error

以下示例搜索错误记录

search error

如果错误后跟堆栈跟踪,则堆栈跟踪将出现在可搜索字段 stack_t 中。以下示例显示了对 stack_t 字段的搜索以及结果中显示的堆栈跟踪。

stack