Windows ESENT内部:JetPrereadKeys()的预期行为
我有一个应用程序处理大量存储在ESENT中的数据(100 GB+)。该表的模式是:12字节的键和值,典型大小约为2 KiB。页面大小设置为32 KiB。我不会更改外部长值的默认1024字节大小阈值,因此我认为这些值主要存储在外部 我对改进冷缓存查找和检索性能感兴趣,因为操作是成批进行的,并且密钥是预先知道的。据我所知,()API是为了在这种情况下提高性能而设计的,但事实证明,无论是否使用此调用,我都看不到实际行为有任何变化 详情如下:Windows ESENT内部:JetPrereadKeys()的预期行为,windows,performance,caching,esent,extensible-storage-engine,Windows,Performance,Caching,Esent,Extensible Storage Engine,我有一个应用程序处理大量存储在ESENT中的数据(100 GB+)。该表的模式是:12字节的键和值,典型大小约为2 KiB。页面大小设置为32 KiB。我不会更改外部长值的默认1024字节大小阈值,因此我认为这些值主要存储在外部 我对改进冷缓存查找和检索性能感兴趣,因为操作是成批进行的,并且密钥是预先知道的。据我所知,()API是为了在这种情况下提高性能而设计的,但事实证明,无论是否使用此调用,我都看不到实际行为有任何变化 详情如下: 在我的例子中,jetpreradkeys()总是报告足够数
- 在我的例子中,jetpreradkeys()总是报告足够数量的预读密钥,相当于调用API时提交的密钥数量。如文档中所述,对提交的密钥进行了适当排序
- 我尝试了同步和异步两种方法,其中异步方法是:将预读调用发送到线程池,同时继续查找和检索当前线程上的数据
- 通过尝试和参数的所有可用组合,我尝试了ESENT的两种可用缓存模式,即使用MMAP或专用页面缓存
- 除了一个小的例外,我看不到有预读和没有预读时记录的I/O操作有任何区别。也就是说,我希望这个操作会导致(最好是异步)获取B树的必要内部节点。但我看到的唯一一件事是从jetpreradkeys()本身的堆栈中偶尔出现一个同步小读取。读取的大小很小,我认为它不可能预取所有需要的信息
- 如果调试Windows Search服务,我可以中断对JetPrereadKeys()的各种调用。因此,至少有一个现实世界中调用此API的示例,可能是出于某种原因
- 我的所有实验都是在机器重新启动后执行的,以确保数据库页面缓存为空
问题:
esentutl /ms Your.Db /v /fName,Depth,Internal,Data
列出表名、深度、内部页面数和叶级数据页面数。主记录树将按表名列出单独的行,然后在其下方列出LVs/as“[Long Values]”
还请注意,此预读键也不会扩展到突发LVs。。。同样,如果你立即读到一个突发LV列,不幸的是,你会被锁定在IO后面
默认模式是ESE专门分配和控制自己的数据库缓冲区/页面缓存。JET_参数化文件缓存主要用于(通常较小)退出(或至少是JetTerm/JetDeach其数据库)并大量重新启动的客户端进程。。。所以每次退出时ESE的私有缓冲区缓存都会丢失。。。但是JET_parameterEnableFileCache是一个参数,因此如果最近退出,数据可能仍在文件缓存中。但不建议将其用于大型数据库,因为这会导致数据在ESE缓冲区缓存和NTFS/ReFS文件缓存中进行双重缓存。JET_参数化缓存增强了以前的参数,并在某种程度上改进了这种双重缓存。。。但它只能在干净/未修改的页面缓冲区上节省内存/而不是双缓冲区。对于大型DBs,将这两个参数都保留为off/false。此外,如果您不使用这些参数,则更容易测试冷性能。。。在你的应用程序退出后,只需在你的硬盘上复制一个大文件(100MB,可能是1或2GB)几次(以清除硬盘缓存),你的数据就会变冷。;-)
现在我们已经提到了缓存。。。最后一件事——我认为可能是您的实际问题(如果不是我上面提到的“数据的形状”。。。打开perfmon并查找“数据库”和/或“数据库==>实例”perf对象(这些对象用于ESENT),查看缓存大小[数据库缓存大小”或“数据库缓存大小(MB)”],并查看可用池大小/[“数据库缓存%可用”]。。。当然,您必须取这个百分比,并根据数据库缓存大小进行计算,以获得一个想法。。。但如果这是低,这可能是你的问题。。。这是因为JetRepreAdKeys将只使用已经可用的缓冲区,所以您必须拥有一个健康/足够大的可用池。将JET_paramCacheSizeMin增大,或将JET_paramStartFlushThreshold/JET_paramStopFlushThreshold设置为使可用缓存大于总缓存大小的%。。。注意,它们被设置为与JET_paramCacheSizeMax成比例,与设置类似:
paramCacheSizeMin = 500
paramCacheSizeMax = 100000
paramStartFlush.. = 1000
paramStopFlushT.. = 2000
这意味着您的开始和停止阈值分别为当前缓存大小的1%和2%