我正在研究Solr DIH(DataImportHandler)任务,以导入存储在Oracle数据库中的大约2000万个文档。最初,这些导入每秒将增加到500多个文档,但在最初的150,000个文档中,速度将崩溃至200以下,最终降为50-60 / s。这时我的耐心就结束了,我杀死了这个过程。导入500万份文档的过程无需花费30多个小时。
这些文档存储为XMLType,因此必须在查询中对其进行“解码”或推断。
一些团队成员认为使用getCLOBVal()会导致内存膨胀,并在JDBC管道中消耗资源(可能是在服务器端),但是我将getCLOB与XMLSeriaize进行比较的测试似乎不可行出来。
在JDBC连接器中也许我还没有尝试过一些连接选项,这些选项可以帮助减少开销并保持较高的吞吐量。
过去,我使用简单的HTTP帖子(在CasperJS和PHP中)在不到一天的时间内提交了1.5亿个文档。.因此,我确信这是Solr DIH和/或我们的方式存在的问题重新连接到Oracle。
以下是连接的样子:
<dataSource
name="OracDB"
type="JdbcDataSource"
driver="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@vape.blah-blah-blah.PUB"
user="some-user-name"
password="some-user-name"
convertType="true"
/>
查询看起来像这样 选择 PRODUCT_ID, 产品类别, 状态, XMLSerialize(DOCUMENT DOCXML)作为xml 从 CDBXML.PRODUCTS 哪里 PRODUCT_TYPE ='超级赞' AND gp.STATUS <>'C'
这里正在使用XPATH从数据库中的XML获取数据...如下所示:
<entity
name="DB/Import"
dataSource="OracDB"
onError="skip"
query="<already refe'd above>"
>
<field column="ID" name="id" />
<entity
name="productxml"
rootEntity="false"
dataSource="db"
dataField="DB/Import.XML"
processor="XPathEntityProcessor"
transformer="TemplateTransformer,com.megacorp.solr.dih.Transform"
forEach="/document">
<!--
XPATH PARSING OF FIELDS
-->
<field column="buildversion" xpath="/document/attribs/attrib[@id='build']" />
<field column="lastPublishedTime" setValue="n/a" />
<field column="SearchStatus" xpath="/document/attribs/attrib[@id='searchStatus']" />
<field column="ProdcutType" xpath="/document/attribs/attrib[@id='productType']" commonField="true" />
[... and a bunch more stuff ...]
</entity>
</entity>
我已经进行了很多测试,以查看托管模式或import .xml配置中的更改是否可以改善或降低摄入量,但无济于事。
几周前,该流程在11小时内导入了700万个文档,然后源数据集增加到将近2000万个文档,那时事情似乎不合时宜。
我的JDBC连接器设置是否错误?我可以设置一些内容来告诉Oracle不要缓存此查询吗?这个问题使我们感到困惑。在我不得不通过HTTPD进行旧式暴力数据填充之前,需要寻找一些提示。
答案 0 :(得分:1)
已解决 导致速度变慢的问题是Oracle及其JDBC驱动程序之间的交互,这导致 entire select被缓存在排序内部游标中,并且当该游标遍历列表时,资源减少了,速度减少了我们结束了漫长的过程。使用Ruby,我们确认此问题完全在Solr上下文之外发生了……这是“ Oracle Thing”。此时,决定减少诱饵并解决它,这就是我所做的。
为此,我们必须创建一个帮助程序或查找表,以便可以使用SQL快速快进到数据堆栈中的任何点。由于product_id是复杂的,因此无法对其进行排序,并且该表没有被批准的机会。因此,创建了另一个仅包含产品ID和序列号的表。这样就可以将17,000,000个记录非常快速地分解为较小的顺序块,每个块包含10,000个文档(在10,000个文档点附近,查询将开始失去速度)。
那不是完整的解决方案。.我们仍然会因连接/拆卸成本和串行处理而受阻。
最后的解决方法是创建多个相同的,顺序编号的数据导入处理程序,然后分别针对每个导入处理程序进行一次小的导入。我最终得到了30个处理程序,然后编写了一个迭代器工具,向每个处理程序提交了单独的导入请求,有效地解决了顺序导入问题。
最终产品是将分度从近100小时缩短到1小时。 15m。尽管Oracle 11竭尽全力阻止我们的数据提取,但问题仍得以解决。