Mac 上的内容缓存指标
内容缓存将指标储存在以下文件夹中:
/资源库/Application Support/Apple/AssetCache/Metrics。
指标不会随着缓存内容移动;相反,指标会始终储存在此位置。例如,如果你将缓存从:
/资源库/Application Support/Apple/AssetCache/Data
移动到:
/Volumes/Data/Library/Application Support/Apple/AssetCache/Data
指标仍旧储存在:
/资源库/Application Support/Apple/AssetCache/Metrics
如果曾在 Mac 上使用过内容缓存,此文件夹会包含一个名为 Metrics.db 的文件,可能还包含一个或多个具有相似名称的其他文件。这些文件构成了一个你可读取的 SQLite 数据库。
若要查看描述指标的 CoreData 对象模型,可访问 /usr/libexec/AssetCache/AssetCache.momd 中的“Metric”条目。
【注】虽然此处描述的是 v7 模型,但 Apple 可能会在后续发布的 macOS 中更改此模型(或使用 SQLite 之外的数据库),而不另行通知。这可能需要你更新所配置的任何脚本以聚合缓存内容数据。
内容缓存:
会随着运行每分钟向数据库添加新的一行
闲置时不会添加“全零”行,而会跳过添加此类行
不会修改现有行
定期删除超过 30 天的行
【提示】你可以通过更改 MetricsInterval
高级设置来更改 60 秒的报告期,以及通过更改 MetricsMaxAge
高级设置来更改最长 30 天的行储存时间。
数据库中的每一行都包含以下栏。除了 creationDate
之外,每个对象都是可选的。
对象 | 描述 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
bytesDropped | 在报告期间已下载但无法添加到其缓存中的内容缓存数据量。 | ||||||||||
bytesFromCacheToChild | 在报告期间内容缓存从其缓存提供给子内容缓存的数据量。 | ||||||||||
bytesFromCacheToClient | 在报告期间内容缓存从其缓存提供给客户端 Apple 设备的数据量。 | ||||||||||
bytesFromCacheToPeer | 在报告期间内容缓存从其缓存提供给对等内容缓存的数据量。 | ||||||||||
bytesFromOriginToChild | 在报告期间内容缓存通过互联网下载并提供给子内容缓存的数据量。 | ||||||||||
bytesFromOriginToClient | 在报告期间内容缓存通过互联网下载并提供给客户端 Apple 设备的数据量。 | ||||||||||
bytesFromOriginToPeer | 在报告期间内容缓存通过互联网下载并提供给对等内容缓存的数据量。 | ||||||||||
bytesFromParentToChild | 在报告期间内容缓存从父内容缓存下载并提供给子内容缓存的数据量。 | ||||||||||
bytesFromParentToClient | 在报告期间内容缓存从父内容缓存下载并提供给客户端 Apple 设备的数据量。 | ||||||||||
bytesFromParentToPeer | 在报告期间内容缓存从父内容缓存下载并提供给对等内容缓存的数据量。 | ||||||||||
bytesFromPeerToChild | 在报告期间内容缓存从对等内容缓存接收并提供给子内容缓存的数据量。 | ||||||||||
bytesFromPeerToClient | 在报告期间内容缓存从对等内容缓存接收并提供给客户端 Apple 设备的数据量。 | ||||||||||
bytesImportedByHTTP | 在报告期间内容缓存通过 HTTP 接收的数据量。 | ||||||||||
bytesImportedByXPC | 在报告期间内容缓存通过 XPC 接收的数据量。 | ||||||||||
bytesPurgedTotal | 在报告期间内容缓存从其缓存清除的数据量。包括 bytesPurgedYoungerThan30Days。 | ||||||||||
bytesPurgedYoungerThan1Day | 在报告期间内容缓存在不到 1 天前添加到缓存并从其缓存清除的数据量。 | ||||||||||
bytesPurgedYoungerThan30Days | 在报告期间内容缓存在不到 30 天前添加到缓存并从其缓存清除的数据量。包括 bytesPurgedYoungerThan7Days。 | ||||||||||
bytesPurgedYoungerThan7Days | 在报告期间内容缓存在不到 7 天前添加到缓存并从其缓存清除的数据量。包括 bytesPurgedYoungerThan1Day。 | ||||||||||
creationDate | 收集此指标对象的日期。此指标项描述在 creationDate 结束期间内容缓存的性能。 | ||||||||||
importsByHTTP | 在报告期间内容缓存通过 HTTP 收到的上传请求次数。 | ||||||||||
importsByXPC | 在报告期间内容缓存通过 XPC 收到的上传请求次数。 | ||||||||||
period | 报告期在 creationDate 结束时的时长(以秒钟为单位)。 | ||||||||||
repliesFromCacheToChild | 在报告期间内容缓存从其缓存提供给子内容缓存的应答次数。 | ||||||||||
repliesFromCacheToClient | 在报告期间内容缓存从其缓存提供给客户端 Apple 设备的应答次数。 | ||||||||||
repliesFromCacheToPeer | 在报告期间内容缓存从其缓存提供给对等内容缓存的应答次数。 | ||||||||||
repliesFromOriginToChild | 在报告期间内容缓存通过互联网下载并提供给子内容缓存的应答次数。 | ||||||||||
repliesFromOriginToClient | 在报告期间内容缓存通过互联网下载并提供给客户端 Apple 设备的应答次数。 | ||||||||||
repliesFromOriginToPeer | 在报告期间内容缓存通过互联网下载并提供给对等内容缓存的应答次数。 | ||||||||||
repliesFromParentToChild | 在报告期间内容缓存从父内容缓存下载并提供给子内容缓存的应答次数。 | ||||||||||
repliesFromParentToClient | 在报告期间内容缓存从父内容缓存下载并提供给客户端 Apple 设备的应答次数。 | ||||||||||
repliesFromParentToPeer | 在报告期间内容缓存从父内容缓存下载并提供给对等内容缓存的应答次数。 | ||||||||||
repliesFromPeerToChild | 在报告期间内容缓存从对等内容缓存接收并提供给子内容缓存的应答次数。 | ||||||||||
repliesFromPeerToClient | 在报告期间内容缓存从对等内容缓存接收并提供给客户端 Apple 设备的应答次数。 | ||||||||||
requestsFromChild | 在报告期间内容缓存从子内容缓存收到的下载请求次数。 | ||||||||||
requestsFromClient | 在报告期间内容缓存从客户端 Apple 设备收到的下载请求次数。 | ||||||||||
requestsFromPeer | 在报告期间内容缓存从对等内容缓存收到的下载请求次数。 | ||||||||||
requestsRejectedForNoSpace | 在报告期间内容缓存因为高缓存压力而拒绝的下载请求次数(HTTP 响应代码为 503,即“服务不可用”)。 |
归类结果
将部分上述项目分类可能会很有用。请尝试以下建议。所有内容都是基于整数。
内容 | 归类对象 | 描述 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
提供给对等的字节数 | bytesFrom*ToPeer 的总和 | 在报告期间内容缓存提供给其任何对等内容缓存的数据量。 | |||||||||
提供给客户端的字节数 | bytesFrom*ToClient 的总和 | 在报告期间内容缓存提供给客户端 Apple 设备的数据量。 | |||||||||
提供给子项的字节数 | bytesFrom*ToChild 的总和 | 在报告期间内容缓存提供给其任何子内容缓存的数据量。 | |||||||||
已上传的字节数 | bytesImportedBy* 的总和 | 在报告期间通过内容缓存上传的数据量。 | |||||||||
已提供的字节数 | 在报告期间内容缓存所提供的总数据量。此值不为零时,表示内容缓存正在工作。 | bytesFrom*To* 的总和 | |||||||||
已下载的字节数 | bytesFrom <Origin,Parent,Peer>To | 在报告期间内容缓存通过互联网或者从对等或父项下载的数据量。 | |||||||||
由对等提供的字节数 | bytesFromPeerTo* 的总和 | 在报告期间内容缓存从其任何对等内容缓存下载的数据量。 | |||||||||
由父项提供的字节数 | bytesFromParentTo* 的总和 | 在报告期间内容缓存从其任何父内容缓存下载的数据量。 | |||||||||
由缓存提供的字节数 | bytesFromCacheTo* 的总和 | 在报告期间内容缓存从其缓存提供的数据量。当此值越接近已提供的字节数值,说明内容缓存越有用。 | |||||||||
由来源提供的字节数 | bytesFromOriginTo* 的总和 | 在报告期间内容缓存通过互联网下载的数据量。 |
获取缓存压力数据
你可以查看在报告期间内容缓存需要更多储存空间的急迫性。缓存压力越低越好。
活动监视器按照以下方式计算缓存压力:
requestsRejectedForNoSpace > 0 时,压力为 100%
bytesPurgedYoungerThan1Day > 0 时,压力为 80%
bytesPurgedYoungerThan7Days > 0 时,压力为 60%
bytesPurgedYoungerThan30Days > 0 时,压力为 40%
bytesPurgedTotal > 0 时,压力为 20%
否则压力为 0%
活动监视器还会按照以下方式整理上述项目,例如计算比一个周期要长的时间间隔内的值。
按照时间间隔来总计字节数、导入次数、请求次数或响应次数。
按照时间间隔来计算最大缓存压力。
读取指标数据库的示例代码
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
void readMetricsSinceDate(NSDate *date)
{
NSURL *modelURL = [NSURL fileURLWithPath:@"/usr/libexec/AssetCache/AssetCache.momd"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
if (model == nil) {
// handle the error
}
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
NSURL *databaseURL = [NSURL fileURLWithPath:@"/Library/Application Support/Apple/AssetCache/Metrics/Metrics.db"];
NSError *storeError = nil;
NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:databaseURL options:@{ NSReadOnlyPersistentStoreOption: @YES } error:&storeError];
if (store == nil) {
// handle the error
}
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.persistentStoreCoordinator = coordinator;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Metric"];
request.predicate = [NSPredicate predicateWithFormat:@"%K > %@", @"creationDate", date];
request.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES] ];
NSError *fetchError = nil;
NSArray *results = [context executeFetchRequest:request error:&fetchError];
if (results == nil) {
// handle the error
}
for (NSManagedObject *result in results) {
NSNumber *bytesDropped = [result valueForKey:@"bytesDropped"];
// ...
NSNumber *requestsRejectedForNoSpace = [result valueForKey:@"requestsRejectedForNoSpace"];
// use the values
}
}