2017-06-03 8 views
5

मैं लगभग 500k नोड्स के साथ एक नियो 4 जे डेटाबेस का उपयोग करता हूं। जब मैं अपने स्प्रिंग एप्लिकेशन को स्टार्टअप करता हूं और पहली क्वेरी करता हूं, तो इसमें लगभग 4-5 सेकंड लगते हैं। यह केवल पहली क्वेरी के लिए होता है, इसलिए मैंने सोचा कि वसंत शुरू होने के बाद मैं सभी गर्म प्रश्नों को तेज करने के लिए एक गर्मजोशी कर सकता हूं।वार्मुप नियो 4 जे डेटाबेस

यह मेरा applicationContext.xml है:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-2.5.xsd"> 

    <!-- neo4j database --> 
    <util:map id="config"> 
     <entry key="enable_remote_shell" value="false" /> 
    </util:map> 

    <bean id="graphDbFactory" class="org.neo4j.graphdb.factory.GraphDatabaseFactory" /> 

    <bean id="graphDbBuilder" factory-bean="graphDbFactory" 
     factory-method="newEmbeddedDatabaseBuilder"> 
     <constructor-arg value="/path/to/db" /> 
    </bean> 

    <bean id="graphDbBuilderFinal" factory-bean="graphDbBuilder" 
     factory-method="setConfig"> 
     <constructor-arg ref="config" /> 
    </bean> 

    <bean id="graphDatabaseService" factory-bean="graphDbBuilderFinal" 
     factory-method="newGraphDatabase" destroy-method="shutdown" class="org.neo4j.graphdb.GraphDatabaseService"/> 

    <context:component-scan base-package="com.app.components" /> 
</beans> 

मैंने देखा कि एक तरह से वसंत सेम आरंभीकरण के लिए प्रतीक्षा करने के लिए एक ApplicationListener लागू करने के लिए था, और नव साथ डेटाबेस वार्मअप करने के लिए नियमित रूप से जिस तरह से apoc.runtime.warmup() समारोह कॉल करने के लिए किया गया था, इसलिए मैं इस प्रकार किया:

package com.app.components; 

@Component 
public class StartupTasks implements ApplicationListener<ContextRefreshedEvent> { 

    private static final Logger LOG = LogManager.getLogger(StartupTasks.class); 

    @Autowired 
    GraphDatabaseService db; 

    @Override 
    public void onApplicationEvent(ContextRefreshedEvent event) { 
     executeTestSelect(); 
    } 

    private void executeTestSelect() { 
     LOG.info("Warming up Neo4j..."); 

     Transaction tx = db.beginTx(); 
     db.execute("CALL apoc.warmup.run()"); 
     tx.close(); 

     LOG.info("Warmup complete."); 
    } 
} 

यह एक काम नहीं किया, सब कुछ हो जाता है सही ढंग से लॉग इन किया लेकिन पहले neo4j क्वेरी अभी भी धीमी है।

चूंकि ऐसा करने से काम नहीं किया, मैं एक असली क्वेरी चलाने के लिए executeTestSelect विधि संपादित और इस तरह के परिणाम की प्रक्रिया:

private void executeTestSelect() { 
    String textToSearch = "a"; // returns almost all nodes, should make neo4j cache them all 
    Transaction tx = db.beginTx(); 
    Map<String, Object> params = new HashMap<String, Object>(); 
    params.put("textToSearch", textToSearch); 
    Result resultSet = db.execute("MATCH (n:PROD) WHERE n.description CONTAINS {textToSearch} RETURN n", 
       params); 
    Iterator<Node> results = resultSet.columnAs("n"); 
    int count = 0; 
    while (results.hasNext()) { 
     results.next(); 
     count++: 
    } 
    tx.close(); 
    LOG.info("Neo4j cache done. Processed " + count + " nodes."); 
} 

इस बार स्टार्टअप बस क्वेरी निष्पादित करने के लिए 4-5 सेकंड लेता है , लेकिन फिर यह

नियो 4j कैश किया गया। संसाधित 0 नोड्स।

यह अजीब है, क्योंकि ऐप पूरी तरह शुरू होने पर सटीक वही क्वेरी चलाता है जब 450k नोड्स लौटाता है।

मुझे क्या याद आ रही है? क्या यह संभव है कि onApplicationEvent तक पहुंचने पर Neo4j डीबी अभी तक शुरू नहीं हुआ है और क्वेरी निष्पादित नहीं कर सकता है?

पूर्ण वसंत ऐप प्रारंभ करने के बाद मैं सही ढंग से neo4j डेटाबेस को कैसे गर्म कर सकता हूं?

+0

मैं यह परीक्षण नहीं किया: यदि आप 'ContextStartedEvent' साथ ContextRefreshedEvent' की जगह' यह काम कर सकते हैं। –

उत्तर

1

ठीक है मैंने इसे शुद्ध भाग्य से खोजा।

मैं ApplicationListener हटा दिया और विधि है कि वार्मअप करता है पर @Autowired टिप्पणी के साथ एक @Service श्रेणी का निर्माण, यह काम कर रहा है।

मैंने यहां @Autowired एनोटेशन को देखे बिना कक्षा के क्षेत्र को हटाकर इसे खोज लिया, और यह काम किया। मैंने इसे कई बार कोशिश की, गर्मजोशी अब काम कर रही है। मुझे नहीं पता कि यह वसंत दस्तावेज़ीकरण में कहीं कहीं दस्तावेज है या नहीं।

यह मेरा अंतिम वर्ग है:

package com.app.components; 

@Component 
public class Neo4jWarmup { 

    private static final Logger LOG = LogManager.getLogger(StartupTasks.class); 

    @Autowired 
    GraphDatabaseService db; 

    /* 
    * this did the trick - the method gets called 
    * after Spring initialization and the DB works as expected 
    */ 
    @Autowired 
    public void neo4jWarmup() { 
     executeTestSelect(); 
    } 

    private void executeTestSelect() { 
     LOG.info("Warming up Neo4j..."); 

     Transaction tx = db.beginTx(); 
     db.execute("CALL apoc.warmup.run()"); 
     tx.close(); 

     LOG.info("Warmup complete."); 
    } 
} 
संबंधित मुद्दे