Spanner 提供了用于存储有关读取的统计信息的内置表。您可以使用 SQL 语句从这些 SPANNER_SYS.READ_STATS*
表中检索统计信息。
何时使用读取统计信息
读取统计信息可让您深入了解应用如何使用数据库,这对于调查性能问题非常有用。例如,您可以查看针对数据库运行的读取形状、它们运行的频率,以及解释这些读取形状的性能特征。您可以使用数据库的读取统计信息来识别导致高 CPU 使用率的读取形状。简而言之,读取统计信息可帮助您从资源使用率角度了解流量进入数据库的行为。
限制
此工具最适合用于分析占大多数 CPU 使用率的类似读取流。它不适合搜索仅运行一次的读取。
这些统计信息中跟踪的 CPU 使用率代表 Spanner 服务器端 CPU 用量,不包括预取 CPU 用量和一些其他开销。
系统会尽最大努力收集统计信息。因此,当底层系统出现问题时,可能会错过统计信息。例如,如果存在内部网络问题, 可能会漏掉一些统计信息
可用性
SPANNER_SYS
数据只能通过 SQL 接口获得;例如:
Google Cloud 控制台中的数据库 Spanner Studio 页面
gcloud spanner databases execute-sql
命令executeQuery
API
不支持 Spanner 提供的其他单次读取方法
SPANNER_SYS
。
按读取形状分组的 CPU 使用率
下面的表跟踪特定时间段内 CPU 使用率最高的读取形状:
SPANNER_SYS.READ_STATS_TOP_MINUTE
:以1 分钟为间隔汇总的读取形状统计信息。SPANNER_SYS.READ_STATS_TOP_10MINUTE
:以 10 分钟为间隔汇总的读取形状统计信息。SPANNER_SYS.READ_STATS_TOP_HOUR
:以 1 小时为间隔汇总的读取形状统计信息。
这些表具有以下属性:
每个表包含表名指定的非重叠时间段长度的数据。
间隔基于时钟时间。1 分钟间隔结束于分钟,10 分钟间隔从小时开始每 10 分钟结束一次,而 1 小时间隔结束于小时。在每个时间间隔后,Spanner 会从 然后很快在 SPANNER_SYS 表中提供数据 。
例如,在上午 11:59:30,SQL 查询可用的最近时间段为:
- 1 分钟:上午 11:58:00–11:58:59
- 10 分钟:上午 11:40:00–11:49:59
- 1 小时:上午 10:00:00–10:59:59
Spanner 按读取形状对统计信息进行分组。如果存在代码 FPRINT 是标记的哈希值。否则,它是
READ_COLUMNS
值的哈希值。每行包含特定读取形状的所有执行的统计信息 指定时间间隔内 Spanner 捕获统计信息的间隔时间。
如果 Spanner 无法存储有关每个不同读取的信息 在时间间隔内运行的任何形状,系统会优先读取已读取的形状, 在指定时间间隔内最高的 CPU 使用率。
表架构
列名 | 类型 | 说明 |
---|---|---|
INTERVAL_END |
TIMESTAMP |
所包含读取执行所处的时间间隔的结束时间。 |
REQUEST_TAG |
STRING |
此读取操作的可选请求标记。如需详细了解如何使用标记,请参阅请求标记问题排查。具有相同标记字符串的多个读取的统计信息归为一行,其中“REQUEST_TAG”与该标记字符串匹配。 |
READ_TYPE |
STRING |
指示读取操作是 PARTITIONED_READ 还是
READ 。带有
从 PartitionRead API 获取的 PartitionToken 由
PARTITIONED_READ 读取类型和其他读取 API
READ 。
|
READ_COLUMNS |
ARRAY<STRING> |
读取的列集。这些按字母顺序排序。 |
FPRINT |
INT64 |
REQUEST_TAG 值的哈希值(如果存在);否则,READ_COLUMNS 值的哈希值。 |
EXECUTION_COUNT |
INT64 |
Spanner 在 。 |
AVG_ROWS |
FLOAT64 |
读取返回的平均行数。 |
AVG_BYTES |
FLOAT64 |
读取返回的数据字节数的平均值,不包括传输编码开销。 |
AVG_CPU_SECONDS |
FLOAT64 |
执行 读取,不包括预取 CPU 和其他开销。 |
AVG_LOCKING_DELAY_SECONDS |
FLOAT64 |
由于锁定而等待的平均秒数。 |
AVG_CLIENT_WAIT_SECONDS |
FLOAT64 |
因客户端未消耗广告而等待的平均秒数 与 Spanner 生成数据的速度一样快。 |
AVG_LEADER_REFRESH_DELAY_SECONDS |
FLOAT64 |
等待 Paxos 主要副本确认观察到所有写入的平均秒数。 |
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT |
INT64 |
作为读写事务的一部分执行读取操作的次数。 此列可帮助您确定是否可以通过将 对只读事务执行读取操作 |
示例查询
本部分提供了几个可检索读取统计信息的示例 SQL 语句。您可以使用 客户端库、 gcloud spanner 或 Google Cloud 控制台。
列出指定时间段内每个读取形状的基本统计信息
以下查询返回最近 1 分钟时间间隔内顶部读取形状的原始数据。
SELECT fprint,
read_columns,
execution_count,
avg_cpu_seconds,
avg_rows,
avg_bytes,
avg_locking_delay_seconds,
avg_client_wait_seconds
FROM spanner_sys.read_stats_top_minute
ORDER BY interval_end DESC LIMIT 3;
查询输出
fprint | read_columns | execution_count | avg_cpu_seconds | avg_rows | avg_bytes | avg_locking_delay_seconds | avg_client_wait_seconds |
---|---|---|---|---|---|---|---|
125062082139 |
["Singers.id", "Singers.name"] |
8514387 |
0.000661355290396507 |
310.79 |
205 |
8.3232564943763752e-06 |
0 |
151238888745 |
["Singers.singerinfo"] |
3341542 |
6.5992827184280315e-05 |
12784 |
54 |
4.6859741349028595e-07 |
0 |
14105484 |
["Albums.id", "Albums.title"] |
9306619 |
0.00017855774721667873 |
1165.4 |
2964.71875 |
1.4328191393074178e-06 |
0 |
列出按最高 CPU 总使用率排序的读取形状
以下查询返回最近一小时内 CPU 使用率最高的读取形状:
SELECT read_columns,
execution_count,
avg_cpu_seconds,
execution_count * avg_cpu_seconds AS total_cpu
FROM spanner_sys.read_stats_top_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.read_stats_top_hour)
ORDER BY total_cpu DESC LIMIT 3;
查询输出
read_columns | execution_count | avg_cpu_seconds | total_cpu |
---|---|---|---|
["Singers.id", "Singers.name"] |
1647 |
0.00023380297430622681 |
0.2579 |
["Albums.id", "Albums.title"] |
720 |
0.00016738889440282034 |
0.221314999999999 |
["Singers.singerinfo""] |
3223 |
0.00037764625882302246 |
0.188053 |
聚合统计信息
SPANNER_SYS
还包含用于存储捕获的汇总读取统计信息的表
特定时段内的流量:
SPANNER_SYS.READ_STATS_TOTAL_MINUTE
:1 分钟间隔内所有读取形状的汇总统计信息。SPANNER_SYS.READ_STATS_TOTAL_10MINUTE
:10 分钟间隔内所有读取形状的汇总统计信息。SPANNER_SYS.READ_STATS_TOTAL_HOUR
:1 小时间隔内所有读取形状的汇总统计信息。
聚合统计信息表具有以下属性:
每个表包含表名指定的非重叠时间段长度的数据。
时间段基于时钟时间。1 分钟时间段结束于整点分钟,10 分钟时间段结束于整点 10 分钟(自当前小时数开始),1 小时时间段结束于整点小时数。
例如,在上午 11:59:30,SQL 查询可用的汇总读取统计信息的最近间隔为:
- 1 分钟:上午 11:58:00–11:58:59
- 10 分钟:上午 11:40:00–11:49:59
- 1 小时:上午 10:00:00–10:59:59
每行包含在指定间隔内在数据库中执行的所有读取形状的汇总统计信息。每个时间段只有一行。
SPANNER_SYS.READ_STATS_TOTAL_*
表中捕获的统计信息可能 包含 Spanner 未在SPANNER_SYS.READ_STATS_TOP_*
个表。这些表中的一些列在 Cloud Monitoring 中显示为指标。 公开的指标包括:
- 返回的行数
- 读取执行次数
- 读取 CPU 时间
- 锁定延迟
- 客户端等待时间
- 主要副本刷新延迟
- 返回的字节数
如需了解详情,请参阅 Spanner 指标。
表架构
列名 | 类型 | 说明 |
---|---|---|
INTERVAL_END |
TIMESTAMP |
所包含读取形状执行所处的时间间隔的结束时间。 |
EXECUTION_COUNT |
INT64 |
Spanner 在 。 |
AVG_ROWS |
FLOAT64 |
读取返回的平均行数。 |
AVG_BYTES |
FLOAT64 |
读取返回的数据字节数的平均值,不包括传输编码开销。 |
AVG_CPU_SECONDS |
FLOAT64 |
执行 读取,不包括预取 CPU 和其他开销。 |
AVG_LOCKING_DELAY_SECONDS |
FLOAT64 |
由于锁定而等待的平均秒数。 |
AVG_CLIENT_WAIT_SECONDS |
FLOAT64 |
由于节流而等待的平均秒数。 |
AVG_LEADER_REFRESH_DELAY_SECONDS |
FLOAT64 |
在多地区配置中协调各实例读取所用的平均秒数。 |
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT |
INT64 |
作为读写事务一部分的读取运行的次数。 此列可帮助您确定是否可以通过将 对只读事务进行一些读取 |
示例查询
本部分提供了几个可检索汇总读取统计信息的示例 SQL 语句。您可以使用 客户端库、 gcloud spanner 或 Google Cloud 控制台。
查找所有读取形状的 CPU 总使用率
以下查询返回最近一小时内读取形状使用的 CPU 小时数:
SELECT (avg_cpu_seconds * execution_count / 60 / 60)
AS total_cpu_hours
FROM spanner_sys.read_stats_total_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.read_stats_total_hour);
查询输出
total_cpu_hours |
---|
0.00026186111111111115 |
查找指定时间段内的总执行次数
以下查询返回在最近 1 分钟间隔内执行的读取形状的总数:
SELECT interval_end,
execution_count
FROM spanner_sys.read_stats_total_minute
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.read_stats_total_minute);
查询输出
interval_end | execution_count |
---|---|
2020-05-28 11:02:00-07:00 |
12861966 |
数据保留
Spanner 至少会为每个表保留以下时间的数据 周期:
SPANNER_SYS.READ_STATS_TOP_MINUTE
和SPANNER_SYS.READ_STATS_TOTAL_MINUTE
:前 6 个小时中的时间段。SPANNER_SYS.READ_STATS_TOP_10MINUTE
和SPANNER_SYS.READ_STATS_TOTAL_10MINUTE
:前 4 天中的时间段。SPANNER_SYS.READ_STATS_TOP_HOUR
和SPANNER_SYS.READ_STATS_TOTAL_HOUR
:前 30 天中的时间段。
通过读取统计信息排查 CPU 使用率高问题
在以下情况下,Spanner 读取统计信息可以派上用场 调查 Spanner 数据库上的高 CPU 使用率,或者 只是尝试了解数据库上 CPU 占用量大的读取形状。检查 使用大量数据库资源的读取形状,让 Spanner 用户有机会降低运营成本, 以缩短一般系统延迟时间按照以下步骤执行操作,我们将向您展示如何使用读取统计信息来调查数据库中的高 CPU 使用率。
选择要调查的时间段
调查之初是查找您的应用开始出现高 CPU 使用率的时间。例如,在以下情形中, 在 2020 年 5 月 28 日下午 5:20 左右开始。
收集所选时间段的读取统计信息
选择开始调查的时间段后,我们将查看在约该时间的 READ_STATS_TOTAL_10MINUTE
表中收集的统计信息。此查询的结果可能有助于我们了解 CPU 和其他读取统计信息在该时间段内的变化情况。以下查询返回从 4:30 pm
到 7:30 pm
(含)的汇总读取统计信息。
SELECT
interval_end,
ROUND(avg_cpu_seconds,4) as avg_cpu_seconds,
execution_count,
avg_locking_delay_seconds
FROM SPANNER_SYS.READ_STATS_TOTAL_10MINUTE
WHERE
interval_end >= "2020-05-28T16:30:00"
AND interval_end <= "2020-05-28T19:30:00"
ORDER BY interval_end;
以下数据是我们通过查询返回的结果的示例。
interval_end | avg_cpu_seconds | execution_count | avg_locking_delay_seconds |
---|---|---|---|
2020-05-28 16:40:00-07:00 | 0.0004 | 11111421 | 8.3232564943763752e-06 |
2020-05-28 16:50:00-07:00 | 0.0002 | 8815637 | 8.98734051776406e-05 |
2020-05-28 17:00:00-07:00 | 0.0001 | 8260215 | 6.039129247846453e-06 |
2020-05-28 17:10:00-07:00 | 0.0001 | 8514387 | 9.0535466616680686e-07 |
2020-05-28 17:20:00-07:00 | 0.0006 | 13715466 | 2.6801485272173765e-06 |
2020-05-28 17:30:00-07:00 | 0.0007 | 12861966 | 4.6859741349028595e-07 |
2020-05-28 17:40:00-07:00 | 0.0007 | 3755954 | 2.7131391918005383e-06 |
2020-05-28 17:50:00-07:00 | 0.0006 | 4248137 | 1.4328191393074178e-06 |
2020-05-28 18:00:00-07:00 | 0.0006 | 3986198 | 2.6973481999639748e-06 |
2020-05-28 18:10:00-07:00 | 0.0006 | 3510249 | 3.7577083563017905e-06 |
2020-05-28 18:20:00-07:00 | 0.0004 | 3341542 | 4.0940589703795433e-07 |
2020-05-28 18:30:00-07:00 | 0.0002 | 8695147 | 1.9914494947583975e-05 |
2020-05-28 18:40:00-07:00 | 0.0003 | 11679702 | 1.8331461539001595e-05 |
2020-05-28 18:50:00-07:00 | 0.0003 | 9306619 | 1.2527332321222135e-05 |
2020-05-28 19:00:00-07:00 | 0.0002 | 8520508 | 6.2268448078447915e-06 |
2020-05-28 19:10:00-07:00 | 0.0006 | 13715466 | 2.6801485272173765e-06 |
2020-05-28 19:20:00-07:00 | 0.0005 | 11947323 | 3.3029114639321295e-05 |
2020-05-28 19:30:00-07:00 | 0.0002 | 8514387 | 9.0535466616680686e-07 |
在这里,我们可以看到,平均 CPU 时间 avg_cpu_seconds
在突出显示的间隔中较高。值为 2020-05-28 19:20:00 的 interval_end
具有较高的 CPU 时间,因此我们将在下一步中选择该间隔来进一步调查。
查找哪些读取形状导致高 CPU 使用率
我们来深入了解一下,我们现在查询 READ_STATS_TOP_10MINUTE
表来查找在上一步中选择的间隔。此查询的结果可以帮助指明哪些读取形状导致高 CPU 利用率。
SELECT
read_columns,
ROUND(avg_cpu_seconds,4) as avg_cpu_seconds,
execution_count,
avg_rows
FROM SPANNER_SYS.READ_STATS_TOP_10MINUTE
WHERE
interval_end = "2020-05-28T19:20:00"
ORDER BY avg_cpu_seconds DESC LIMIT 3;
以下数据是我们从查询中获得的结果示例,返回按 avg_cpu_seconds
排列的前三大读取形状的相关信息。请注意,在我们的查询中使用 ROUND
将 avg_cpu_seconds
的输出限制为 4 位小数。
read_columns | avg_cpu_seconds | execution_count | avg_rows |
---|---|---|---|
[TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.shares] 1 |
0.4192 | 1182 | 11650.42216582 |
[TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.likes,globalTagAffinity.score] |
0.0852 | 4 | 12784 |
[TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.ugcCount] |
0.0697 | 1140 | 310.7921052631 |
1 _exists
是一个内部字段,用于检查特定行是否存在。
高 CPU 使用率的一个原因是您开始更频繁地执行一些读取形状 (execution_count
)。或许读取返回的平均行数已增加 (avg_rows
)。如果读取形状的任何属性均未显示任何值得关注的内容,您可以检查其他属性,例如 avg_locking_delay_seconds
、avg_client_wait_seconds
或 avg_bytes
。
运用最佳实践减少高 CPU 使用率
在完成上述步骤后,请考虑提供其中任何最佳做法是否有助于您解决问题。
Spanner 在时间间隔内执行读取形状的次数 就是一个很好的指标示例,需要一个基准来判断 合理或存在问题的迹象。为指标建立基准后,您可以检测和调查与正常行为的意外偏差的原因。
如果 CPU 使用率在大多数情况下相对固定,但突然显示可能与用户请求或应用行为中的类似突然峰值相关联的峰值,则可能表示一切正常。
尝试以下查询查找按数量排序的热门已读形状 Spanner 针对每个读取形状执行的次数:
SELECT interval_end, read_columns, execution_count FROM SPANNER_SYS.READ_STATS_TOP_MINUTE ORDER BY execution_count DESC LIMIT 10;
如果您希望尽可能降低读取延迟时间,尤其是在 如果使用的是多区域实例配置,请使用过时读取而非强一致性读取 读取来减少或消除
AVG_LEADER_REFRESH_DELAY_SECONDS
读取延迟时间的组成部分如果您只执行读取,并且可以使用单次读取方法来表示您的读取,则应该使用该单次读取方法。单个 与读写事务不同,读取不会锁定,因此您应该使用 与价格更高的读写事务相比 写入数据
后续步骤
- 了解其他内省工具。
- 有关 Spanner 为每个数据库存储的其他信息,请参阅 数据库的信息架构表。
- 详细了解 SQL 最佳实践 Spanner。
- 详细了解调查高 CPU 利用率。