Object Storage 监控¶
注意
本节摘自 Darrell Bishop 的博客文章,此后已进行编辑。
OpenStack Object Storage 集群是由许多守护进程在许多节点上协同工作而组成的。 拥有如此多的不同组件,您必须能够了解集群内部的情况。 跟踪服务器级别的指标,如 CPU 利用率、负载、内存消耗、磁盘使用率和利用率等是必要的,但不足以满足需求。
Swift Recon¶
Swift Recon 中间件(参见 集群遥测和监控)提供一般的机器统计信息,例如负载平均值、套接字统计信息、/proc/meminfo 内容,以及 Swift 特定的指标
每个环文件的
MD5校验和。最近的对象复制时间。
每种类型隔离文件的数量:账户、容器或对象。
磁盘上“async_pendings”(延迟容器更新)的数量。
Swift Recon 是安装在对象服务器管道中的中间件,它有一个必需的选项:本地缓存目录。 要跟踪 async_pendings,您必须为每个对象服务器设置一个额外的 cron 作业。 您可以通过直接向对象服务器发送 HTTP 请求或使用 swift-recon 命令行客户端来访问数据。
存在 Object Storage 集群统计信息,但典型的服务器指标与现有的服务器监控系统重叠。 要将 Swift 特定的指标导入监控系统,必须对其进行轮询。 Swift Recon 充当指标收集器中间件。 将指标馈送到您的统计系统(例如 collectd 和 gmond)的进程应已在存储节点上运行。 您可以选择与 Swift Recon 通信或直接收集指标。
Swift-Informant¶
Swift-Informant 中间件(参见 swift-informant)可以实时了解 Object Storage 客户端请求。 它位于代理服务器的管道中,并在每次向代理服务器的请求后将三个指标发送到 StatsD 服务器
例如
obj.GET.200或cont.PUT.404等指标的计数器递增。例如
acct.GET.200或obj.GET.200等指标的计时数据。[README 中显示指标类似于duration.acct.GET.200,但我没有在代码中看到duration。 我不确定 Etsy 服务器如何工作,但我们的 StatsD 服务器会将计时指标转换为带有新片段附加的五个派生指标,因此它可能按编码方式工作。第一个指标变为acct.GET.200.lower、acct.GET.200.upper、acct.GET.200.mean、acct.GET.200.upper_90和acct.GET.200.count]。例如
tfer.obj.PUT.201等指标的传输字节数增加。
这用于接收有关客户端体验的服务质量信息,以及感知请求服务器类型、命令和响应代码的各种修改的量。 Swift-Informant 不需要更改核心 Object Storage 代码,因为它实现为中间件。 但是,它无法了解代理服务器之外的集群的工作原理。 如果一个存储节点的响应速度下降,您只能看到一些请求出现问题,要么是高延迟,要么是错误状态码。
Statsdlog¶
Statsdlog 项目根据记录的事件递增 StatsD 计数器。 像 Swift-Informant 一样,它也是非侵入性的,但是 statsdlog 可以跟踪所有 Object Storage 守护进程的事件,而不仅仅是代理服务器。 守护进程侦听 UDP 流的 syslog 消息,并在日志行匹配正则表达式时递增 StatsD 计数器。 指标名称映射到 JSON 文件中的正则表达式匹配模式,从而灵活配置从日志流中提取哪些指标。
当前,只有第一个匹配的正则表达式会触发 StatsD 计数器递增,并且计数器始终递增 1。 没有办法将计数器递增超过 1 或根据日志行内容将计时数据发送到 StatsD。 可以扩展该工具以处理每行更多的指标和数据提取,包括计时数据。 但是,仍然会存在日志文本格式和日志解析正则表达式之间的耦合,后者本身将更复杂,以支持每行和数据提取的多个匹配项。 此外,日志处理会在触发事件和将数据发送到 StatsD 之间引入延迟。 最好在发生时递增错误计数器,并在已知时立即发送计时数据,以避免日志字符串和解析正则表达式之间的耦合,并防止事件和将数据发送到 StatsD 之间的时间延迟。
下一节描述了另一种收集 Object Storage 运行指标的方法。
Swift StatsD 日志记录¶
StatsD(参见 衡量一切)旨在深度检测应用程序代码。 指标由刚刚注意到或执行某事的代码实时发送。 发送指标的开销极低:一个 UDP 数据包的 sendto。
为了避免中间件监控和事后日志处理固有的问题,将 StatsD 指标的发送集成到 Object Storage 本身中。 跟踪的指标的详细信息在 管理员指南 中。
指标的发送与日志记录框架集成。 要启用,请在相关配置文件中配置 log_statsd_host。 您还可以指定端口和默认采样率。 除非对 statsd 日志记录方法(如下所示)的特定调用覆盖它,否则将使用指定的默认采样率。 当前,没有日志记录调用覆盖采样率,但可以想象的是,某些指标可能需要准确度(sample_rate=1),而其他指标可能不需要。
[DEFAULT]
# ...
log_statsd_host = 127.0.0.1
log_statsd_port = 8125
log_statsd_default_sample_rate = 1
然后,由 get_logger() 返回的 LogAdapter 对象(通常存储在 self.logger 中)具有这些新方法
update_stats(self, metric, amount, sample_rate=1)将提供的指标递增给定的数量。 当您需要添加或减去大于 1 的计数器时,例如在对象复制器中按计算哈希的数量递增suffix.hashes时使用此方法。increment(self, metric, sample_rate=1)将给定的计数器指标递增 1。decrement(self, metric, sample_rate=1)将给定的计数器指标递减 1。timing(self, metric, timing_ms, sample_rate=1)记录给定的指标花费了提供的毫秒数。timing_since(self, metric, orig_time, sample_rate=1)便利方法,用于记录一个计时指标,其值为“现在”减去现有的时间戳。
注意
这些日志记录方法可以在您拥有 logger 对象的任何地方安全地调用。 如果未配置 StatsD 日志记录,则这些方法将不起作用。 这避免了在记录每个指标时进行繁琐的条件逻辑。 这些示例用法显示了新的日志记录方法
# swift/obj/replicator.py
def update(self, job):
# ...
begin = time.time()
try:
hashed, local_hash = tpool.execute(tpooled_get_hashes, job['path'],
do_listdir=(self.replication_count % 10) == 0,
reclaim_age=self.reclaim_age)
# See tpooled_get_hashes "Hack".
if isinstance(hashed, BaseException):
raise hashed
self.suffix_hash += hashed
self.logger.update_stats('suffix.hashes', hashed)
# ...
finally:
self.partition_times.append(time.time() - begin)
self.logger.timing_since('partition.update.timing', begin)
# swift/container/updater.py
def process_container(self, dbfile):
# ...
start_time = time.time()
# ...
for event in events:
if 200 <= event.wait() < 300:
successes += 1
else:
failures += 1
if successes > failures:
self.logger.increment('successes')
# ...
else:
self.logger.increment('failures')
# ...
# Only track timing data for attempted updates:
self.logger.timing_since('timing', start_time)
else:
self.logger.increment('no_changes')
self.no_changes += 1