gpt4 book ai didi

c# - SQL Server 2012 FileTable 创建文件时性能下降(集成 Lucene.NET)

转载 作者:行者123 更新时间:2023-11-30 17:51:47 25 4
gpt4 key购买 nike

我一直在设计一种使用 SQL Server FileTable 将 Lucene.NET 与 SQL Server 集成的方法原型(prototype)。使用非常方便,代码也很简单——我不需要为自定义 Lucene.NET 做任何特别的事情。我寻求的优势主要是操作性和企业性——我的公司 24/7 全天候运行 SQL Server 并且将搜索索引保持在同一控制空间中对我们有很多优势(......我确实意识到我不会获得精确的事务一致性,没关系)。

问题:无论我做什么,使用 WinAPI(通过 System.IO.FileStream)写入 SQL FileTable UNC 共享中的文件时,似乎都有大约 200 毫秒(+- 20-30 毫秒)的开销。这对于 Lucene.NET 来说意义重大,因为直接对我的本地文件系统执行索引写入操作需要大约 50 毫秒,而对 FileTable 的相同操作需要大约 2-3 秒!

为了对此进行完整性检查,我创建了另一个实验,以 10KB、1MB 和 10MB 写入 3 个新(创建)文件。我将这 3 个文件写到:

  1. 本地目录 (c:\Search\\)
  2. 通过 UNC 路径的非 FileTable 共享 (\\\127.0.0.1\\Search\\)
  3. FileTable UNC 路径(\\\127.0.0.1\[instance-share]\\search_index\\)

使用 System.Diagnostics.Stopwatch,写入本地目录的速度与预期一样快,写入非 FileTable 共享的速度较慢但具有可比性,而 FileTable 的速度要慢一个数量级。有趣的是,在案例 2 和案例 3 中,2 个较大的文件大小的表现相似,这让我相信文件创建的开销会影响时间。

问题:有没有人更深入地了解为什么使用 FileTable 创建文件如此“慢”?

这是一个几乎没有并发事件的开发 VM(4GB RAM、2 个 vCPU,可能存在一些 IO 争用,但这些测试旨在进行相对比较)。将此框上的一个微不足道的行插入到 SQL Server 中仅需 1 毫秒。

我手边没有代码,但会很快发布编辑(有准确的时间)- 它非常简单,只需在循环中将静态初始化字节数组的 4K block 写入所需大小即可。

我确实实现了以下建议,还调整了 SMB 堆栈,性能没有差异: http://blogs.msdn.com/b/blogdoezequiel/archive/2011/02/11/best-practices-on-filestream-implementations.aspx#.UkbEYtKshcZ

编辑:输出测试控制台的时间:

Writing files for directory: c:\Search
Writing file size : 10240
Writing file size : 1048576
Writing file size : 10485760
Writing files for directory: \\127.0.0.1\Search
Writing file size : 10240
Writing file size : 1048576
Writing file size : 10485760
Writing files for directory: \\127.0.0.1\Sql2012\FIndex\search_index
Writing file size : 10240
Writing file size : 1048576
Writing file size : 10485760

Write Timings
---------------------------------------------------------------
Paths (rows): Local, Shared, SQL File Table
Sizes (columns): 10KB, 1MB, 10MB
---------------------------------------------------------------
Local: 3 2 17
Share: 28 31 64
FTable: 205 249 317

源代码(非常简单,为完整性而发布):省略 ASCII 艺术的 Console Main:

private static readonly string[] paths = new string[] 
{
@"c:\Search",
@"\\127.0.0.1\Search",
@"\\127.0.0.1\Sql2012\FIndex\search_index"
};

private static readonly int[] sizes = new int[]
{
1024 * 10,
1024 * 1024,
1024 * 1024 * 10
};

static void Main(string[] args)
{
// Directory: Size 1, 2, 3
var timings = new long[3, 3];
var stopwatch = new Stopwatch();
for(var x = 0; x < 3; x++)
{
Console.WriteLine("Writing files for directory: {0}", paths[x]);
for(var y = 0; y < 3; y++)
{
Console.WriteLine("\tWriting file size : {0}", sizes[y]);
string fileName = Path.Combine(paths[x], Guid.NewGuid().ToString() + ".bin");
stopwatch.Start();
FileIOTestHelper.WriteFile(fileName, sizes[y]);
stopwatch.Stop();
timings[x, y] = stopwatch.ElapsedMilliseconds;
stopwatch.Reset();
}
}

// ascii art display code
}

实现类:

public static class FileIOTestHelper
{
private static readonly byte[] testBuffer = CreateBuffer();

private static byte[] CreateBuffer()
{
var buffer = new byte[4096];
for (var i = 0; i < 4096; i++)
{
buffer[i] = (byte)(i % 256);
}

ForceIOJit(buffer);
return buffer;
}

private static void ForceIOJit(byte[] initBuffer)
{
// Shouldn't matter, but eliminating any possible warm up cost.
using (var fs = new FileStream(Path.GetTempFileName(), FileMode.Open))
{
fs.Write(initBuffer, 0, 4096);
fs.Flush();
}
}

public static void WriteFile(string name, int sizeInBytes)
{
var count = sizeInBytes / 4096;
var remainder = sizeInBytes % 4096;
using (var fs = new FileStream(name, FileMode.Create))
{
for (int i = 0; i < count; i++)
{
fs.Write(testBuffer, 0, 4096);
}

if (remainder > 0)
{
fs.Write(testBuffer, 0, remainder);
}

fs.Flush();
}
}
}

最佳答案

经过更多测试后,我遇到的延迟是一致的并且对缓冲区大小不敏感。我接受这是 FileTable 的局限性,它对于非常繁琐的 IO 来说不太理想。

关于c# - SQL Server 2012 FileTable 创建文件时性能下降(集成 Lucene.NET),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19066896/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com