从 json 文件流上传批量数据时,最后一批永远不会上传到 Solr
Posted
技术标签:
【中文标题】从 json 文件流上传批量数据时,最后一批永远不会上传到 Solr【英文标题】:Last batch never uploads to Solr when uploading batches of data from json file stream 【发布时间】:2018-10-17 23:03:31 【问题描述】:这可能是一个长镜头,但我不妨在这里尝试。有一段 c# 代码正在重建 solr 核心。步骤如下:
-
删除所有现有文档
获取核心实体
将实体分成 1000 个批次
执行下一组进程的线程自旋:
将每个批次序列化为 json 并将 json 写入服务器上的文件
托管核心
向核心发送命令以使用 System.Net.WebClient solrurl/corename/update/json?stream.file=myfile.json&stream.contentType=application/json;charset=utf-8 上传该文件
删除文件。我也试过在所有批次完成后删除文件,以及根本不删除文件
所有批次完成后,它会提交。我也尝试过提交
每批完成后。
我的问题是如果最后一批远小于批量大小,则不会上传。它像调用命令一样流过,但没有任何反应。它不会引发异常,并且我在 solr 日志中看不到任何错误。我的问题是为什么?以及如何确保最后一批总是被上传?我们认为这是一个时间问题,但我们在代码的许多部分添加了 Thread.Sleep(30000) 来测试该理论,但它仍然会发生。
唯一没有发生的情况是:
如果批次已满或几乎已满 我们不运行多个线程 我们在最后一批的 File.Delete 行设置断点,等待 30 秒左右,然后继续这是编写文件和调用更新命令的代码。每个批次都会调用它。
private const string
FileUpdateCommand = "1/update/json?stream.file=0&stream.contentType=application/json;charset=utf-8",
SolrFilesDir = @"\\MYSERVER\SolrFiles",
SolrFileNameFormat = SolrFilesDir + @"\0-1.json",
_solrUrl = "http://MYSERVER:8983/solr/",
CoreName = "MyCore";
public void UpdateCoreByFile(List<CoreModel> items)
if (items.Count == 0)
return;
var settings = new JsonSerializerSettings DateTimeZoneHandling = DateTimeZoneHandling.Utc ;
var dir = new DirectoryInfo(SolrFilesDir);
if (!dir.Exists)
dir.Create();
var filename = string.Format(SolrFileNameFormat, Guid.NewGuid(), CoreName);
using (var sw = new StreamWriter(filename))
sw.Write(JsonConvert.SerializeObject(items, settings));
var file = HttpUtility.UrlEncode(filename);
var command = string.Format(FileUpdateCommand, file, CoreName);
using (var client = _clientFactory.GetClient())//System.Net.WebClient
client.DownloadData(new Uri(_solrUrl + command));
//Thread.Sleep(30000);//doesn't work if I add this
File.Delete(filename);//works here if add breakpoint and wait 30 sec or so
我只是想弄清楚为什么会发生这种情况以及如何解决它。我希望这是有道理的,并且我已经提供了足够的信息和代码。感谢您的帮助。
【问题讨论】:
【参考方案1】:由于更改数据集的大小并添加断点“修复”它,这肯定是一种竞争条件。由于您尚未添加实际索引内容的代码,因此无法说出问题 真正 是什么,但我的猜测是最后一次提交发生在所有线程完成之前,并且仅有效当 all 线程完成时(如果你让线程休眠,问题仍然存在,因为所有线程都在同一时间休眠)。
简单的解决方法 - 改用 commitWithin
,并且永远不要发出显式提交。 commitWithin
参数确保文档在给定时间范围内(以毫秒为单位)在索引中可用。为确保您提交的文档在十秒内可用,请将&commitWithin=10000
附加到您的网址。
如果已经有文档等待提交,则添加的文档将在十秒之前提交,但即使最后一个文档作为最后一批提交,也不会超过十秒变得可见(.. 不会有任何文档永远处于未提交的边缘)。
这样您就不必保持线程同步或发出最终提交,只要您等到所有线程完成后再退出您的应用程序(如果它是实际终止的应用程序)。
【讨论】:
其中的提交很有趣,可能会帮助遇到类似问题的其他人;但是,这不是解决方案。我们发现了问题,它不在我粘贴的代码范围内。感谢您的意见! 出了什么问题?它可能对以后偶然发现该帖子的其他人有所帮助。 我们必须在提交之前调用 task.Wait()!以上是关于从 json 文件流上传批量数据时,最后一批永远不会上传到 Solr的主要内容,如果未能解决你的问题,请参考以下文章
Python 3:如何在不保存在磁盘上的情况下将 pandas 数据帧作为 csv 流上传?
json代码驾照考题批量加入MySQL数据库 ps.executeUpdate()永远只能悲催的加一条数据 去掉id主键自增 for 与 foreach