Beste werkwijzen voor de berekening van de algehele waardering

Ik heb op LAMP gebaseerde bedrijfsapplicatie. SugarCRM om preciezer te zijn. Er zijn momenteel 120+ actieve gebruikers. Elke gebruiker genereert elke dag enkele records die worden gebruikt in complexe berekeningen om zogenaamde "individuele beoordeling" te krijgen.

Het duurt ongeveer 6 seconden om een ​​waarde voor "individuele beoordeling" te berekenen. En er was nog geen groot probleem: elke gebruiker klikt op de link om de berekeningen met "individuele beoordeling" te starten, wacht 6-7 seconden en krijgt de waarde weergegeven.

Maar nu moet ik de berekening van de "algehele beoordeling" uitvoeren. Dat betekent dat ik aanvullend op "individuele beoordeling" de gebruiker moet berekenen en weergeven:

  • minimale individuele beoordeling van ALLE gebruikers van de toepassing

  • maximale individuele beoordeling van ALLE gebruikers van de toepassing

  • huidige gebruikerspositie binnen het bereik van alle individuele beoordelingen.

Stel: de huidige gebruiker heeft een individuele beoordeling gelijk aan 220 punten, de minimale waarde van de rating is 80, de maximale is 235 en hij bevindt zich op de 23e positie van alle gebruikers.

Wat zijn (imho) de belangrijkste problemen die moeten worden opgelost?

  1. Als een berekening 6 seconden duurt, duurt het totale aantal berekeningen langer dan 10 minuten. Ik denk dat het niet goed is om de applicatie bijna onbereikbaar te maken voor deze periode. En wat als de hoeveelheid gebruikers in de nabije toekomst 2-3 keer zal stijgen?

  2. Die berekeningen kunnen worden uitgevoerd als nachtelijke taken, maar alle gebruikers bevinden zich in verschillende tijdzones. In Rusland is het verschil tussen extreme tijdzones 9 uur. Dus mensen in het westen van Rusland werken nog steeds in "vandaag". Terwijl mensen in oostelijke delen wakker worden om te werken in "morgen". Dus wat is de beste tijd voor nachtelijke werk in dit geval?

Zijn er best practices | benaderingen | algoritmen om een ​​dergelijk beoordelingssysteem te bouwen?

0
Ik denk dat het grootste probleem is: waarom zou het 6-7 seconden duren om één rating te berekenen?
toegevoegd de auteur alzaimar, de bron
Dit is meestal het moment om SQL-query's uit te voeren.
toegevoegd de auteur erop, de bron
Dit is meestal het moment om SQL-query's uit te voeren.
toegevoegd de auteur erop, de bron
Dit is meestal het moment om SQL-query's uit te voeren.
toegevoegd de auteur erop, de bron

6 antwoord

