Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Sockets, serialization & hyperthreading προβλήματα

Îåêßíçóå áðü ôï ìÝëïò Mitsaras. Τελευταία δημοσίευση από το μέλος Παναγιώτης Καναβός στις 22-09-2005, 10:23. Υπάρχουν 6 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  20-09-2005, 21:37 5597

    Sockets, serialization & hyperthreading προβλήματα

    Λοιπόον... Έχω ένα σύνολο εφαρμογών, το οποίο έχει μοιραστεί στις κατηγορίες: Client, Server, Main Server.
    Κάθε επίπεδο από αυτές, αποτελείται από το Service, το οποίο αναλαμβάνει όλη τη "δουλειά", το Application, που χρησιμοποιείται για monitoring του Service, προσθήκη/αλλαγή στοιχείων κλπ, και τη βάση δεδομένων όπου αποθηκεύει τα στοιχεία του (εκτός του client, που έχει μόνο Service & Application).

    Ας μείνουμε στο επίπεδο του Server λοιπόν. Έστω ότι εγώ από το application, θέλω να τραβήξω κάποια δεδομένα. Ο τρόπος που το έχω υλοιποιήσει, είναι ο εξής:
    1) Στέλνει το application το request στο service μέσω socket, ως ένα byte[]'d νούμερο.
    2) Το service λαμβάνει το request, τραβάει τα δεδομένα από τη βάση, τα κάνει serialize.
    3) Αποστέλει το μέγεθος των serialized δεδομένων στο application.
    Το application απαντά με ΟΚ.
    4) Αποστέλει τα serialized δεδομένα στο application. Το application απαντά με ΟΚ.
    5) Το application τα κάνει deserialize, και όλα ΟΚ.

    Να προσθέσω εδώ, ότι η "υποδοχή" των νέων συνδέσεων στο service γίνεται με ασύγχρονα sockets, ενώ όλες οι υπόλοιπες διεργασίες με blocking (ελέγχεται δηλαδή το τέλος κάθε "πρότασης" στην επικοινωνία, με delimiter, εκτός από την περίπτωση που θα παραληφθούν serialized δεδομένα, όπου και ο έλεγχος γίνεται με βάση την ποσότητα των ληφθέντων δεδομένων). Σκέφτηκα να το υλοποιήσω όλο το πρόγραμμα με πλήρως ασύγχρονο τρόπο, αλλά η πολυπλοκότητα θα πλησίαζε σε επικίνδυνα επίπεδα.

    Τα ερωτήματά μου:
    1) Θα μπορούσατε να μου προτείνετε κάποιον άλλο τρόπο για να επιτύχω το παραπάνω; Πάει μια χαρά πάντως από ταχύτητα και CPU use.
    2) Όταν το τρέξω στο desktop μηχάνημά μου, το οποίο είναι ένας athlon64, όλα πάνε μια χαρά. Αν βάλω service & application όμως στο notebook, το οποίο έχει Intel με HT, τα πράγματα δεν πάνε καθόλου καλά. Συγκεκριμένα, αν υποθέσουμε ότι έχω ένα κουμπί που κάνει τη προαναφερθείσα διαδικασία 1 ως 5 και μου εμφανίζει τα στοιχεία σε ένα datagrid, τότε μετά από μερικά κλικ (ή και στο πρώτο), και πάντοτε τυχαία, θα δεχθώ μήνυμα λάθους για "binary stream does not contain a valid BinaryHeader". Αν θέσω το affinity και του application και του Service ώστε να δουλεύουν μόνο στη μία και ίδια Logical cpu, όλα πάνε καλά (οποιοσδήποτε άλλος συνδυασμός αποτυγχάνει).
    Υποθέτω λοιπόν, ότι το πρόβλημα οφείλεται στο μπλέξιμο των cache των 2 cpus (αλλά μπορεί να κάνω και λάθος). Έχω φροντίσει να "καλύψω" όλα τα επικίνδυνα από threading πλευράς κομμάτια του κώδικα με lock, τα οποία είναι λίγα όμως, και δεν έχουν σχέση με τη διαδικασία αυτή (καθώς όπως φαίνεται από τα παραπάνω, είναι γραμμική). Υπάρχει τρόπος λοιπόν ι) να ρίξω το affinity σε μία συγκεκριμένη cpu (.net 1.1) ή ii) έχει καταγραφεί παρόμοιο πρόβλημα;


    Ευχαριστώ προκαταβολικά όποιους μπορέσουν να βοηθήσουν έστω και στο ελάχιστο.
    Δεν έχω πρόβλημα να δώσω απόσπασμα από τον κώδικα, αλλά καθώς είναι αρκετά "μοιρασμένος", θα χρειαστεί "ξεψάχνισμα" για να τον κάνω copy paste.


    Μην αφήνετε τα media να σας "ταΐζουν"!
  •  20-09-2005, 23:21 5599 σε απάντηση της 5597

    Απ: Sockets, serialization & hyperthreading προβλήματα

    Τελικά το πρόβλημα όντως συνδέονταν με το hyperthreading, κι από ένα tracing των buffers κατάλαβα ότι κάπου προστίθεντο άχρηστα \0 (ο χώρος του buffer που έμεινε κενός). Πάντως η ερώτηση 1 παραμένει. Υπάρχει καλύτερος τρόπος να το κάνω αυτό; Μέχρι στιγμής, δουλεύω με MemoryStreams και όχι NetworkStreams.
    Ο λόγος για όλο το Implementation που περιέγραψα, ήταν η ανησυχία μου, στο τι θα γίνει αν υπάρξει ξαφνικά ένα μικρό lag-άκι κατά τη μεταφορά των δεδομένων, ενώ έχουν ήδη μεταφερθεί κατά 50%.
    Υπέθεσα ότι ένα check τύπου Socket.Available > 0 μάλλον θα οδηγήσει σε προβλήματα, ενώ ένα time-out περιθώριο θα οδηγήσει σε άσκοπες καθυστερήσεις. Θα ήθελα τη γνώμη σας.
    Μην αφήνετε τα media να σας "ταΐζουν"!
  •  21-09-2005, 10:41 5606 σε απάντηση της 5599

    Απ: Sockets, serialization & hyperthreading προβλήματα

    Μία γρήγορη ερώτηση μέχρι να διαβάσω και να καταλάβω το πρόβλημα. Γιατί χρησιμοποιείς sockets αντί για ένα από τους πιο high-level μηχανισμούς, όπως Remoting, COM+? Είναι φτιαγμένοι για να αντιμετωπίζουν ακριβώς τα προβλήματα που αντιμετωπίζεις.
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  21-09-2005, 14:57 5612 σε απάντηση της 5597

    Απ: Sockets, serialization & hyperthreading προβλήματα

    Όταν ξεκινήσαμε το project, αποφασίσαμε να χρησιμοποιήσουμε όσο πιο low-level μηχανισμούς γίνεται για τέτοιες διαδικασίες, κυρίως λόγω ανησυχιών για το overhead. Έτσι λοιπόν έφτιαξα το framework για τα sockets, το οποίο δουλεύει αρκετά καλά, και χωρίς να βασανίζει τη CPU. ΔΕΝ είναι και ότι απλούστερο και "καθαρό" από πλευράς κώδικα, αλλά πλησιάζει αρκετά.
    Η μανία με το Overhead, οφείλεται στο ότι έχουμε
    1) 1 Main server, που θα επικοινωνεί με
    2) καμμιά 10 ή και 20 Servers, οι οποίοι μπορούν να επικοινωνούν και μεταξύ τους όπου η αρχιτεκτονική το επιτρέπει, αλλά ο κάθε Server έχει και
    3) 20-30 clients με τους οποίους επικοινωνεί.

    Ομολογώ επίσης, ότι δεν έχω υλοποιήσει ποτέ λύση με remoting ή COM+ (η μόνη μου σχέση με το remoting, είναι κάποια άρθρα που διάβασα στο web). Οι ανησυχίες μου, ήταν το τι γίνεται με τα δικαιώματα που μπορεί να απαιτεί μια λύση με remoting (trust), καθώς και με την ταχύτητα.
    Θα εκτιμούσα δεόντως συμβουλές και links που θα εξηγήσουν το ζήτημα των .net remoting & COM+, αλλά κυρίως, τα πιθανά προβλήματα και τις παγίδες που μπορεί να υπάρξουν.

    ΥΓ. Το πρόβλημα που ανέφερα λύθηκε πάντως, κάνοντας μια μικρή αλλαγή στον buffer.
    Μην αφήνετε τα media να σας "ταΐζουν"!
  •  21-09-2005, 16:38 5615 σε απάντηση της 5612

    Απ: Sockets, serialization & hyperthreading προβλήματα

    Χμμ...θα συμφωνησω απο τη μια με τον pkanavos, το Remoting ειναι θεωρητικα καλυτερη λυση μιας και γινεται και scale καλυτερα.
    Και στην περιπτωση σου, τωρα που το εξηγησες καλυτερα, μαλλον ειναι πιο σωστη σαν λυση.

    Απο την αλλη ομως, αν θελεις να το στησεις με το Remoting σωστα, εχεις να κανεις με object distribution και καθε φορα που τα αλλαζεις θα πρεπει να κανεις και το αντιστοιχο update κτλ κτλ...
    Εχω χρησιμοποιησει κι εγω sockets για πολλα πραγματα εδω που δουλευω και νομιζω τελικα οτι αν στησεις σωστα το ολο συστημα και το "πρωτοκολλο" που θα φτιαξεις να δουλευει σωστα, τοτε εισαι οκ...

    Πιστευω δηλ., οτι για λιγα πραγματα τα sockets βολευουν, αν θες ομως καλυτερο scaling και πιο "βαριες" εφαρμογες, το Remoting ειναι καλυτερη λυση...

    Software Engineer, specializes in Microsoft .net/C#, COM, Sql Server and now Python.
  •  21-09-2005, 18:11 5618 σε απάντηση της 5597

    Απ: Sockets, serialization & hyperthreading προβλήματα

    Ευχαριστώ για το input. Μάλλον στην επόμενη εφαρμογή μου, θα μελετήσω το remoting παραπάνω.

    Αν μάλιστα έχει event driven notifications, θα αρχίσω να βαράω το κεφάλι μου στον τοίχο (είναι χαζό να κλείνεις τα προβληματικά sockets βασιζόμενος στο timeout τους).

    Κάπου πήρε το μάτι μου δυο λεξούλες, "Mobile agents". Για να το μελετήσω καλύτερα...
    Μην αφήνετε τα media να σας "ταΐζουν"!
  •  22-09-2005, 10:23 5638 σε απάντηση της 5618

    Απ: Sockets, serialization & hyperthreading προβλήματα

      Εξαρτάται τί εννοείς "event driven notifications". Αν αυτό που σε απασχολεί είναι απλά να κλείνεις κάποια sockets στο timeout, δεν έχεις πρόβλημα καθώς τα θέματα "άνοιξε σύνδεση-κλείσε σύνδεση-κάνε κλήση" τα αναλαμβάνει το framework. Σε μεγάλο βαθμό, εσύ κάνεις απλά κλήσεις σε μεθόδους ενός remote αντικειμένου. Σαν έννοια είναι αντίστοιχο του Java Remote Method Invocation, αν το έχεις υπόψη.
      Κάτι που ίσως σε ενδιαφέρει είναι τα "Loosely Coupled Events" του COM+. Αντί να χρησιμοποιείς μια συγκεκριμμένη κλάση για να υλοποιήσεις κάποιο service, μπορείς να δώσεις μέσω configuration στον production server ότι οι κλήσεις θα προωθούνται σε όσες κλάσεις υλοποιούν αυτό το interface και έχουν οριστεί ως subscribers. Αν θες να προσθέσεις μια νέα κλάση, φτιάχνεις το assembly της, ορίζεις την κλάση σαν subscriber και είσαι έτοιμος. Και αυτό χωρίς να χρειαστεί να πειράξεις καθόλου την εφαρμογή που ήδη είχες. Η υπάρχουσα εφαρμογή δεν θα πάρει χαμπάρι ότι προστέθηκε ένας νέος subscriber!
     Πες πως έχεις ορίσει ένα event interface για να στέλνεις ειδοποιήσεις στους χρήστες, και έφτιαξες και μία κλάση που το υλοποιεί για να στέλνει email. Την εγκαθιστάς στο production server και τελείωσε. Αν στο μέλλον θέλεις να στείλεις και SMS, φτιάχνεις τη νέα κλάση στο δικό της DLL και τη βάζεις και αυτή στον production server. Δεν χρειάζεται να πειράξεις καθόλου την αρχική εφαρμογή.
      Πες τώρα ότι θέλεις να καταγράφεις και τις ειδοποιήσεις, σε περίπτωση που σε ειδοποιήσουν ότι υπάρχει πρόβλημα στην αποστολή. Φτιάχνεις μια άλλη κλάση που υλοποιεί το interface, τη βάζεις στο server αλλά δεν την ορίζεις ως subscriber. Πέριμένεις μέχρι να χρειαστεί και τότε πας και την ορίζεις ως subscriber.
      Το σημαντικό είναι ότι σε κάθε περίπτωση δεν πειράζεις την βασική εφαρμογή. Δεν ξανακάνεις compile, ούτε χρειάζεται να ξέρει η εφαρμογή σου ότι υπάρχουν subscribers.
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems