سؤال

يرتبط هذا السؤال بالآخرين الذين طرحتهم هنا، فيما يتعلق بفرز مجموعات ضخمة من البيانات في الذاكرة.

أساسا هذا هو ما أريد / لديك:

خادم XMLRPC الملتوية قيد التشغيل. يحتفظ هذا الخادم بعدة (32) مثيلات فئة فو في الذاكرة. يحتوي كل فئة FOO على شريط قائمة (والذي سيحتوي عدة ملايين من السجلات). هناك خدمة تسترجع البيانات من قاعدة بيانات، ويمررها إلى خادم XMLRPC. البيانات هي أساسا القاموس، مع مفاتيح المقابلة لكل مثيل فو، والقيم هي قائمة القواميس، مثل ذلك:

data = {'foo1':[{'k1':'v1', 'k2':'v2'}, {'k1':'v1', 'k2':'v2'}], 'foo2':...}

ثم يتم تمرير كل مثيل FOO القيمة المقابلة لمفتاحها، ويتم تحديث قواميس FOO.BAR وفرزها.

class XMLRPCController(xmlrpc.XMLRPC):

    def __init__(self):
        ...
        self.foos = {'foo1':Foo(), 'foo2':Foo(), 'foo3':Foo()}
        ...

    def update(self, data):
        for k, v in data:
            threads.deferToThread(self.foos[k].processData, v)

    def getData(self, fookey):
        # return first 10 records of specified Foo.bar
        return self.foos[fookey].bar[0:10]

class Foo():

    def __init__(self):
        bar = []

    def processData(self, new_bar_data):
        for record in new_bar_data:
            # do processing, and add record, then sort
            # BUNCH OF PROCESSING CODE
            self.bar.sort(reverse=True)

المشكلة هي أنه عند استدعاء وظيفة التحديث في xmlrpccontroller مع الكثير من السجلات (قل 100K +)، توقف عن الاستجابة لمكالمات GetDATA الخاصة بي حتى اكتمال جميع مثيلات 32 فو طريقة Process_Data. اعتقدت أن DeFertothread ستعمل، لكنني أعتقد أنني أسيء فهم حيث المشكلة هي.

أي اقتراحات ... أنا منفتح لاستخدام شيء آخر، مثل Cherrypy إذا كان يدعم هذا السلوك المطلوب.


تعديل

Roy: هذا هو كيفية إعداد المفاعل

reactor.listenTCP(port_no, server.Site(XMLRPCController)
reactor.run()

بقدر جيل، هل سيكون هناك خيار قابل للتطبيق لتغيير قيمة syssetcheckinterval () إلى شيء أصغر، لذلك يتم إصدار القفل الموجود على البيانات حتى يمكن قراءته؟

هل كانت مفيدة؟

المحلول

أسهل طريقة للحصول على التطبيق لتكون استجابة هي كسر المعالجة المكثفة وحدة المعالجة المركزية في قطع أصغر، مع ترك المفاعل الملتوي قيد التشغيل بينهما. على سبيل المثال عن طريق استدعاء مفاعل.callater (0، process_next_chunk) للتقدم إلى الجزء التالي. تنفيذ فعالا تعدد المهام التعاونية بنفسك.

هناك طريقة أخرى هي استخدام عمليات منفصلة للقيام بالعمل، ثم ستستفيد من النوى المتعددة. ألق نظرة على أمبولة: https://launchpad.net/ampoule. يوفر واجهة برمجة تطبيقات مماثلة ل DeFertothread.

نصائح أخرى

لا أعرف كم من أسلوب ProcessData الخاص بك يعمل ولا كيف تقوم بإعداد مفاعلك الملتوي. بشكل افتراضي, ، يحتوي المفاعل الملتوي على تجمع موضوعي بين 0 و 10 مواضيع. قد تحاول إرجاء ما يصل إلى 32 عملية حسابية طويلة الأمد إلى ما يصل إلى 10 مواضيع. هذا هو المستوى الأمثل.

تحتاج أيضا إلى طرح الدور الذي يلعبه GIL في تحديث كل هذه المجموعات.

تحرير: قبل إجراء أي تغييرات خطيرة في برنامجك (مثل الاتصال sys.setcheckinterval()) ربما يجب تشغيله باستخدام وحدة التعريف أو وحدة Trace Python. يجب أن أقول لك هذه الأساليب التي تستخدمها كل وقتك. بدون المعلومات الصحيحة، لا يمكنك إجراء التغييرات الصحيحة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top