如何改进我的java应用程序,将数百万条记录从mariadb数据库迁移到solr服务器

bybem2ql  于 2021-10-10  发布在  Java
关注(0)|答案(0)|浏览(369)

我已经实现了一个从mariadb数据库插入/更新solr索引的解决方案。
集成流包含以下组件:
一个简单的java应用程序,cli执行的入口点
充当rest客户机的java类
使用服务类的servlet
一个服务类,它实现从mariadb读取记录并插入/更新到solr索引中。
实现的流程如下所示:
java应用程序>rest客户端>servlet>服务>dao等

  1. public final class BatchSolrApp {
  2. private BatchSolrApp() {
  3. //I am capturing start time using localtime API
  4. BatchSolrClient batchSolrIndexingClient = new BatchSolrClient();
  5. int statusCode = batchSolrIndexingClient.updateSolrIndex();
  6. //This line returns before batch processing completes,

//所以我无法在这里捕获完成时间!}

  1. public static void main(String[] args) {
  2. try {
  3. new BatchSolrApp();
  4. } catch (Exception exception) {
  5. //log.error('xxx'+exception.getMessage());
  6. }
  7. }
  8. }
  9. /**
  10. * API Client to call batch solr reindex service via servlet.
  11. */
  12. public class BatchSolrClient {
  13. public int updateSolrIndex() {
  14. HttpClient httpClient = httpLibCustom.createProvider(loggerHttpClient).createHttpClient();
  15. String xxxUri = "www.xxx.org/aaa/bbbb?action=batchIndex&csrfToken=fakeCsrfToken";
  16. HttpUrl xxxHttpUri = HttpUrl.parse(xxxUri);
  17. Request request = new Request.Builder().url(xxxHttpUri).get().build();
  18. HttpAPIResponse httpAPIResponse = null;
  19. Response response = null;
  20. try {
  21. httpAPIResponse = httpClient.executeHttpRequest(request);
  22. if (httpAPIResponse != null) {
  23. response = httpAPIResponse.getResponse();
  24. if (response != null) {
  25. return response.code();
  26. }
  27. }
  28. } catch (
  29. Exception excResponse) {
  30. logger.error("Exception xxxxxx : \n" +
  31. exceptionStackTraceToString(excResponse));
  32. return 206;
  33. }
  34. return 202;
  35. }
  36. }
  37. public class BatchSolrServlet extends HttpServlet {
  38. @Override
  39. protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  40. throws ServletException {
  41. HashMap<String, String> params = SomeServletUtils.getServletParams(req,
  42. resp, this);
  43. ServletUtils.processRequest(this, req, resp, () -> new BatchSolrService(params));
  44. }
  45. @Override
  46. protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  47. throws ServletException {
  48. doPost(req, resp);
  49. }
  50. }
  51. /**
  52. * Service to execute Batch Solr Indexing
  53. */
  54. public class BatchSolrService extends SomeAbstractClass {
  55. public BatchSolrIndexingService(HashMap<String, String> params) {
  56. processRequest();
  57. }
  58. protected AbstractResponse processRequest() throws ServerException {
  59. CustomJSONResponse response = new CustomJSONResponse(this.getFunction());
  60. try {
  61. List<String> productIdList = fetchAllProductIds();
  62. if (productIdList != null && !productIdList.isEmpty()) {
  63. //This read the records from MariaDB, creates SOLR docs from them and insert/add to SOLR
  64. //Next line Uses the following logic amongst other code
  65. //EmbeddedSolrServer server = SolrService.getSolrServer();
  66. // server.add(doc)
  67. boolean batchUpdateOutcome = XXXSolrService.addProductBatchToSolr(productIdList);
  68. }
  69. } catch (Exception batchIndexException) {
  70. logger.error("XXX " +exceptionStackTraceToString(batchIndexException));
  71. }
  72. response.setStatusCode(201);
  73. response.setSuccess();
  74. return response;
  75. super.setError("Error during batch solr indexing request handling.", 400);
  76. return errorResponse;
  77. }
  78. }

上面的实现很有效,但我想对其进行改进。
此时,应用程序中的main()方法在批处理过程完成之前返回。但是,我希望集中跟踪批处理的进度,并相应地记录消息。由于从mariadb迁移到solr的记录量很大,批处理需要几个小时。
主应用程序在命令行上执行,摘录如下:

  1. C:\XXXX\SSSS\AppHome\WEB-INF\lib >
  2. java - cp "batchUtils.jar;*" a.b.c.d.BatchSolrApp

上面的jar将在部署新版本的应用程序后由operations手动执行,同时也没有问题。但是,简单的线程方法是受欢迎的。jar文件位于webapp的war文件的lib中!
请说明如何改进当前的解决方案,以便:
但是,我想集中跟踪批处理的进度,并相应地记录消息?
我可以跟踪批次的开始和完成时间。我现在通过在batchsolrapp中捕获开始时间和在batchsolrservice中捕获完成时间(在遍历所有记录并更新solr之后)来实现这一点?
如何从我的服务>客户端>主应用程序中最好地处理和传播http状态代码?
当从mariadb读取一些错误记录时,如何最好地处理异常。目前,我正在捕获异常,记录并移动到下一个记录。
我对一些建议和设计投入持开放态度。我想保留当前的main()java应用程序servlet组件。
采用servlet的原因是,现有的ui功能通过servlet与solr交互,并且实现cli入口点导致了solr索引的锁定。所以,我们想要一个进入solr引擎的单点,真的!

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题