أحتاج إلى إدراج كمية هائلة من العقد مع العلاقات بينها في Neo4J عبر نقطة نهاية دفعة REST API ، حوالي 5K سجلات/S (لا تزال متزايدة).
سيكون هذا الإدراج المستمر 24 × 7. قد يتطلب كل سجل إنشاء عقدة واحدة فقط ، ولكن قد يتطلب الآخر عقدًا وعلاقة واحدة يتم إنشاؤها.
هل يمكنني تحسين أداء الإدراج عن طريق تغيير الإجراء الخاص بي أو تعديل إعدادات Neo4J؟
تقدمي حتى الآن:
1. لقد كنت أختبر مع Neo4J لفترة من الوقت ، لكنني لم أستطع الحصول على الأداء الذي احتاجه
مربع خادم الاختبار: 24 نوى + 32 جيجابايت ذاكرة الوصول العشوائي
NEO4J 2.0.0-M06 مثبت كخدمة مستقلة.
تشغيل تطبيق Java الخاص بي على نفس الخادم. (سيحتاج تطبيق Neo4J و Java إلى تشغيله على الخادم الخاص بهما في المستقبل ، لذلك لا يمكن استخدام الوضع المضمّن)
REST API نقطة النهاية: /dB /بيانات /دفعة (الهدف: /cypher)
باستخدام فهرس المخطط ، يقيد ، دمج ، إنشاء فريدة من نوعها.
2. مخططي:
neo4j-sh (0)$ schema
==> Indexes
==> ON :REPLY(created_at) ONLINE
==> ON :REPLY(ids) ONLINE (for uniqueness constraint)
==> ON :REPOST(created_at) ONLINE
==> ON :REPOST(ids) ONLINE (for uniqueness constraint)
==> ON :Post(userId) ONLINE
==> ON :Post(postId) ONLINE (for uniqueness constraint)
==>
==> Constraints
==> ON (post:Post) ASSERT post.postId IS UNIQUE
==> ON (repost:REPOST) ASSERT repost.ids IS UNIQUE
==> ON (reply:REPLY) ASSERT reply.ids IS UNIQUE
3. طلبات Cypher الخاصة بي وطلبات JSON
3.1. عندما يتطلب سجل واحد إنشاء عقدة واحدة ، يبدو وصف الوظيفة أدناه
{"method" : "POST","to" : "/cypher","body" : {"query" : "MERGE (child:Post {postId:1001, userId:901})"}}
3.2. عندما يتطلب سجل واحد إنشاء عقد واحد مع وجود علاقة واحدة ، يبدو أن الوصف الوظيفي يبدو أدناه
{"method" : "POST","to" : "/cypher","body" : {"query" : "MERGE (parent:Post {postId:1002, userId:902}) MERGE (child:Post {postId:1003, userId:903}) CREATE UNIQUE parent-[relationship:REPOST {ids:'1002_1003', created_at:'Wed Nov 06 14:06:56 AST 2013' }]->child"}}
3.3. عادةً ما أرسل 100 وصف وظيفي (مختلط 3.1 و 3.2) لكل دفعة تتطلب حوالي 150 ~ 250 مللي ثانية لإنجازها.
4. مشاكل الأداء
4.1. التزامن:
/db/data/batch (الهدف:/cypher) يبدو غير آمن مؤشر ترابط ، ويتم اختباره مع اثنين أو أكثر من مؤشرات الترابط المتزامنة مما أدى إلى انخفاض خادم Neo4J في الدقيقة الثانية.
4.2. الدمج مع القيود لا تعمل دائما.
عند إنشاء عقدين وعلاقة واحدة مع استعلام واحد (المذكور أعلاه في 3.2.) ، فإنه يعمل في وقت ما مثل السحر ؛ لكنه فشل في وقت ما مع cypherexecutionexception وقول أحد العقدة xxxx موجودة بالفعل مع التسمية AAAA والخاصية "bbbbb" = [CCCCC] ؛ من فهمي ، لا يفترض الاندماج إرجاع أي استثناء ، ولكن إرجاع العقدة إذا كانت موجودة بالفعل.
نتيجة للاستثناء ، ستفشل الدفعة بأكملها وتراجعها ، والتي تؤثر على معدل الإدراج الخاص بي.
لقد فتحت مشكلة في جيثب لهذه القضية ، https://github.com/neo4j/neo4j/issues/1428
4.3. إنشاء فريدة من نوعها مع قيود لا تعمل دائمًا لإنشاء العلاقة.
هذا مذكور في نفس قضية جيثب أيضا.
4.4. أداء:
في الواقع ، قبل استخدام الدُفعة مع Cypher ، جربت الفهرسة القديمة باستخدام get_or_create (/db/data/index/node/post؟ freadeness = get_or_create &/db/index/exper
نظرًا لطبيعة نقاط نهاية الفهرس القديمة هذه (يقومون بإرجاع موقع البيانات في الفهرس بدلاً من ذلك موقع البيانات في تخزين البيانات الفعلي) ، لذلك لم أتمكن )
أعلم أنه يمكنني تمكين Auto_indexing ، والتعامل مع تخزين البيانات مباشرة بدلاً من الفهرس القديم ، لكنهم ذكروا من 2.0.0 ، يوصى بفهرس المخطط على الفهرس القديم ، لذلك قررت التبديل إلى نهج فهرس Schema + Cypher +.
ومع ذلك ، مع Batch + Cypher ، لا يمكنني الحصول على حوالي 200 وصف وظيفي في الثانية الواحدة ، وكان من الممكن أن يكون أعلى بكثير إذا كان الدمج مع قيود يعمل دائمًا ، فلنقول حوالي 600 ~ 800/ثانية ، لكنه لا يزال أقل بكثير من 5 آلاف /س. لقد جربت أيضًا مؤشر المخطط دون أي قيود ، فقد انتهى الأمر بأداء أقل من حيث معدل الإدراج.