Gezien alleen de verstrekte informatie, de enige opties die ik zie:

  1. The obvious one - reduce the time taken for a rating calculation (6 seconds to calculate 1 user's rating seems like a lot)

  2. If possible, have intermediate values which you only recalculate some of, as required (for example, have 10 values that make up the rating, all based on different data, when some of the data changes, flag the appropriate values for recalcuation). Either do this recalculation:

    • During your daily recalculation or
    • When the update happens
  3. Partial batch calculation - only recalculate x of the users' ratings at chosen intervals (where x is some chosen value) - has the disadvantage that, at all times, some of the ratings can be out of date

  4. Calculate if not busy - either continuously recalculate ratings or only do so at a chosen interval, but instead of locking the system, have it run as a background process, only doing work if the system is idle

0
toegevoegd

Gezien alleen de verstrekte informatie, de enige opties die ik zie:

  1. The obvious one - reduce the time taken for a rating calculation (6 seconds to calculate 1 user's rating seems like a lot)

  2. If possible, have intermediate values which you only recalculate some of, as required (for example, have 10 values that make up the rating, all based on different data, when some of the data changes, flag the appropriate values for recalcuation). Either do this recalculation:

    • During your daily recalculation or
    • When the update happens
  3. Partial batch calculation - only recalculate x of the users' ratings at chosen intervals (where x is some chosen value) - has the disadvantage that, at all times, some of the ratings can be out of date

  4. Calculate if not busy - either continuously recalculate ratings or only do so at a chosen interval, but instead of locking the system, have it run as a background process, only doing work if the system is idle

0
toegevoegd

Gezien alleen de verstrekte informatie, de enige opties die ik zie:

  1. The obvious one - reduce the time taken for a rating calculation (6 seconds to calculate 1 user's rating seems like a lot)

  2. If possible, have intermediate values which you only recalculate some of, as required (for example, have 10 values that make up the rating, all based on different data, when some of the data changes, flag the appropriate values for recalcuation). Either do this recalculation:

    • During your daily recalculation or
    • When the update happens
  3. Partial batch calculation - only recalculate x of the users' ratings at chosen intervals (where x is some chosen value) - has the disadvantage that, at all times, some of the ratings can be out of date

  4. Calculate if not busy - either continuously recalculate ratings or only do so at a chosen interval, but instead of locking the system, have it run as a background process, only doing work if the system is idle

0
toegevoegd

(Sorry, het lukte niet om "lange" reacties te plaatsen, dus besloot om als antwoord te posten)

@Dukeling

SQL-query die bijna alle tijd kost voor de bovengenoemde berekening is slechts een replicatie van bedrijfslogica die moet worden uitgevoerd in PHP-code. De logica is verplaatst naar SQL met de hoop de rekentijd te verkorten. OK, ik zal beide proberen om SQL-query's te optimaliseren en te spelen met het uitvoeren van logica in PHP-code.

Stel dat na die geoptimaliseerde applicatie de individuele beoordeling voor slechts 1 seconde wordt berekend. Super goed! Maar zelfs in dit geval moet de eerste gebruiker die op het systeem is ingelogd 120 seconden wachten (120+ gebruikers * 1 sec = 120 sec) om de algehele beoordeling te berekenen en zijn positie erin te krijgen.

Ik denk aan het implementeren van de volgende aanpak:

  1. Let’s have 2 “overall ratings” – “today” and “yesterday”.

  2. For displaying purposes we’ll use “yesterday” overall rating represented as huge already sorted PHP array.

  3. When user hits calculation link he started “today” calculation but application displays him “yesterday” value. Thus we have quickly accessible “yesterday” rating and each user randomly launches rating calculation that will be displayed for them tomorrow.

  4. User list are partitioned by timezones. Each hour a cron job started to check if there’re any users in selected timezone that don’t have “today” individual rating calculated (e.g. user didn’t log into application). If so, application starts calculation of individual rating and puts its value in “today” (still invisible) ovarall rating array. Thus we have a cron job that runs nightly for each timezone-specific user group and fills the probable gaps in case users didn’t log into system.

  5. After all users in all timezones had been worked out, application
    1. sorts “today” array,
    2. drops “yesterday” one,
    3. rename “today” in “yesterday” and
    4. initialize new “today”.

Wat denk je er van? Is het redelijk genoeg of niet?

0
toegevoegd

(Sorry, het lukte niet om "lange" reacties te plaatsen, dus besloot om als antwoord te posten)

@Dukeling

SQL-query die bijna alle tijd kost voor de bovengenoemde berekening is slechts een replicatie van bedrijfslogica die moet worden uitgevoerd in PHP-code. De logica is verplaatst naar SQL met de hoop de rekentijd te verkorten. OK, ik zal beide proberen om SQL-query's te optimaliseren en te spelen met het uitvoeren van logica in PHP-code.

Stel dat na die geoptimaliseerde applicatie de individuele beoordeling voor slechts 1 seconde wordt berekend. Super goed! Maar zelfs in dit geval moet de eerste gebruiker die op het systeem is ingelogd 120 seconden wachten (120+ gebruikers * 1 sec = 120 sec) om de algehele beoordeling te berekenen en zijn positie erin te krijgen.

Ik denk aan het implementeren van de volgende aanpak:

  1. Let’s have 2 “overall ratings” – “today” and “yesterday”.

  2. For displaying purposes we’ll use “yesterday” overall rating represented as huge already sorted PHP array.

  3. When user hits calculation link he started “today” calculation but application displays him “yesterday” value. Thus we have quickly accessible “yesterday” rating and each user randomly launches rating calculation that will be displayed for them tomorrow.

  4. User list are partitioned by timezones. Each hour a cron job started to check if there’re any users in selected timezone that don’t have “today” individual rating calculated (e.g. user didn’t log into application). If so, application starts calculation of individual rating and puts its value in “today” (still invisible) ovarall rating array. Thus we have a cron job that runs nightly for each timezone-specific user group and fills the probable gaps in case users didn’t log into system.

  5. After all users in all timezones had been worked out, application
    1. sorts “today” array,
    2. drops “yesterday” one,
    3. rename “today” in “yesterday” and
    4. initialize new “today”.

Wat denk je er van? Is het redelijk genoeg of niet?

0
toegevoegd

(Sorry, het lukte niet om "lange" reacties te plaatsen, dus besloot om als antwoord te posten)

@Dukeling

SQL-query die bijna alle tijd kost voor de bovengenoemde berekening is slechts een replicatie van bedrijfslogica die moet worden uitgevoerd in PHP-code. De logica is verplaatst naar SQL met de hoop de rekentijd te verkorten. OK, ik zal beide proberen om SQL-query's te optimaliseren en te spelen met het uitvoeren van logica in PHP-code.

Stel dat na die geoptimaliseerde applicatie de individuele beoordeling voor slechts 1 seconde wordt berekend. Super goed! Maar zelfs in dit geval moet de eerste gebruiker die op het systeem is ingelogd 120 seconden wachten (120+ gebruikers * 1 sec = 120 sec) om de algehele beoordeling te berekenen en zijn positie erin te krijgen.

Ik denk aan het implementeren van de volgende aanpak:

  1. Let’s have 2 “overall ratings” – “today” and “yesterday”.

  2. For displaying purposes we’ll use “yesterday” overall rating represented as huge already sorted PHP array.

  3. When user hits calculation link he started “today” calculation but application displays him “yesterday” value. Thus we have quickly accessible “yesterday” rating and each user randomly launches rating calculation that will be displayed for them tomorrow.

  4. User list are partitioned by timezones. Each hour a cron job started to check if there’re any users in selected timezone that don’t have “today” individual rating calculated (e.g. user didn’t log into application). If so, application starts calculation of individual rating and puts its value in “today” (still invisible) ovarall rating array. Thus we have a cron job that runs nightly for each timezone-specific user group and fills the probable gaps in case users didn’t log into system.

  5. After all users in all timezones had been worked out, application
    1. sorts “today” array,
    2. drops “yesterday” one,
    3. rename “today” in “yesterday” and
    4. initialize new “today”.

Wat denk je er van? Is het redelijk genoeg of niet?

0
toegevoegd